From 64bfe506d77e39ab31db5999b64253210907a59b Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Wed, 28 Feb 2024 10:39:12 -0800 Subject: [PATCH 01/53] Release Notes 5.2.0 (#2370) --- CHANGELOG.md | 67 +++++++++ release-notes/5.2/5.2.0.md | 284 +++++++++++++++++++++++++++++++++++- release-notes/5.2/5.2.md | 18 +++ release-notes/5.2/README.md | 6 + release-notes/README.md | 4 +- 5 files changed, 370 insertions(+), 9 deletions(-) create mode 100644 release-notes/5.2/5.2.md diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e4d1acc3..29c1c394af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,73 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +## [Stable release 5.2.0] - 2024-02-28 + +### Added + +- Added a new `AccessTokenCallBack` API to `SqlConnection`. [#1260](https://github.com/dotnet/SqlClient/pull/1260) +- Added `SqlBatch` support on .NET 6+ [#1825](https://github.com/dotnet/SqlClient/pull/1825), [#2223](https://github.com/dotnet/SqlClient/pull/2223),[#2371](https://github.com/dotnet/SqlClient/pull/2371), [#2373](https://github.com/dotnet/SqlClient/pull/2373) +- Added support of `SqlDiagnosticListener` on **.NET Standard**. [#1931](https://github.com/dotnet/SqlClient/pull/1931) +- Added new property `RowsCopied64` to `SqlBulkCopy`. [#2004](https://github.com/dotnet/SqlClient/pull/2004) +- Added support for the `SuperSocketNetLib` registry option for Encrypt on .NET on Windows. [#2047](https://github.com/dotnet/SqlClient/pull/2047) +- Added the ability to generate debugging symbols in a separate package file [#2137](https://github.com/dotnet/SqlClient/pull/2137) +- Added Workload Identity authentication support [#2159](https://github.com/dotnet/SqlClient/pull/2159), [#2264](https://github.com/dotnet/SqlClient/pull/2264) +- Added support for Big Endian systems [#2170](https://github.com/dotnet/SqlClient/pull/2170) +- Added support for Georgian collation [#2194](https://github.com/dotnet/SqlClient/pull/2194) +- Added Localization support on .NET [#2210](https://github.com/dotnet/SqlClient/pull/2110) +- Added .NET 8 support [#2230](https://github.com/dotnet/SqlClient/pull/2230) +- Added explicit version for major .NET version dependencies on System.Runtime.Caching 8.0.0, System.Configuration.ConfigurationManager 8.0.0, and System.Diagnostics. +- DiagnosticSource 8.0.0 [#2303](https://github.com/dotnet/SqlClient/pull/2303) + +### Changed + +- Improved parsing buffered characters in `TdsParser`. [#1544](https://github.com/dotnet/SqlClient/pull/1544) +- Added Microsoft.SqlServer.Types to verify support for SqlHierarchyId and Spatial for .NET Core. [#1848](https://github.com/dotnet/SqlClient/pull/1848) +- Moved to new System.Data.SqlTypes APIs on **.NET 7** and up. [#1934](https://github.com/dotnet/SqlClient/pull/1934) and [#1981](https://github.com/dotnet/SqlClient/pull/1981) +- Removed reference to Microsoft.Win32.Registry since it's shipped starting with .NET 6.0. [#1974](https://github.com/dotnet/SqlClient/pull/1974) +- Changed **[UseOneSecFloorInTimeoutCalculationDuringLogin](https://learn.microsoft.com/sql/connect/ado-net/appcontext-switches#enable-a-minimum-timeout-during-login)** App Context switch default to **true** and extended its effect to .NET and .NET Standard. [#2012](https://github.com/dotnet/SqlClient/pull/2012) +- Updated `Microsoft.Identity.Client` version from 4.47.2 to 4.53.0. [#2031](https://github.com/dotnet/SqlClient/pull/2031), [#2055](https://github.com/dotnet/SqlClient/pull/2055) +- Switched to the new .NET [NegotiateAuthentication](https://learn.microsoft.com/en-us/dotnet/api/system.net.security.negotiateauthentication?view=net-7.0) API on .NET 7.0 and above for SSPI token negotiation using Managed SNI. [#2063](https://github.com/dotnet/SqlClient/pull/2063) +- Removed `ignoreSniOpenTimeout` in open connection process on Windows. [#2067](https://github.com/dotnet/SqlClient/pull/2067) +- Enforce explicit ordinal for internal `StringComparison` operations. [#2068](https://github.com/dotnet/SqlClient/pull/2068) +- Improved error messages when validating server certificates in managed SNI (Linux/macOS) [#2060](https://github.com/dotnet/SqlClient/pull/2060) +- Improved CPU usage when `AppContext` switches are in use [#2227](https://github.com/dotnet/SqlClient/pull/2227) +- Upgraded `Azure.Identity` dependency version to [1.10.3](https://www.nuget.org/packages/Azure.Identity/1.10.3) to address [CVE-2023-36414](https://github.com/advisories/GHSA-5mfx-4wcx-rv27), [#2189](https://github.com/dotnet/SqlClient/pull/2189) +- Changed Microsoft.IdentityModel.JsonWebTokens and Microsoft.IdentityModel.Protocols.OpenIdConnect version 6.24.0 to 6.35.0 [#2290](https://github.com/dotnet/SqlClient/pull/2290) to address [CVE-2024-21319](https://www.cve.org/CVERecord?id=CVE-2024-21319) +- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET/.NET Standard dependency) version to `v5.2.0`. [#2363](https://github.com/dotnet/SqlClient/pull/2363), which includes removing dead code and addressing static analysis warnings +- Code health improvements: [#1198](https://github.com/dotnet/SqlClient/pull/1198), [#1829](https://github.com/dotnet/SqlClient/pull/1829), [#1943](https://github.com/dotnet/SqlClient/pull/1943), [#1949](https://github.com/dotnet/SqlClient/pull/1949), [#1959](https://github.com/dotnet/SqlClient/pull/1959), [#1985](https://github.com/dotnet/SqlClient/pull/1985), [#2071](https://github.com/dotnet/SqlClient/pull/2071), [#2073](https://github.com/dotnet/SqlClient/pull/2073), [#2088](https://github.com/dotnet/SqlClient/pull/2088), [#2091](https://github.com/dotnet/SqlClient/pull/2091), [#2098](https://github.com/dotnet/SqlClient/pull/2098), [#2121](https://github.com/dotnet/SqlClient/pull/2121), [#2122](https://github.com/dotnet/SqlClient/pull/2122), [#2132](https://github.com/dotnet/SqlClient/pull/2132), [#2136](https://github.com/dotnet/SqlClient/pull/2136), [#2144](https://github.com/dotnet/SqlClient/pull/2144), [#2147](https://github.com/dotnet/SqlClient/pull/2147), [#2157](https://github.com/dotnet/SqlClient/pull/2157), [#2164](https://github.com/dotnet/SqlClient/pull/2164), [#2166](https://github.com/dotnet/SqlClient/pull/2166), [#2168](https://github.com/dotnet/SqlClient/pull/2168), [#2186](https://github.com/dotnet/SqlClient/pull/2186), [#2254](https://github.com/dotnet/SqlClient/pull/2254), [#2288](https://github.com/dotnet/SqlClient/pull/2288), [#2305](https://github.com/dotnet/SqlClient/pull/2305), [#2317](https://github.com/dotnet/SqlClient/pull/2317) + +### Fixed + +- Fixed Always Encrypted secure enclave retry logic for async queries. [#1988](https://github.com/dotnet/SqlClient/pull/1988) +- Fixed activity correlator to continue use of same GUID for connection activity. [#1997](https://github.com/dotnet/SqlClient/pull/1997) +- Fixed behavior when error class is greater than 20 on connection retry. [#1953](https://github.com/dotnet/SqlClient/pull/1953) +- Fixed error message when symmetric key decryption failed using Always Encrypted. [#1948](https://github.com/dotnet/SqlClient/pull/1948) +- Fixed TransactionScope connection issue when Enlist is enable, Pooling is disabled and network connection type is Redirect. [#1960](https://github.com/dotnet/SqlClient/pull/1960) +- Fixed TDS RPC error on large queries in SqlCommand.ExecuteReaderAsync. [#1936](https://github.com/dotnet/SqlClient/pull/1936) +- Fixed throttling of token requests by calling AcquireTokenSilent. [#1925](https://github.com/dotnet/SqlClient/pull/1925) +- Fixed Linux code coverage result in Build proj. [#1950](https://github.com/dotnet/SqlClient/pull/1950) +- Fixed NullReferenceException in GetBytesAsync. [#1906](https://github.com/dotnet/SqlClient/pull/1906) +- Fixed Transient fault handling issue with OpenAsync. [#1983](https://github.com/dotnet/SqlClient/pull/1983) +- Fixed invariant mode checks. [#1917](https://github.com/dotnet/SqlClient/pull/1917) +- Fixed GC behavior in TdsParser by adding array rental capability in TryReadPlpUnicodeChars. [#1866](https://github.com/dotnet/SqlClient/pull/1866) +- Fixed socket synchronization issue during connect in managed SNI. [#1029](https://github.com/dotnet/SqlClient/pull/1029) +- Fixed issue with `SqlConnectionStringBuilder` property indexer not supporting non-string values. [#2018](https://github.com/dotnet/SqlClient/pull/2018) +- Fixed `SqlDataAdapter.Fill` and configurable retry logic issue on .NET Framework. [#2084](https://github.com/dotnet/SqlClient/pull/2084) +- Fixed `SqlConnectionEncryptOption` type conversion by introducing the `SqlConnectionEncryptOptionConverter` attribute when using **appsettings.json** files. [#2057](https://github.com/dotnet/SqlClient/pull/2057) +- Fixed th-TH culture info issue on Managed SNI. [#2066](https://github.com/dotnet/SqlClient/pull/2066) +- Fixed an issue when using the Authentication option, but not encrypting on .NET Framework where the server certificate was being incorrectly validated [#2224](https://github.com/dotnet/SqlClient/pull/2224) +- Fixed a deadlock problem for distributed transactions when on .NET [#2161](https://github.com/dotnet/SqlClient/pull/2161) +- Fixed an issue with connecting to named instances on named pipes in managed SNI (Linux/macOS) [#2142](https://github.com/dotnet/SqlClient/pull/2142) +- Fixed LocalDb connection issue with an invalid source when using managed SNI [#2129](https://github.com/dotnet/SqlClient/pull/2129) +- Fixed an `AccessViolationException` when using a SQL Express user instance [#2101](https://github.com/dotnet/SqlClient/pull/2101) +- Fixed a metadata query issue when connecting to Azure SQL Edge [#2099](https://github.com/dotnet/SqlClient/pull/2099) +- Fixed file version information for .NET and .NET Standard binaries [#2093](https://github.com/dotnet/SqlClient/pull/2093) +- Fixed the SPN sent for a named instance when using Kerberos authentication on Linux/macOS [#2240](https://github.com/dotnet/SqlClient/pull/2240) +- Fixed connection to unsubscribe from transaction completion events before returning it to the connection pool [#2301](https://github.com/dotnet/SqlClient/pull/2301) +- Fixed InvalidCastException when reading an Always Encrypted date or time column [#2275](https://github.com/dotnet/SqlClient/pull/2275) +- Fixed token caching to prevent expired access tokens from being reused in a connection pool [#2273](https://github.com/dotnet/SqlClient/pull/2273) + ## [Preview Release 5.2.0-preview5.24024.3] - 2024-01-24 This update brings the below changes over the previous release: diff --git a/release-notes/5.2/5.2.0.md b/release-notes/5.2/5.2.0.md index 498db81ac6..e499e795da 100644 --- a/release-notes/5.2/5.2.0.md +++ b/release-notes/5.2/5.2.0.md @@ -1,7 +1,277 @@ -| Release Date | Version | Notes | -| :-- | :-- | :--: | -| 2024/01/24 | 5.2.0-preview5.24024.3 | [release notes](5.2.0-preview5.md) | -| 2023/12/08 | 5.2.0-preview4.23342.2 | [release notes](5.2.0-preview4.md) | -| 2023/07/20 | 5.2.0-preview3.23201.1 | [release notes](5.2.0-preview3.md) | -| 2023/06/08 | 5.2.0-preview2.23159.1 | [release notes](5.2.0-preview2.md) | -| 2023/04/20 | 5.2.0-preview1.23109.1 | [release notes](5.2.0-preview1.md) | +# Release Notes + +## Microsoft.Data.SqlClient 5.2.0 released 28 February 2024 + +This update includes the following changes over the previous release: + +### Contributors +Thanks to the following public contributors. Their efforts toward this project are very much appreciated. + +- [Wraith2](https://github.com/Wraith2) +- [ErikEJ](https://github.com/ErikEJ) +- [kant2002](https://github.com/kant2002) +- [mattjohnsonpint](https://github.com/mattjohnsonpint) +- [azerios](https://github.com/azerios) +- [jinek](https://github.com/jinek) +- [christothes](https://github.com/christothes) +- [panoskj](https://github.com/panoskj) +- [saitama951](https://github.com/saitama951) +- [danielmarbach](https://github.com/danielmarbach) +- [wsugarman](https://github.com/wsugarman) +- [ViktorHofer](https://github.com/ViktorHofer) +- [emidah](https://github.com/emidah) + +### Added + +- Added a new `AccessTokenCallback` API to `SqlConnection`. [#1260](https://github.com/dotnet/SqlClient/pull/1260) [Read more](#added-new-property-accesstokencallback-to-sqlconnection) +- Added `SqlBatch` support on .NET 6+ [#1825](https://github.com/dotnet/SqlClient/pull/1825), [#2223](https://github.com/dotnet/SqlClient/pull/2223), [#2371](https://github.com/dotnet/SqlClient/pull/2371), [#2373](https://github.com/dotnet/SqlClient/pull/2373) [Read more](#added-new-property-sqlbatch-api) +- Added support of `SqlDiagnosticListener` on **.NET Standard**. [#1931](https://github.com/dotnet/SqlClient/pull/1931) +- Added new property `RowsCopied64` to `SqlBulkCopy`. [#2004](https://github.com/dotnet/SqlClient/pull/2004) [Read more](#added-new-property-rowscopied64-to-sqlbulkcopy) +- Added support for the `SuperSocketNetLib` registry option for Encrypt on .NET on Windows. [#2047](https://github.com/dotnet/SqlClient/pull/2047) +- Added the ability to generate debugging symbols in a separate package file [#2137](https://github.com/dotnet/SqlClient/pull/2137) +- Added Workload Identity authentication support [#2159](https://github.com/dotnet/SqlClient/pull/2159), [#2264](https://github.com/dotnet/SqlClient/pull/2264) +- Added support for Big Endian systems [#2170](https://github.com/dotnet/SqlClient/pull/2170) +- Added support for Georgian collation [#2194](https://github.com/dotnet/SqlClient/pull/2194) +- Added Localization support on .NET [#2210](https://github.com/dotnet/SqlClient/pull/2110) +- Added .NET 8 support [#2230](https://github.com/dotnet/SqlClient/pull/2230) +- Added explicit version for major .NET version dependencies on System.Runtime.Caching 8.0.0, System.Configuration.ConfigurationManager 8.0.0, and System.Diagnostics.DiagnosticSource 8.0.0 [#2303](https://github.com/dotnet/SqlClient/pull/2303) + +### Changed + +- Improved parsing buffered characters in `TdsParser`. [#1544](https://github.com/dotnet/SqlClient/pull/1544) +- Added Microsoft.SqlServer.Types to verify support for SqlHierarchyId and Spatial for .NET Core. [#1848](https://github.com/dotnet/SqlClient/pull/1848) +- Moved to new System.Data.SqlTypes APIs in **.NET 7** and upper. [#1934](https://github.com/dotnet/SqlClient/pull/1934) and [#1981](https://github.com/dotnet/SqlClient/pull/1981) +- Removed reference to Microsoft.Win32.Registry since it's shipped starting with .NET 6.0. [#1974](https://github.com/dotnet/SqlClient/pull/1974) +- Changed **[UseOneSecFloorInTimeoutCalculationDuringLogin](https://learn.microsoft.com/sql/connect/ado-net/appcontext-switches#enable-a-minimum-timeout-during-login)** App Context switch default to **true** and extended its effect to .NET and .NET Standard. [#2012](https://github.com/dotnet/SqlClient/pull/2012) +- Updated `Microsoft.Identity.Client` version from 4.47.2 to 4.53.0. [#2031](https://github.com/dotnet/SqlClient/pull/2031), [#2055](https://github.com/dotnet/SqlClient/pull/2055) +- Switched to the new .NET [NegotiateAuthentication](https://learn.microsoft.com/en-us/dotnet/api/system.net.security.negotiateauthentication?view=net-7.0) API on .NET 7.0 and above for SSPI token negotiation using Managed SNI. [#2063](https://github.com/dotnet/SqlClient/pull/2063) +- Removed `ignoreSniOpenTimeout` in open connection process on Windows. [#2067](https://github.com/dotnet/SqlClient/pull/2067) +- Enforce explicit ordinal for internal `StringComparison` operations. [#2068](https://github.com/dotnet/SqlClient/pull/2068) +- Improved error messages when validating server certificates in managed SNI (Linux/macOS) [#2060](https://github.com/dotnet/SqlClient/pull/2060) +- Improved CPU usage when `AppContext` switches are in use [#2227](https://github.com/dotnet/SqlClient/pull/2227) +- Upgraded `Azure.Identity` dependency version to [1.10.3](https://www.nuget.org/packages/Azure.Identity/1.10.3) to address [CVE-2023-36414](https://github.com/advisories/GHSA-5mfx-4wcx-rv27), [#2189](https://github.com/dotnet/SqlClient/pull/2189) +- Changed Microsoft.IdentityModel.JsonWebTokens and Microsoft.IdentityModel.Protocols.OpenIdConnect version 6.24.0 to 6.35.0 [#2290](https://github.com/dotnet/SqlClient/pull/2290) to address [CVE-2024-21319](https://www.cve.org/CVERecord?id=CVE-2024-21319) +- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET/.NET Standard dependency) version to `v5.2.0`. [#2363](https://github.com/dotnet/SqlClient/pull/2363), which includes removing dead code and addressing static analysis warnings +- Code health improvements: [#1198](https://github.com/dotnet/SqlClient/pull/1198), [#1829](https://github.com/dotnet/SqlClient/pull/1829), [#1943](https://github.com/dotnet/SqlClient/pull/1943), [#1949](https://github.com/dotnet/SqlClient/pull/1949), [#1959](https://github.com/dotnet/SqlClient/pull/1959), [#1985](https://github.com/dotnet/SqlClient/pull/1985), [#2071](https://github.com/dotnet/SqlClient/pull/2071), [#2073](https://github.com/dotnet/SqlClient/pull/2073), [#2088](https://github.com/dotnet/SqlClient/pull/2088), [#2091](https://github.com/dotnet/SqlClient/pull/2091), [#2098](https://github.com/dotnet/SqlClient/pull/2098), [#2121](https://github.com/dotnet/SqlClient/pull/2121), [#2122](https://github.com/dotnet/SqlClient/pull/2122), [#2132](https://github.com/dotnet/SqlClient/pull/2132), [#2136](https://github.com/dotnet/SqlClient/pull/2136), [#2144](https://github.com/dotnet/SqlClient/pull/2144), [#2147](https://github.com/dotnet/SqlClient/pull/2147), [#2157](https://github.com/dotnet/SqlClient/pull/2157), [#2164](https://github.com/dotnet/SqlClient/pull/2164), [#2166](https://github.com/dotnet/SqlClient/pull/2166), [#2168](https://github.com/dotnet/SqlClient/pull/2168), [#2186](https://github.com/dotnet/SqlClient/pull/2186), [#2254](https://github.com/dotnet/SqlClient/pull/2254), [#2288](https://github.com/dotnet/SqlClient/pull/2288), [#2305](https://github.com/dotnet/SqlClient/pull/2305), [#2317](https://github.com/dotnet/SqlClient/pull/2317) + +### Fixed + +- Fixed Always Encrypted secure enclave retry logic for async queries. [#1988](https://github.com/dotnet/SqlClient/pull/1988) +- Fixed activity correlator to continue use of same GUID for connection activity. [#1997](https://github.com/dotnet/SqlClient/pull/1997) +- Fixed behavior when error class is greater than 20 on connection retry. [#1953](https://github.com/dotnet/SqlClient/pull/1953) +- Fixed error message when symmetric key decryption failed using Always Encrypted. [#1948](https://github.com/dotnet/SqlClient/pull/1948) +- Fixed TransactionScope connection issue when Enlist is enable, Pooling is disabled and network connection type is Redirect. [#1960](https://github.com/dotnet/SqlClient/pull/1960) +- Fixed TDS RPC error on large queries in SqlCommand.ExecuteReaderAsync. [#1936](https://github.com/dotnet/SqlClient/pull/1936) +- Fixed throttling of token requests by calling AcquireTokenSilent. [#1925](https://github.com/dotnet/SqlClient/pull/1925) +- Fixed Linux code coverage result in Build proj. [#1950](https://github.com/dotnet/SqlClient/pull/1950) +- Fixed NullReferenceException in GetBytesAsync. [#1906](https://github.com/dotnet/SqlClient/pull/1906) +- Fixed Transient fault handling issue with OpenAsync. [#1983](https://github.com/dotnet/SqlClient/pull/1983) +- Fixed invariant mode checks. [#1917](https://github.com/dotnet/SqlClient/pull/1917) +- Fixed GC behavior in TdsParser by adding array rental capability in TryReadPlpUnicodeChars. [#1866](https://github.com/dotnet/SqlClient/pull/1866) +- Fixed socket synchronization issue during connect in managed SNI. [#1029](https://github.com/dotnet/SqlClient/pull/1029) +- Fixed issue with `SqlConnectionStringBuilder` property indexer not supporting non-string values. [#2018](https://github.com/dotnet/SqlClient/pull/2018) +- Fixed `SqlDataAdapter.Fill` and configurable retry logic issue on .NET Framework. [#2084](https://github.com/dotnet/SqlClient/pull/2084) +- Fixed `SqlConnectionEncryptOption` type conversion by introducing the `SqlConnectionEncryptOptionConverter` attribute when using **appsettings.json** files. [#2057](https://github.com/dotnet/SqlClient/pull/2057) +- Fixed th-TH culture info issue on Managed SNI. [#2066](https://github.com/dotnet/SqlClient/pull/2066) +- Fixed an issue when using the Authentication option, but not encrypting on .NET Framework where the server certificate was being incorrectly validated [#2224](https://github.com/dotnet/SqlClient/pull/2224) +- Fixed a deadlock problem for distributed transactions when on .NET [#2161](https://github.com/dotnet/SqlClient/pull/2161) +- Fixed an issue with connecting to named instances on named pipes in managed SNI (Linux/macOS) [#2142](https://github.com/dotnet/SqlClient/pull/2142) +- Fixed LocalDb connection issue with an invalid source when using managed SNI [#2129](https://github.com/dotnet/SqlClient/pull/2129) +- Fixed an `AccessViolationException` when using a SQL Express user instance [#2101](https://github.com/dotnet/SqlClient/pull/2101) +- Fixed a metadata query issue when connecting to Azure SQL Edge [#2099](https://github.com/dotnet/SqlClient/pull/2099) +- Fixed file version information for .NET and .NET Standard binaries [#2093](https://github.com/dotnet/SqlClient/pull/2093) +- Fixed the SPN sent for a named instance when using Kerberos authentication on Linux/macOS [#2240](https://github.com/dotnet/SqlClient/pull/2240) +- Fixed connection to unsubscribe from transaction completion events before returning it to the connection pool [#2301](https://github.com/dotnet/SqlClient/pull/2301) +- Fixed InvalidCastException when reading an Always Encrypted date or time column [#2275](https://github.com/dotnet/SqlClient/pull/2275) +- Fixed token caching to prevent expired access tokens from being reused in a connection pool [#2273](https://github.com/dotnet/SqlClient/pull/2273) + +## New features + +### Added new property `SQLBatch API` + +```csharp +using Microsoft.Data.SqlClient; + +class Program +{ + static void Main() + { + string str = "Data Source=(local);Initial Catalog=Northwind;" + + "Integrated Security=SSPI;Encrypt=False"; + RunBatch(str); + } + + static void RunBatch(string connString) + { + using var connection = new SqlConnection(connString); + connection.Open(); + + var batch = new SqlBatch(connection); + + const int count = 10; + const string parameterName = "parameter"; + for (int i = 0; i < count; i++) + { + var batchCommand = new SqlBatchCommand($"SELECT @{parameterName} as value"); + batchCommand.Parameters.Add(new SqlParameter(parameterName, i)); + batch.BatchCommands.Add(batchCommand); + } + + // Optionally Prepare + batch.Prepare(); + + var results = new List(count); + using (SqlDataReader reader = batch.ExecuteReader()) + { + do + { + while (reader.Read()) + { + results.Add(reader.GetFieldValue(0)); + } + } while (reader.NextResult()); + } + Console.WriteLine(string.Join(", ", results)); + } +} +``` + +### Added new property `RowsCopied64` to SqlBulkCopy + +SqlBulkCopy has a new property `RowsCopied64` which supports `long` value types. + +**Note that the existing `SqlBulkCopy.RowsCopied` behavior is unchanged. When the value exceeds `int.MaxValue`, `RowsCopied` can return a negative number.** + +Example usage: + +```C# + using (SqlConnection srcConn = new SqlConnection(srcConstr)) + using (SqlCommand srcCmd = new SqlCommand("select top 5 * from employees", srcConn)) + { + srcConn.Open(); + using (DbDataReader reader = srcCmd.ExecuteReader()) + { + using (SqlBulkCopy bulkcopy = new SqlBulkCopy(dstConn)) + { + bulkcopy.DestinationTableName = dstTable; + SqlBulkCopyColumnMappingCollection ColumnMappings = bulkcopy.ColumnMappings; + + ColumnMappings.Add("EmployeeID", "col1"); + ColumnMappings.Add("LastName", "col2"); + ColumnMappings.Add("FirstName", "col3"); + + bulkcopy.WriteToServer(reader); + long rowsCopied = bulkcopy.RowsCopied64; + } + } + } +``` + +### Added new property `AccessTokenCallback` to SqlConnection + +SqlConnection supports `TokenCredential` authentication by introducing a new `AccessTokenCallback` property as a `Func>` delegate to return a federated authentication access token. + +Example usage: + +```C# + using Microsoft.Data.SqlClient; + using Azure.Identity; + + const string defaultScopeSuffix = "/.default"; + string connectionString = GetConnectionString(); + using SqlConnection connection = new SqlConnection(connectionString); + + connection.AccessTokenCallback = async (authParams, cancellationToken) => + { + var cred = new DefaultAzureCredential(); + string scope = authParams.Resource.EndsWith(defaultScopeSuffix) ? authParams.Resource : authParams.Resource + defaultScopeSuffix; + AccessToken token = await cred.GetTokenAsync(new TokenRequestContext(new[] { scope }), cancellationToken); + return new SqlAuthenticationToken(token.Token, token.ExpiresOn); + } + + connection.Open(); + Console.WriteLine("ServerVersion: {0}", connection.ServerVersion); + Console.WriteLine("State: {0}", connection.State); +``` + +## Target Platform Support + +- .NET Framework 4.6.2+ (Windows x86, Windows x64) +- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) +- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) + +### Dependencies + +#### .NET Framework + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.10.3 +- Microsoft.Identity.Client 4.56.0 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- System.Buffers 4.5.1 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Runtime.InteropServices.RuntimeInformation 4.3.0 +- System.Text.Encoding.Web 6.0.0 + +#### .NET 6 + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.10.3 +- Microsoft.Identity.Client 4.56.0 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Diagnostics.DiagnosticSource 6.0.1 +- System.Runtime.Caching 6.0.0 + +#### .NET 8 + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.10.3 +- Microsoft.Identity.Client 4.56.0 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- System.Configuration.ConfigurationManager 8.0.0 +- System.Diagnostics.DiagnosticSource 8.0.0 +- System.Runtime.Caching 8.0.0 + +#### .NET Standard 2.0 + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.10.3 +- Microsoft.Identity.Client 4.56.0 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- Microsoft.Win32.Registry 5.0.0 +- System.Buffers 4.5.1 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Diagnostics.DiagnosticSource 6.0.1 +- System.Runtime.Caching 6.0.0 +- System.Text.Encoding.CodePages 6.0.0 +- System.Text.Encodings.Web 6.0.0 +- System.Runtime.Loader 4.3.0 +- System.Security.Cryptography.Cng 5.0.0 +- System.Security.Principal.Windows 5.0.0 + +#### .NET Standard 2.1 + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.10.3 +- Microsoft.Identity.Client 4.56.0 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- Microsoft.Win32.Registry 5.0.0 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Diagnostics.DiagnosticSource 6.0.1 +- System.Runtime.Caching 6.0.0 +- System.Text.Encoding.CodePages 6.0.0 +- System.Text.Encodings.Web 6.0.0 +- System.Runtime.Loader 4.3.0 +- System.Security.Cryptography.Cng 5.0.0 +- System.Security.Principal.Windows 5.0.0 + diff --git a/release-notes/5.2/5.2.md b/release-notes/5.2/5.2.md new file mode 100644 index 0000000000..8193904e37 --- /dev/null +++ b/release-notes/5.2/5.2.md @@ -0,0 +1,18 @@ +# Microsoft.Data.SqlClient 5.2 Releases + +The following Microsoft.Data.SqlClient 5.2 stable releases have been shipped: + +| Release Date | Version | Notes | +| :-- | :-- | :--: | +| 2024/02/28 | 5.2.0 | [release notes](5.2.0.md) | + +The following Microsoft.Data.SqlClient 5.2 preview releases have been shipped: + +| Release Date | Version | Notes | +| :-- | :-- | :--: | +| 2024/01/24 | 5.2.0-preview5.24024.3 | [release notes](5.2.0-preview5.md) | +| 2023/12/08 | 5.2.0-preview4.23342.2 | [release notes](5.2.0-preview4.md) | +| 2023/07/20 | 5.2.0-preview3.23201.1 | [release notes](5.2.0-preview3.md) | +| 2023/06/08 | 5.2.0-preview2.23159.1 | [release notes](5.2.0-preview2.md) | +| 2023/04/20 | 5.2.0-preview1.23109.1 | [release notes](5.2.0-preview1.md) | + diff --git a/release-notes/5.2/README.md b/release-notes/5.2/README.md index 8d4c031aea..a311f99484 100644 --- a/release-notes/5.2/README.md +++ b/release-notes/5.2/README.md @@ -1,5 +1,11 @@ # Microsoft.Data.SqlClient 5.2 Releases +The following Microsoft.Data.SqlClient 5.2 stable releases have been shipped: + +| Release Date | Version | Notes | +| :-- | :-- | :--: | +| 2024/02/28 | 5.2.0 | [release notes](5.2.0.md) | + The following Microsoft.Data.SqlClient 5.2 preview releases have been shipped: | Release Date | Version | Notes | diff --git a/release-notes/README.md b/release-notes/README.md index 94f7459695..8a23b21e3b 100644 --- a/release-notes/README.md +++ b/release-notes/README.md @@ -1,6 +1,6 @@ # Microsoft.Data.SqlClient Release Notes -The latest stable release is [Microsoft.Data.SqlClient 5.1](5.1). +The latest stable release is [Microsoft.Data.SqlClient 5.2](5.2). ## Release Information @@ -18,7 +18,7 @@ The latest stable release is [Microsoft.Data.SqlClient 5.1](5.1). # Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider Release Notes -The latest stable release is [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 3.0](add-ons/AzureKeyVaultProvider/3.0). +The latest stable release is [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 5.1](add-ons/AzureKeyVaultProvider/5.1). ## Release Information From 8ef005a2ee67c55b2900bcbe32a931e3de64c556 Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Wed, 28 Feb 2024 17:38:28 -0600 Subject: [PATCH 02/53] Build Tweaks for Onboarding (#2366) --- src/Directory.Build.props | 7 ++- src/Microsoft.Data.SqlClient.sln | 52 ++++++++++++++----- .../Sql/SqlDataSourceEnumerator.Windows.cs | 2 +- .../Data/Sql/SqlDataSourceEnumerator.cs | 6 +-- .../tests/NuGet.config | 8 --- src/NuGet.config | 2 +- 6 files changed, 49 insertions(+), 28 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/tests/NuGet.config diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 27b5f364dd..0bd20392c2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -95,5 +95,10 @@ - + + + + + false + diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index b09409f828..d47f0a450e 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -78,6 +78,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.Sql", "Microsoft.Data.Sql", "{0CE216CE-8072-4985-B248-61F0D0BE9C2E}" ProjectSection(SolutionItems) = preProject ..\doc\snippets\Microsoft.Data.Sql\SqlNotificationRequest.xml = ..\doc\snippets\Microsoft.Data.Sql\SqlNotificationRequest.xml + ..\doc\snippets\Microsoft.Data.Sql\SqlDataSourceEnumerator.xml = ..\doc\snippets\Microsoft.Data.Sql\SqlDataSourceEnumerator.xml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient", "{C05F4FFE-6A14-4409-AA0A-10630BE4F1EE}" @@ -142,6 +143,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", ..\doc\snippets\Microsoft.Data.SqlClient\SqlRowUpdatingEventArgs.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRowUpdatingEventArgs.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlRowUpdatingEventHandler.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRowUpdatingEventHandler.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnOrderHint.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnOrderHint.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnOrderHintCollection.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnOrderHintCollection.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlConfigurableRetryFactory.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConfigurableRetryFactory.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionIPAddressPreference.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionIPAddressPreference.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionOverrides.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionOverrides.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryingEventArgs.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryingEventArgs.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryIntervalBaseEnumerator.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryIntervalBaseEnumerator.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicBase.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicBase.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicBaseProvider.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicBaseProvider.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicOption.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlRetryLogicOption.xml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient.DataClassification", "Microsoft.Data.SqlClient.DataClassification", "{5D1F0032-7B0D-4FB6-A969-FCFB25C9EA1D}" @@ -151,22 +162,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient.Da ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\Label.xml = ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\Label.xml ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityClassification.xml = ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityClassification.xml ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityProperty.xml = ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityProperty.xml + ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityRank.xml = ..\doc\snippets\Microsoft.Data.SqlClient.DataClassification\SensitivityRank.xml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient.Server", "Microsoft.Data.SqlClient.Server", "{650EB7FA-EB0D-4F8E-AB2C-161C3AD8E363}" ProjectSection(SolutionItems) = preProject - ..\doc\snippets\Microsoft.Data.SqlClient.Server\DataAccessKind.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\DataAccessKind.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\Format.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\Format.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\IBinarySerialize.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\IBinarySerialize.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\InvalidUdtException.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\InvalidUdtException.xml ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlFacetAttribute.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlFacetAttribute.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlFunctionAttribute.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlFunctionAttribute.xml ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlMetaData.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlMetaData.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlMethodAttribute.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlMethodAttribute.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlUserDefinedAggregateAttribute.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlUserDefinedAggregateAttribute.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlUserDefinedTypeAttribute.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlUserDefinedTypeAttribute.xml - ..\doc\snippets\Microsoft.Data.SqlClient.Server\SystemDataAccessKind.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\SystemDataAccessKind.xml ..\doc\snippets\Microsoft.Data.SqlClient.Server\TriggerAction.xml = ..\doc\snippets\Microsoft.Data.SqlClient.Server\TriggerAction.xml EndProjectSection EndProject @@ -197,9 +199,29 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.PerformanceTests", "Microsoft.Data.SqlClient\tests\PerformanceTests\Microsoft.Data.SqlClient.PerformanceTests.csproj", "{599A336B-2A5F-473D-8442-1223ED37C93E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4F3CD363-B1E6-4D6D-9466-97D78A56BE45}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + NuGet.config = NuGet.config + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlServer.Server", "Microsoft.SqlServer.Server\Microsoft.SqlServer.Server.csproj", "{A314812A-7820-4565-A2A8-ABBE391C11E4}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.SqlServer.Server", "Microsoft.SqlServer.Server", "{869A9BCC-D303-4365-9BF7-958CD6387916}" + ProjectSection(SolutionItems) = preProject + ..\doc\snippets\Microsoft.SqlServer.Server\DataAccessKind.xml = ..\doc\snippets\Microsoft.SqlServer.Server\DataAccessKind.xml + ..\doc\snippets\Microsoft.SqlServer.Server\Format.xml = ..\doc\snippets\Microsoft.SqlServer.Server\Format.xml + ..\doc\snippets\Microsoft.SqlServer.Server\IBinarySerialize.xml = ..\doc\snippets\Microsoft.SqlServer.Server\IBinarySerialize.xml + ..\doc\snippets\Microsoft.SqlServer.Server\InvalidUdtException.xml = ..\doc\snippets\Microsoft.SqlServer.Server\InvalidUdtException.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SqlFacetAttribute.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SqlFacetAttribute.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SqlFunctionAttribute.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SqlFunctionAttribute.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SqlMethodAttribute.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SqlMethodAttribute.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SqlUserDefinedAggregateAttribute.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SqlUserDefinedAggregateAttribute.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SqlUserDefinedTypeAttribute.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SqlUserDefinedTypeAttribute.xml + ..\doc\snippets\Microsoft.SqlServer.Server\SystemDataAccessKind.xml = ..\doc\snippets\Microsoft.SqlServer.Server\SystemDataAccessKind.xml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestClr", "TestClr", "{CDE508A5-F5D0-4A59-A4EF-978833830727}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -483,11 +505,7 @@ Global {8DC9D1A0-351B-47BC-A90F-B9DA542550E9} = {0CC4817A-12F3-4357-912C-09315FAAD008} {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9} = {0CC4817A-12F3-4357-912C-09315FAAD008} {37431336-5307-4184-9356-C4B7E47DC714} = {28E5EFE6-C9DD-4FF9-9FEC-532F72DFFA6E} - {D1392B54-998A-4F27-BC17-4CE149117BCC} = {0CC4817A-12F3-4357-912C-09315FAAD008} {45DB5F86-7AE3-45C6-870D-F9357B66BDB5} = {0CC4817A-12F3-4357-912C-09315FAAD008} - {6C88F00F-9597-43AD-9E5F-9B344DA3B16F} = {0CC4817A-12F3-4357-912C-09315FAAD008} - {B73A7063-37C3-415D-AD53-BB3DA20ABD6E} = {0CC4817A-12F3-4357-912C-09315FAAD008} - {E0A6BB21-574B-43D9-890D-6E1144F2EE9E} = {0CC4817A-12F3-4357-912C-09315FAAD008} {A2E7E470-5EFF-4828-B55E-FCBA3650F51C} = {28E5EFE6-C9DD-4FF9-9FEC-532F72DFFA6E} {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B} = {A2E7E470-5EFF-4828-B55E-FCBA3650F51C} {771F3F1E-7A68-4A9D-ADA8-A24F1D5BE71D} = {3FDD425C-FE01-4B56-863E-1FCDD0677CF5} @@ -507,6 +525,12 @@ Global {B93A3149-67E8-491E-A1E5-19D65F9D9E98} = {0CC4817A-12F3-4357-912C-09315FAAD008} {599A336B-2A5F-473D-8442-1223ED37C93E} = {0CC4817A-12F3-4357-912C-09315FAAD008} {A314812A-7820-4565-A2A8-ABBE391C11E4} = {4F3CD363-B1E6-4D6D-9466-97D78A56BE45} + {869A9BCC-D303-4365-9BF7-958CD6387916} = {71F356DC-DFA3-4163-8BFE-D268722CE189} + {CDE508A5-F5D0-4A59-A4EF-978833830727} = {0CC4817A-12F3-4357-912C-09315FAAD008} + {D1392B54-998A-4F27-BC17-4CE149117BCC} = {CDE508A5-F5D0-4A59-A4EF-978833830727} + {6C88F00F-9597-43AD-9E5F-9B344DA3B16F} = {CDE508A5-F5D0-4A59-A4EF-978833830727} + {B73A7063-37C3-415D-AD53-BB3DA20ABD6E} = {CDE508A5-F5D0-4A59-A4EF-978833830727} + {E0A6BB21-574B-43D9-890D-6E1144F2EE9E} = {CDE508A5-F5D0-4A59-A4EF-978833830727} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {01D48116-37A2-4D33-B9EC-94793C702431} 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 index 83ce5085e7..25caa8911b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs @@ -7,7 +7,7 @@ namespace Microsoft.Data.Sql { - /// + /// public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator { private partial DataTable GetDataSourcesInternal() 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 e8f7aac29c..496c887294 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs @@ -7,17 +7,17 @@ namespace Microsoft.Data.Sql { - /// + /// public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator { private static readonly Lazy s_singletonInstance = new(() => new SqlDataSourceEnumerator()); private SqlDataSourceEnumerator() : base(){} - /// + /// public static SqlDataSourceEnumerator Instance => s_singletonInstance.Value; - /// + /// override public DataTable GetDataSources() => GetDataSourcesInternal(); private partial DataTable GetDataSourcesInternal(); diff --git a/src/Microsoft.Data.SqlClient/tests/NuGet.config b/src/Microsoft.Data.SqlClient/tests/NuGet.config deleted file mode 100644 index 366141ab39..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/NuGet.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/NuGet.config b/src/NuGet.config index 5832a9da27..3233e60161 100644 --- a/src/NuGet.config +++ b/src/NuGet.config @@ -2,6 +2,6 @@ - + From 1a009b46c9729080c477882b3ce4c26285964de5 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Fri, 1 Mar 2024 18:49:25 +0100 Subject: [PATCH 03/53] Test | Improve test quality of life (#2331) --- .../BaseProviderAsyncTest/BaseProviderAsyncTest.cs | 2 +- .../FunctionalTests/BaseProviderAsyncTest/MockCommand.cs | 2 +- .../FunctionalTests/BaseProviderAsyncTest/MockConnection.cs | 2 +- .../FunctionalTests/BaseProviderAsyncTest/MockDataReader.cs | 2 +- .../tests/FunctionalTests/SqlMetaDataTest.cs | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/BaseProviderAsyncTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/BaseProviderAsyncTest.cs index 0d13ad5f77..92acc68092 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/BaseProviderAsyncTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/BaseProviderAsyncTest.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; using Xunit; -namespace Microsoft.Data.SqlClient.ManualTesting.Tests +namespace Microsoft.Data.SqlClient.Tests { public static class BaseProviderAsyncTest { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockCommand.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockCommand.cs index eef8d13700..ce77e22db8 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockCommand.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockCommand.cs @@ -9,7 +9,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Data.SqlClient.ManualTesting.Tests +namespace Microsoft.Data.SqlClient.Tests { public class MockCommand : DbCommand { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockConnection.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockConnection.cs index 77c84e9f26..96f6922eb6 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockConnection.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockConnection.cs @@ -7,7 +7,7 @@ using System.Data.Common; using System.Threading; -namespace Microsoft.Data.SqlClient.ManualTesting.Tests +namespace Microsoft.Data.SqlClient.Tests { public class MockConnection : DbConnection { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockDataReader.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockDataReader.cs index 5914f9825a..b4e6875ddc 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockDataReader.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/BaseProviderAsyncTest/MockDataReader.cs @@ -7,7 +7,7 @@ using System.Data.Common; using System.Threading; -namespace Microsoft.Data.SqlClient.ManualTesting.Tests +namespace Microsoft.Data.SqlClient.Tests { internal class MockDataReader : DbDataReader { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs index a9123e1582..dd6c228fd2 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlMetaDataTest.cs @@ -870,7 +870,7 @@ public void XmlConstructorWithNullObjectName_Throws() new object[] {SqlDbType.Bit, new SqlBinary(new byte[] { 1 })}, new object[] {SqlDbType.Decimal, new SqlBytes()}, new object[] {SqlDbType.Char, new TimeSpan(0, 0, 1)}, - new object[] {SqlDbType.UniqueIdentifier, new DateTimeOffset(new DateTime(0))}, + new object[] {SqlDbType.UniqueIdentifier, new DateTimeOffset(new DateTime(0), TimeSpan.Zero)}, new object[] {SqlDbType.DateTimeOffset, SqlGuid.Null}, new object[] {SqlDbType.Date, new SqlDateTime(DateTime.UtcNow)}, new object[] {SqlDbType.Bit, SqlXml.Null }, @@ -963,7 +963,7 @@ public void XmlConstructorWithNullObjectName_Throws() new object[] {SqlDbType.Image, new SqlBinary(new byte[] { 1 })}, new object[] {SqlDbType.Image, new SqlBytes(new byte[] { 1 })}, new object[] {SqlDbType.Time, new TimeSpan(0, 0, 1)}, - new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0))}, + new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0), TimeSpan.Zero)}, new object[] {SqlDbType.UniqueIdentifier, SqlGuid.Null}, new object[] {SqlDbType.UniqueIdentifier, Guid.Empty}, }; @@ -1019,7 +1019,7 @@ public void XmlConstructorWithNullObjectName_Throws() new object[] {SqlDbType.VarBinary, new byte[8001]}, new object[] {SqlDbType.Time, new TimeSpan(0, 0, 1)}, new object[] {SqlDbType.Time, new TimeSpan(TimeSpan.TicksPerDay - 1)}, - new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0))}, + new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(new DateTime(0), TimeSpan.Zero)}, new object[] {SqlDbType.DateTimeOffset, new DateTimeOffset(DateTime.Now)}, new object[] {SqlDbType.UniqueIdentifier, SqlGuid.Null}, new object[] {SqlDbType.UniqueIdentifier, Guid.Empty}, From ced726a3ee7b955be238267cc6dd7d61971731b4 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 1 Mar 2024 13:04:36 -0800 Subject: [PATCH 04/53] Remove test reference to deprecated ADAL library (#2360) --- .../ManualTests/DataCommon/AADUtility.cs | 14 ---- .../SqlClientCustomTokenCredential.cs | 67 ++++++------------- ....Data.SqlClient.ManualTesting.Tests.csproj | 3 - tools/props/Versions.props | 2 - 4 files changed, 20 insertions(+), 66 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs index 6733b49b31..55ab5744e6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs @@ -7,25 +7,11 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Clients.ActiveDirectory; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class AADUtility { - public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource, string scope) - { - var authContext = new AuthenticationContext(authority); - ClientCredential clientCred = new ClientCredential(DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); - if (result == null) - { - throw new Exception($"Failed to retrieve an access token for {resource}"); - } - - return result.AccessToken; - } - public static async Task GetManagedIdentityToken(string clientId = null) => await new MockManagedIdentityTokenProvider().AcquireTokenAsync(clientId).ConfigureAwait(false); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index c83883fca1..8b1ef93e61 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -3,20 +3,21 @@ // See the LICENSE file in the project root for more information. using System; -using System.IdentityModel.Tokens.Jwt; +using System.Collections.Concurrent; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Azure.Core; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Azure.Identity; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class SqlClientCustomTokenCredential : TokenCredential { + private const string DEFAULT_PREFIX = "/.default"; + private static readonly ConcurrentDictionary s_clientSecretCredentials = new(); + string _authority = ""; string _resource = ""; string _akvUrl = ""; @@ -70,40 +71,8 @@ private async Task AcquireTokenAsync() _akvUrl = DataTestUtility.AKVUrl; } - string strAccessToken = await AzureActiveDirectoryAuthenticationCallback(_authority, _resource); - DateTime expiryTime = InterceptAccessTokenForExpiry(strAccessToken); - return new AccessToken(strAccessToken, new DateTimeOffset(expiryTime)); - } - - private DateTime InterceptAccessTokenForExpiry(string accessToken) - { - if (null == accessToken) - { - throw new ArgumentNullException(accessToken); - } - - var jwtHandler = new JwtSecurityTokenHandler(); - var jwtOutput = string.Empty; - - // Check Token Format - if (!jwtHandler.CanReadToken(accessToken)) - throw new FormatException(accessToken); - - JwtSecurityToken token = jwtHandler.ReadJwtToken(accessToken); - - // Re-serialize the Token Headers to just Key and Values - var jwtHeader = JsonConvert.SerializeObject(token.Header.Select(h => new { h.Key, h.Value })); - jwtOutput = $"{{\r\n\"Header\":\r\n{JToken.Parse(jwtHeader)},"; - - // Re-serialize the Token Claims to just Type and Values - var jwtPayload = JsonConvert.SerializeObject(token.Claims.Select(c => new { c.Type, c.Value })); - jwtOutput += $"\r\n\"Payload\":\r\n{JToken.Parse(jwtPayload)}\r\n}}"; - - // Output the whole thing to pretty JSON object formatted. - string jToken = JToken.Parse(jwtOutput).ToString(Formatting.Indented); - JToken payload = JObject.Parse(jToken).GetValue("Payload"); - - return new DateTime(1970, 1, 1).AddSeconds((long)payload[4]["Value"]); + AccessToken accessToken = await AzureActiveDirectoryAuthenticationCallback(_authority, _resource); + return accessToken; } private static string ValidateChallenge(string challenge) @@ -127,16 +96,20 @@ private static string ValidateChallenge(string challenge) /// Authorization URL /// Resource /// - public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource) + public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource) { - var authContext = new AuthenticationContext(authority); - ClientCredential clientCred = new ClientCredential(DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); - if (result == null) - { - throw new InvalidOperationException($"Failed to retrieve an access token for {resource}"); - } - return result.AccessToken; + using CancellationTokenSource cts = new(); + cts.CancelAfter(30000); // Hard coded for tests + string[] scopes = new string[] { resource + DEFAULT_PREFIX }; + TokenRequestContext tokenRequestContext = new(scopes); + int separatorIndex = authority.LastIndexOf('/'); + string authorityHost = authority.Remove(separatorIndex + 1); + string audience = authority.Substring(separatorIndex + 1); + TokenCredentialOptions tokenCredentialOptions = new TokenCredentialOptions() { AuthorityHost = new Uri(authorityHost) }; + ClientSecretCredential clientSecretCredential = s_clientSecretCredentials.GetOrAdd(authority + "|--|" + resource, + new ClientSecretCredential(audience, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret, tokenCredentialOptions)); + AccessToken accessToken = await clientSecretCredential.GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + return accessToken; } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index da3f55dfc1..68e631cc5c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -332,17 +332,14 @@ - - - diff --git a/tools/props/Versions.props b/tools/props/Versions.props index 80db684225..a41fd120d1 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -63,12 +63,10 @@ 9.0.0-beta.23613.3 3.1.6 - 5.2.9 17.8.0 13.0.1 4.3.0 6.0.1 - 6.35.0 2.6.3 2.5.5 1.0.3 From 2ddf7237328b45a4a5a9d41dc7d7edf4f566ae9b Mon Sep 17 00:00:00 2001 From: Jihoon Park Date: Mon, 4 Mar 2024 13:44:09 -0500 Subject: [PATCH 05/53] Doc | Fix typo in SqlConnectionEncryptOption.xml (#2381) --- .../Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml index 35b8d24ab6..39111465a3 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml @@ -7,7 +7,7 @@ property. When converting from a boolean, a value of `true` converts to and a value of `false` converts to . When converting to a boolean, , , and `null` convert to `true` and converts `false`. +Implicit conversions have been added to maintain backwards compatibility with boolean behavior for the property. When converting from a boolean, a value of `true` converts to and a value of `false` converts to . When converting to a boolean, , , and `null` convert to `true` and converts `false`. ]]> @@ -49,13 +49,13 @@ Implicit conversions have been added to maintain backwards compatibility with bo The boolean value to be used for implicit comparison. - Enables implicit converstion of a boolean to a . A value of converts to . A value of converts to . + Enables implicit conversion of a boolean to a . A value of converts to . A value of converts to . The value to be used for implicit comparison. - Enables implicit converstion of a to a boolean. and convert to . converts to . + Enables implicit conversion of a to a boolean. and convert to . converts to . From 5376a04adf786735422029e808333d2a3c6d1fef Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:12:26 -0800 Subject: [PATCH 06/53] Fix | Fixed SqlBulkCopy.WriteToServer to ensure successful completion of consecutive calls to it. (#2375) --- .../Microsoft/Data/SqlClient/SqlBulkCopy.cs | 35 +++-- .../Microsoft/Data/SqlClient/SqlBulkCopy.cs | 34 +++-- ....Data.SqlClient.ManualTesting.Tests.csproj | 1 + .../SQL/SqlBulkCopyTest/WriteToServerTest.cs | 138 ++++++++++++++++++ 4 files changed, 179 insertions(+), 29 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/WriteToServerTest.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs index 273394395a..92c6d0075c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs @@ -1640,14 +1640,12 @@ public void WriteToServer(DbDataReader reader) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _dbDataReaderRowSource = reader; _sqlDataReaderRowSource = reader as SqlDataReader; - - _dataTableSource = null; _rowSourceType = ValueSourceType.DbDataReader; - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(reader.FieldCount, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } finally @@ -1673,12 +1671,11 @@ public void WriteToServer(IDataReader reader) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = _rowSource as SqlDataReader; _dbDataReaderRowSource = _rowSource as DbDataReader; - _dataTableSource = null; _rowSourceType = ValueSourceType.IDataReader; - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(reader.FieldCount, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } finally @@ -1707,13 +1704,12 @@ public void WriteToServer(DataTable table, DataRowState rowState) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowStateToSkip = ((rowState == 0) || (rowState == DataRowState.Deleted)) ? DataRowState.Deleted : ~rowState | DataRowState.Deleted; _rowSource = table; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.DataTable; _rowEnumerator = table.Rows.GetEnumerator(); - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(table.Columns.Count, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } @@ -1746,16 +1742,14 @@ public void WriteToServer(DataRow[] rows) try { statistics = SqlStatistics.StartTimer(Statistics); - + ResetWriteToServerGlobalVariables(); DataTable table = rows[0].Table; Debug.Assert(null != table, "How can we have rows without a table?"); _rowStateToSkip = DataRowState.Deleted; // Don't allow deleted rows _rowSource = rows; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.RowArray; _rowEnumerator = rows.GetEnumerator(); - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(table.Columns.Count, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } @@ -1787,7 +1781,7 @@ public Task WriteToServerAsync(DataRow[] rows, CancellationToken cancellationTok try { statistics = SqlStatistics.StartTimer(Statistics); - + ResetWriteToServerGlobalVariables(); if (rows.Length == 0) { return cancellationToken.IsCancellationRequested ? @@ -1800,7 +1794,6 @@ public Task WriteToServerAsync(DataRow[] rows, CancellationToken cancellationTok _rowStateToSkip = DataRowState.Deleted; // Don't allow deleted rows _rowSource = rows; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.RowArray; _rowEnumerator = rows.GetEnumerator(); _isAsyncBulkCopy = true; @@ -1834,10 +1827,10 @@ public Task WriteToServerAsync(DbDataReader reader, CancellationToken cancellati try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = reader as SqlDataReader; _dbDataReaderRowSource = reader; - _dataTableSource = null; _rowSourceType = ValueSourceType.DbDataReader; _isAsyncBulkCopy = true; resultTask = WriteRowSourceToServerAsync(reader.FieldCount, cancellationToken); // It returns Task since _isAsyncBulkCopy = true; @@ -1871,10 +1864,10 @@ public Task WriteToServerAsync(IDataReader reader, CancellationToken cancellatio try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = _rowSource as SqlDataReader; _dbDataReaderRowSource = _rowSource as DbDataReader; - _dataTableSource = null; _rowSourceType = ValueSourceType.IDataReader; _isAsyncBulkCopy = true; resultTask = WriteRowSourceToServerAsync(reader.FieldCount, cancellationToken); // It returns Task since _isAsyncBulkCopy = true; @@ -1914,9 +1907,9 @@ public Task WriteToServerAsync(DataTable table, DataRowState rowState, Cancellat try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowStateToSkip = ((rowState == 0) || (rowState == DataRowState.Deleted)) ? DataRowState.Deleted : ~rowState | DataRowState.Deleted; _rowSource = table; - _sqlDataReaderRowSource = null; _dataTableSource = table; _rowSourceType = ValueSourceType.DataTable; _rowEnumerator = table.Rows.GetEnumerator(); @@ -3093,5 +3086,17 @@ private Task WriteToServerInternalAsync(CancellationToken ctoken) } return resultTask; } + + private void ResetWriteToServerGlobalVariables() + { + _dataTableSource = null; + _dbDataReaderRowSource = null; + _isAsyncBulkCopy = false; + _rowEnumerator = null; + _rowSource = null; + _rowSourceType = ValueSourceType.Unspecified; + _sqlDataReaderRowSource = null; + _sqlDataReaderRowSource = null; + } } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs index 6b65491499..54b03683b7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs @@ -1689,6 +1689,7 @@ public void WriteToServer(DbDataReader reader) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _dbDataReaderRowSource = reader; _sqlDataReaderRowSource = reader as SqlDataReader; @@ -1697,10 +1698,8 @@ public void WriteToServer(DbDataReader reader) { _rowSourceIsSqlDataReaderSmi = _sqlDataReaderRowSource is SqlDataReaderSmi; } - _dataTableSource = null; _rowSourceType = ValueSourceType.DbDataReader; - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(reader.FieldCount, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } finally @@ -1728,6 +1727,7 @@ public void WriteToServer(IDataReader reader) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = _rowSource as SqlDataReader; if (_sqlDataReaderRowSource != null) @@ -1735,9 +1735,7 @@ public void WriteToServer(IDataReader reader) _rowSourceIsSqlDataReaderSmi = _sqlDataReaderRowSource is SqlDataReaderSmi; } _dbDataReaderRowSource = _rowSource as DbDataReader; - _dataTableSource = null; _rowSourceType = ValueSourceType.IDataReader; - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(reader.FieldCount, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } finally @@ -1768,13 +1766,12 @@ public void WriteToServer(DataTable table, DataRowState rowState) try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowStateToSkip = ((rowState == 0) || (rowState == DataRowState.Deleted)) ? DataRowState.Deleted : ~rowState | DataRowState.Deleted; _rowSource = table; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.DataTable; _rowEnumerator = table.Rows.GetEnumerator(); - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(table.Columns.Count, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } @@ -1809,16 +1806,14 @@ public void WriteToServer(DataRow[] rows) try { statistics = SqlStatistics.StartTimer(Statistics); - + ResetWriteToServerGlobalVariables(); DataTable table = rows[0].Table; Debug.Assert(null != table, "How can we have rows without a table?"); _rowStateToSkip = DataRowState.Deleted; // Don't allow deleted rows _rowSource = rows; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.RowArray; _rowEnumerator = rows.GetEnumerator(); - _isAsyncBulkCopy = false; WriteRowSourceToServerAsync(table.Columns.Count, CancellationToken.None); //It returns null since _isAsyncBulkCopy = false; } @@ -1851,7 +1846,7 @@ public Task WriteToServerAsync(DataRow[] rows, CancellationToken cancellationTok try { statistics = SqlStatistics.StartTimer(Statistics); - + ResetWriteToServerGlobalVariables(); if (rows.Length == 0) { TaskCompletionSource source = new TaskCompletionSource(); @@ -1872,7 +1867,6 @@ public Task WriteToServerAsync(DataRow[] rows, CancellationToken cancellationTok _rowStateToSkip = DataRowState.Deleted; // Don't allow deleted rows _rowSource = rows; _dataTableSource = table; - _sqlDataReaderRowSource = null; _rowSourceType = ValueSourceType.RowArray; _rowEnumerator = rows.GetEnumerator(); _isAsyncBulkCopy = true; @@ -1908,10 +1902,10 @@ public Task WriteToServerAsync(DbDataReader reader, CancellationToken cancellati try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = reader as SqlDataReader; _dbDataReaderRowSource = reader; - _dataTableSource = null; _rowSourceType = ValueSourceType.DbDataReader; _isAsyncBulkCopy = true; resultTask = WriteRowSourceToServerAsync(reader.FieldCount, cancellationToken); // It returns Task since _isAsyncBulkCopy = true; @@ -1946,10 +1940,10 @@ public Task WriteToServerAsync(IDataReader reader, CancellationToken cancellatio try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowSource = reader; _sqlDataReaderRowSource = _rowSource as SqlDataReader; _dbDataReaderRowSource = _rowSource as DbDataReader; - _dataTableSource = null; _rowSourceType = ValueSourceType.IDataReader; _isAsyncBulkCopy = true; resultTask = WriteRowSourceToServerAsync(reader.FieldCount, cancellationToken); // It returns Task since _isAsyncBulkCopy = true; @@ -1990,9 +1984,9 @@ public Task WriteToServerAsync(DataTable table, DataRowState rowState, Cancellat try { statistics = SqlStatistics.StartTimer(Statistics); + ResetWriteToServerGlobalVariables(); _rowStateToSkip = ((rowState == 0) || (rowState == DataRowState.Deleted)) ? DataRowState.Deleted : ~rowState | DataRowState.Deleted; _rowSource = table; - _sqlDataReaderRowSource = null; _dataTableSource = table; _rowSourceType = ValueSourceType.DataTable; _rowEnumerator = table.Rows.GetEnumerator(); @@ -3212,5 +3206,17 @@ private Task WriteToServerInternalAsync(CancellationToken ctoken) } return resultTask; } + + private void ResetWriteToServerGlobalVariables() + { + _dataTableSource = null; + _dbDataReaderRowSource = null; + _isAsyncBulkCopy = false; + _rowEnumerator = null; + _rowSource = null; + _rowSourceType = ValueSourceType.Unspecified; + _sqlDataReaderRowSource = null; + _sqlDataReaderRowSource = null; + } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 68e631cc5c..b2c942dd95 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -163,6 +163,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/WriteToServerTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/WriteToServerTest.cs new file mode 100644 index 0000000000..343a7bcfe2 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/WriteToServerTest.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Data; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class WriteToServerTest + { + private readonly string _connectionString = null; + private readonly string _tableName1 = DataTestUtility.GetUniqueName("Bulk1"); + private readonly string _tableName2 = DataTestUtility.GetUniqueName("Bulk2"); + + public WriteToServerTest() + { + _connectionString = (new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MultipleActiveResultSets = true }).ConnectionString; + } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + public async Task WriteToServerWithDbReaderFollowedByWriteToServerWithDataRowsShouldSucceed() + { + try + { + SetupTestTables(); + + DataRow[] dataRows = WriteToServerTest.CreateDataRows(); + Assert.Equal(4, dataRows.Length); // Verify the number of rows created + + DoBulkCopy(dataRows); + await DoBulkCopyAsync(dataRows); + } + finally + { + RemoveTestTables(); + } + } + + private void SetupTestTables() + { + // Create the source table and insert some data + using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString); + connection.Open(); + + DataTestUtility.DropTable(connection, _tableName1); + DataTestUtility.DropTable(connection, _tableName2); + + using SqlCommand command = connection.CreateCommand(); + + Helpers.TryExecute(command, $"create table {_tableName1} (Id int identity primary key, FirstName nvarchar(50), LastName nvarchar(50))"); + Helpers.TryExecute(command, $"create table {_tableName2} (Id int identity primary key, FirstName nvarchar(50), LastName nvarchar(50))"); + + Helpers.TryExecute(command, $"insert into {_tableName1} (Firstname, LastName) values ('John', 'Doe')"); + Helpers.TryExecute(command, $"insert into {_tableName1} (Firstname, LastName) values ('Johnny', 'Smith')"); + Helpers.TryExecute(command, $"insert into {_tableName1} (Firstname, LastName) values ('Jenny', 'Doe')"); + Helpers.TryExecute(command, $"insert into {_tableName1} (Firstname, LastName) values ('Jane', 'Smith')"); + } + + private static DataRow[] CreateDataRows() + { + DataTable table = new DataTable(); + table.Columns.Add("Id", typeof(int)); + table.Columns.Add("FirstName", typeof(string)); + table.Columns.Add("LastName", typeof(string)); + + table.Rows.Add(null, "Aaron", "Washington"); + table.Rows.Add(null, "Barry", "Mannilow"); + table.Rows.Add(null, "Charles", "Babage"); + table.Rows.Add(null, "Dean", "Snipes"); + + return table.Select(); + } + + private void RemoveTestTables() + { + // Simplify the using statement in a small block of code + using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString); + connection.Open(); + + DataTestUtility.DropTable(connection, _tableName1); + DataTestUtility.DropTable(connection, _tableName2); + } + + private void DoBulkCopy(DataRow[] dataRows) + { + using SqlConnection connection = new SqlConnection(_connectionString); + connection.Open(); + + using SqlCommand command = connection.CreateCommand(); + command.CommandText = $"select * from {_tableName1}"; + + using IDataReader reader = command.ExecuteReader(); + + using SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); + + bulkCopy.DestinationTableName = _tableName2; + + BulkCopy(bulkCopy, reader, dataRows); + } + + private async Task DoBulkCopyAsync(DataRow[] dataRows) + { + // Test should be run with MARS enabled + using SqlConnection connection = new SqlConnection(_connectionString); + await connection.OpenAsync(); + + using SqlCommand command = connection.CreateCommand(); + command.CommandText = $"select * from {_tableName1}"; + + using IDataReader reader = await command.ExecuteReaderAsync(); + + using SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); + + bulkCopy.DestinationTableName = _tableName2; + + await BulkCopyAsync(bulkCopy, reader, dataRows); + } + + private static void BulkCopy(SqlBulkCopy bulkCopy, IDataReader reader, DataRow[] dataRows) + { + bulkCopy.WriteToServer(reader); + Assert.Equal(dataRows.Length, bulkCopy.RowsCopied); // Verify the number of rows copied from the reader + bulkCopy.WriteToServer(dataRows); + Assert.Equal(dataRows.Length, bulkCopy.RowsCopied); // Verify the number of rows copied from the reader + } + + private static async Task BulkCopyAsync(SqlBulkCopy bulkCopy, IDataReader reader, DataRow[] dataRows) + { + await bulkCopy.WriteToServerAsync(reader); + Assert.Equal(dataRows.Length, bulkCopy.RowsCopied); // Verify the number of rows copied from the reader + await bulkCopy.WriteToServerAsync(dataRows); + Assert.Equal(dataRows.Length, bulkCopy.RowsCopied); // Verify the number of rows copied from the reader + } + } +} From 4e341dcba8e5fe7248f2e3870e355aa78af46a3f Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Wed, 6 Mar 2024 14:20:33 -0800 Subject: [PATCH 07/53] Update | updating version props for MDS v6.0.0 (#2382) --- tools/props/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/props/Versions.props b/tools/props/Versions.props index a41fd120d1..c16174881d 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -1,14 +1,14 @@ - 5.2.0 + 6.0.0 0 $(MdsVersionDefault).$(BuildNumber) $(AssemblyFileVersion) - 5.0.0.0 + 6.0.0.0 $(MdsVersionDefault)-dev $(NugetPackageVersion) From 769b982606bc97fee797d6c061973c28400aa362 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Wed, 6 Mar 2024 19:24:54 -0800 Subject: [PATCH 08/53] Adding CommonSourceRoot variable to Directory.Build.Props (#2392) --- src/Directory.Build.props | 1 + .../src/Microsoft.Data.SqlClient.csproj | 372 +++++++++--------- .../netfx/src/Microsoft.Data.SqlClient.csproj | 354 ++++++++--------- 3 files changed, 364 insertions(+), 363 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 0bd20392c2..cc502f3798 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -51,6 +51,7 @@ $(ManagedSourceCode)src\Resources\ $(ManagedSourceCode)add-ons\ $(RepoRoot)src\Microsoft.SqlServer.Server\ + $(RepoRoot)src\Microsoft.Data.SqlClient\src\ $(Artifacts)obj\ $(NetCoreSource)src\Common\src $(NetCoreSource)src\Common\tests 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 7a3a8e208f..eb15ff1e1a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -30,493 +30,493 @@ - + Microsoft\Data\Common\ActivityCorrelator.cs - + Microsoft\Data\Common\AdapterUtil.cs - + Microsoft\Data\Common\BitConverterCompatible.cs - + Microsoft\Data\Common\DbConnectionOptions.Common.cs - + Microsoft\Data\Common\DbConnectionPoolKey.cs - + Microsoft\Data\Common\DbConnectionStringCommon.cs - + Microsoft\Data\Common\MultipartIdentifier.cs - + Microsoft\Data\Common\NameValuePair.cs - + Microsoft\Data\DataException.cs - + Microsoft\Data\OperationAbortedException.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContext.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContextKey.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolGroup.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolGroupProviderInfo.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolOptions.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolProviderInfo.cs - + Microsoft\Data\ProviderBase\DbMetaDataFactory.cs - + Microsoft\Data\ProviderBase\FieldNameLookup.cs - + Microsoft\Data\ProviderBase\TimeoutTimer.cs - + Microsoft\Data\Sql\SqlDataSourceEnumerator.cs - + Microsoft\Data\Sql\SqlDataSourceEnumeratorManagedHelper.cs - + Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs - + Microsoft\Data\Sql\SqlNotificationRequest.cs - + Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationProvider.cs - + Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationTimeoutRetryHelper.cs - + Microsoft\Data\SqlClient\ApplicationIntent.cs - + Microsoft\Data\SqlClient\AssemblyRef.cs - + Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs - + Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs - + Microsoft\Data\SqlClient\DisposableTemporaryOnStack.cs - + Microsoft\Data\SqlClient\EnclaveDelegate.cs - + Microsoft\Data\SqlClient\EnclavePackage.cs - + Microsoft\Data\SqlClient\LocalAppContextSwitches.cs - + Microsoft\Data\SqlClient\OnChangedEventHandler.cs - + Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs - + Microsoft\Data\SqlClient\PoolBlockingPeriod.cs - + Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryingEventArgs.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryIntervalBaseEnumerator.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryLogic.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBase.cs - + Microsoft\Data\SqlClient\Reliability\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\SqlRetryIntervalEnumerators.cs - + Microsoft\Data\SqlClient\RowsCopiedEventArgs.cs - + Microsoft\Data\SqlClient\RowsCopiedEventHandler.cs - + Microsoft\Data\SqlClient\SqlSequentialTextReader.cs - + Microsoft\Data\SqlClient\Server\ExtendedClrTypeCode.cs - + Microsoft\Data\SqlClient\Server\ITypedGetters.cs - + Microsoft\Data\SqlClient\Server\ITypedGettersV3.cs - + Microsoft\Data\SqlClient\Server\ITypedSetters.cs - + Microsoft\Data\SqlClient\Server\ITypedSettersV3.cs - + Microsoft\Data\SqlClient\Server\MemoryRecordBuffer.cs - + Microsoft\Data\SqlClient\Server\MetadataUtilsSmi.cs - + Microsoft\Data\SqlClient\Server\SmiEventSink.cs - + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.Common.cs - + Microsoft\Data\SqlClient\Server\SmiGettersStream.cs - + Microsoft\Data\SqlClient\Server\SmiMetaData.cs - + Microsoft\Data\SqlClient\Server\SmiMetaDataProperty.cs - + Microsoft\Data\SqlClient\Server\SmiRecordBuffer.cs - + Microsoft\Data\SqlClient\Server\SmiSettersStream.cs - + Microsoft\Data\SqlClient\Server\SmiTypedGetterSetter.cs - + Microsoft\Data\SqlClient\Server\SmiXetterAccessMap.Common.cs - + Microsoft\Data\SqlClient\Server\SmiXetterTypeCode.cs - + Microsoft\Data\SqlClient\Server\SqlDataRecord.cs - + Microsoft\Data\SqlClient\Server\SqlDataRecord.netcore.cs - + Microsoft\Data\SqlClient\Server\SqlMetaData.cs - + Microsoft\Data\SqlClient\Server\SqlNormalizer.cs - + Microsoft\Data\SqlClient\Server\SqlRecordBuffer.cs - + Microsoft\Data\SqlClient\SqlTransaction.Common.cs - + Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs - + Microsoft\Data\SqlClient\SignatureVerificationCache.cs - + Microsoft\Data\SqlClient\SortOrder.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Algorithm.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256EncryptionKey.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Factory.cs - + Microsoft\Data\SqlClient\SqlAuthenticationParameters.cs - + Microsoft\Data\SqlClient\SqlAuthenticationProvider.cs - + Microsoft\Data\SqlClient\SqlBuffer.cs - + Microsoft\Data\SqlClient\SqlAuthenticationToken.cs - + Microsoft\Data\SqlClient\SqlBatch.cs - + Microsoft\Data\SqlClient\SqlBatchCommand.cs - + Microsoft\Data\SqlClient\SqlBatchCommandCollection.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnMapping.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnMappingCollection.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnOrderHint.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnOrderHintCollection.cs - + Microsoft\Data\SqlClient\SqlBulkCopyOptions.cs - + Microsoft\Data\SqlClient\SqlCachedBuffer.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithm.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithmFactory.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithmFactoryList.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionType.cs - + Microsoft\Data\SqlClient\SqlClientEventSource.cs - + Microsoft\Data\SqlClient\SqlClientLogger.cs - + Microsoft\Data\SqlClient\SqlClientMetaDataCollectionNames.cs - + Microsoft\Data\SqlClient\SqlClientSymmetricKey.cs - + Microsoft\Data\SqlClient\SqlCollation.cs - + Microsoft\Data\SqlClient\SqlColumnEncryptionKeyStoreProvider.cs - + Microsoft\Data\SqlClient\SqlCommandBuilder.cs - + Microsoft\Data\SqlClient\SqlCommandSet.cs - + Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs - + Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolKey.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolProviderInfo.cs - + Microsoft\Data\SqlClient\SqlConnectionString.cs - + Microsoft\Data\SqlClient\SqlConnectionStringBuilder.cs - + Microsoft\Data\SqlClient\SqlConnectionTimeoutErrorInternal.cs - + Microsoft\Data\SqlClient\SqlCredential.cs - + Microsoft\Data\SqlClient\SqlDataAdapter.cs - + Microsoft\Data\SqlClient\SqlDependency.cs - + Microsoft\Data\SqlClient\SqlDependencyListener.cs - + Microsoft\Data\SqlClient\SqlDependencyUtils.cs - + Microsoft\Data\SqlClient\SqlDependencyUtils.AppDomain.cs - + Microsoft\Data\SqlClient\SqlEnclaveSession.cs - + Microsoft\Data\SqlClient\SqlEnums.cs - + Microsoft\Data\SqlClient\SqlEnvChange.cs - + Microsoft\Data\SqlClient\SqlError.cs - + Microsoft\Data\SqlClient\SqlErrorCollection.cs - + Microsoft\Data\SqlClient\SqlException.cs - + Microsoft\Data\SqlClient\SQLFallbackDNSCache.cs - + Microsoft\Data\SqlClient\SqlInfoMessageEvent.cs - + Microsoft\Data\SqlClient\SqlInfoMessageEventHandler.cs - + Microsoft\Data\SqlClient\SqlInternalConnection.cs - + Microsoft\Data\SqlClient\SqlInternalTransaction.cs - + Microsoft\Data\SqlClient\SqlMetadataFactory.cs - + Microsoft\Data\SqlClient\SqlNotificationEventArgs.cs - + Microsoft\Data\SqlClient\SqlNotificationInfo.cs - + Microsoft\Data\SqlClient\SqlNotificationSource.cs - + Microsoft\Data\SqlClient\SqlNotificationType.cs - + Microsoft\Data\SqlClient\SqlObjectPool.cs - + Microsoft\Data\SqlClient\SqlParameter.cs - + Microsoft\Data\SqlClient\SqlParameterCollection.cs - + Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs - + Microsoft\Data\SqlClient\SqlReferenceCollection.cs - + Microsoft\Data\SqlClient\SqlRowUpdatedEvent.cs - + Microsoft\Data\SqlClient\SqlRowUpdatedEventHandler.cs - + Microsoft\Data\SqlClient\SqlRowUpdatingEvent.cs - + Microsoft\Data\SqlClient\SqlRowUpdatingEventHandler.cs - + Microsoft\Data\SqlClient\SqlSecurityUtility.cs - + Microsoft\Data\SqlClient\SqlSequentialStream.cs - + Microsoft\Data\SqlClient\Server\SqlSer.cs - + Microsoft\Data\SqlClient\SqlStatistics.cs - + Microsoft\Data\SqlClient\SqlSymmetricKeyCache.cs - + Microsoft\Data\SqlClient\SqlUdtInfo.cs - + Microsoft\Data\SqlClient\SqlUtil.cs - + Microsoft\Data\SqlClient\TdsEnums.cs - + Microsoft\Data\SqlClient\TdsParameterSetter.cs - + Microsoft\Data\SqlClient\TdsParserStateObject.cs - + Microsoft\Data\SqlClient\TdsParserStaticMethods.cs - + Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs - + Microsoft\Data\SqlClient\TdsParserSessionPool.cs - + Microsoft\Data\SqlClient\TdsValueSetter.cs - + Microsoft\Data\SQLTypes\SQLResource.cs - + Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs - + Microsoft\Data\SqlClient\SqlStream.cs - + Resources\ResCategoryAttribute.cs - + Resources\ResDescriptionAttribute.cs - + Common\System\Diagnostics\CodeAnalysis.cs @@ -524,10 +524,10 @@ - + Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs - + Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs @@ -539,31 +539,31 @@ - + Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs - + Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs - + Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs - + Microsoft\Data\SqlClient\EnclaveProviderBase.cs - + Microsoft\Data\SqlClient\EnclaveSessionCache.cs - + Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs - + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs - + Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs - + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs @@ -576,30 +576,30 @@ - + Microsoft\Data\SqlClient\SqlDependencyUtils.AssemblyLoadContext.cs - + Resources\StringsHelper.cs - + Resources\Strings.Designer.cs True True Strings.resx - + Resources\Strings.resx Microsoft.Data.SqlClient.Resources.Strings.resources ResXFileCodeGenerator Strings.Designer.cs System - + Resources\%(RecursiveDir)%(Filename)%(Extension) @@ -675,25 +675,25 @@ - + Microsoft\Data\Common\AdapterUtil.Windows.cs - + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs - + Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs - + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs - + Microsoft\Data\Common\AdapterUtil.Unix.cs @@ -975,7 +975,7 @@ - + Microsoft\Data\SqlClient\SqlBatchCommand.Net8OrGreater.cs @@ -1018,5 +1018,5 @@ - + 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 97feee8bef..0a0757731b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -94,520 +94,520 @@ - + Microsoft\Data\Common\ActivityCorrelator.cs - + Microsoft\Data\Common\AdapterUtil.cs - + Microsoft\Data\Common\AdapterUtil.Windows.cs - + Microsoft\Data\Common\BitConverterCompatible.cs - + Microsoft\Data\Common\DbConnectionStringCommon.cs - + Microsoft\Data\Common\DbConnectionOptions.Common.cs - + Microsoft\Data\Common\DbConnectionPoolKey.cs - + Microsoft\Data\Common\MultipartIdentifier.cs - + Microsoft\Data\Common\NameValuePair.cs - + Microsoft\Data\DataException.cs - + Microsoft\Data\OperationAbortedException.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContext.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContextKey.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolGroup.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolGroupProviderInfo.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolOptions.cs - + Microsoft\Data\ProviderBase\DbConnectionPoolProviderInfo.cs - + Microsoft\Data\ProviderBase\DbMetaDataFactory.cs - + Microsoft\Data\ProviderBase\FieldNameLookup.cs - + Microsoft\Data\ProviderBase\TimeoutTimer.cs - + Microsoft\Data\Sql\SqlDataSourceEnumerator.cs - + Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs - + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs - + Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs - + Microsoft\Data\Sql\SqlNotificationRequest.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\AzureAttestationBasedEnclaveProvider.cs - + Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs - + Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs - + Microsoft\Data\SqlClient\DisposableTemporaryOnStack.cs - + Microsoft\Data\SqlClient\EnclaveDelegate.cs - + Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs - + Microsoft\Data\SqlClient\EnclavePackage.cs - + Microsoft\Data\SqlClient\EnclaveProviderBase.cs - + Microsoft\Data\SqlClient\EnclaveSessionCache.cs - + Microsoft\Data\SqlClient\LocalAppContextSwitches.cs - + Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs - + Microsoft\Data\SqlClient\OnChangedEventHandler.cs - + Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs - + Microsoft\Data\SqlClient\PoolBlockingPeriod.cs - + Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryingEventArgs.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryIntervalBaseEnumerator.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryLogic.cs - + Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBase.cs - + Microsoft\Data\SqlClient\Reliability\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\SqlRetryIntervalEnumerators.cs - + Microsoft\Data\SqlClient\RowsCopiedEventArgs.cs - + Microsoft\Data\SqlClient\RowsCopiedEventHandler.cs - + Microsoft\Data\SqlClient\Server\ExtendedClrTypeCode.cs - + Microsoft\Data\SqlClient\Server\ITypedGetters.cs - + Microsoft\Data\SqlClient\Server\ITypedGettersV3.cs - + Microsoft\Data\SqlClient\Server\ITypedSetters.cs - + Microsoft\Data\SqlClient\Server\ITypedSettersV3.cs - + Microsoft\Data\SqlClient\Server\MemoryRecordBuffer.cs - + Microsoft\Data\SqlClient\Server\MetadataUtilsSmi.cs - + Microsoft\Data\SqlClient\Server\SmiEventSink.cs - + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.Common.cs - + Microsoft\Data\SqlClient\Server\SmiEventSink_Default.netfx.cs - + Microsoft\Data\SqlClient\Server\SmiGettersStream.cs - + Microsoft\Data\SqlClient\Server\SmiMetaData.cs - + Microsoft\Data\SqlClient\Server\SmiMetaDataProperty.cs - + Microsoft\Data\SqlClient\Server\SmiRecordBuffer.cs - + Microsoft\Data\SqlClient\Server\SmiSettersStream.cs - + Microsoft\Data\SqlClient\Server\SmiTypedGetterSetter.cs - + Microsoft\Data\SqlClient\Server\SmiXetterAccess.Common.cs - + Microsoft\Data\SqlClient\Server\SmiXetterTypeCode.cs - + Microsoft\Data\SqlClient\Server\SqlDataRecord.cs - + Microsoft\Data\SqlClient\Server\SqlDataRecord.netfx.cs - + Microsoft\Data\SqlClient\Server\SqlMetaData.cs - + Microsoft\Data\SqlClient\Server\SqlNormalizer.cs - + Microsoft\Data\SqlClient\Server\SqlRecordBuffer.cs - + Microsoft\Data\SqlClient\SqlTransaction.Common.cs - + Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs - + Microsoft\Data\SqlClient\Server\ValueUtilsSmi.netfx.cs - + Microsoft\Data\SqlClient\Server\SqlSer.cs - + Microsoft\Data\SqlClient\SignatureVerificationCache.cs - + Microsoft\Data\SqlClient\SortOrder.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Algorithm.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256EncryptionKey.cs - + Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Factory.cs - + Microsoft\Data\SqlClient\SqlAuthenticationParameters.cs - + Microsoft\Data\SqlClient\SqlAuthenticationProvider.cs - + Microsoft\Data\SqlClient\SqlBuffer.cs - + Microsoft\Data\SqlClient\SqlAuthenticationToken.cs - + Microsoft\Data\SqlClient\SqlBatchCommand.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnMapping.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnMappingCollection.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnOrderHint.cs - + Microsoft\Data\SqlClient\SqlBulkCopyColumnOrderHintCollection.cs - + Microsoft\Data\SqlClient\SqlBulkCopyOptions.cs - + Microsoft\Data\SqlClient\SqlCachedBuffer.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithm.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithmFactory.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionAlgorithmFactoryList.cs - + Microsoft\Data\SqlClient\SqlClientEncryptionType.cs - + Microsoft\Data\SqlClient\SqlClientEventSource.cs - + Microsoft\Data\SqlClient\SqlClientLogger.cs - + Microsoft\Data\SqlClient\SqlClientMetaDataCollectionNames.cs - + Microsoft\Data\SqlClient\SqlClientSymmetricKey.cs - + Microsoft\Data\SqlClient\SqlCollation.cs - + Microsoft\Data\SqlClient\SqlColumnEncryptionKeyStoreProvider.cs - + Microsoft\Data\SqlClient\SqlCommandBuilder.cs - + Microsoft\Data\SqlClient\SqlCommandSet.cs - + Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs - + Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolKey.cs - + Microsoft\Data\SqlClient\SqlConnectionPoolProviderInfo.cs - + Microsoft\Data\SqlClient\SqlConnectionString.cs - + Microsoft\Data\SqlClient\SqlConnectionStringBuilder.cs - + Microsoft\Data\SqlClient\SqlConnectionTimeoutErrorInternal.cs - + Microsoft\Data\SqlClient\SqlCredential.cs - + Microsoft\Data\SqlClient\SqlDataAdapter.cs - + Microsoft\Data\SqlClient\SqlDependency.cs - + Microsoft\Data\SqlClient\SqlDependencyListener.cs - + Microsoft\Data\SqlClient\SqlDependencyUtils.cs - + Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs - + Microsoft\Data\SqlClient\SqlEnclaveSession.cs - + Microsoft\Data\SqlClient\SqlEnums.cs - + Microsoft\Data\SqlClient\SqlEnvChange.cs - + Microsoft\Data\SqlClient\SqlError.cs - + Microsoft\Data\SqlClient\SqlErrorCollection.cs - + Microsoft\Data\SqlClient\SqlException.cs - + Microsoft\Data\SqlClient\SQLFallbackDNSCache.cs - + Microsoft\Data\SqlClient\SqlInfoMessageEvent.cs - + Microsoft\Data\SqlClient\SqlInfoMessageEventHandler.cs - + Microsoft\Data\SqlClient\SqlInternalConnection.cs - + Microsoft\Data\SqlClient\SqlInternalTransaction.cs - + Microsoft\Data\SqlClient\SqlMetaDataFactory.cs - + Microsoft\Data\SqlClient\SqlNotificationEventArgs.cs - + Microsoft\Data\SqlClient\SqlNotificationInfo.cs - + Microsoft\Data\SqlClient\SqlNotificationSource.cs - + Microsoft\Data\SqlClient\SqlNotificationType.cs - + Microsoft\Data\SqlClient\SqlParameterCollection.cs - + Microsoft\Data\SqlClient\SqlParameter.cs - + Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs - + Microsoft\Data\SqlClient\SqlReferenceCollection.cs - + Microsoft\Data\SqlClient\SqlRowUpdatedEvent.cs - + Microsoft\Data\SqlClient\SqlRowUpdatedEventHandler.cs - + Microsoft\Data\SqlClient\SqlRowUpdatingEvent.cs - + Microsoft\Data\SqlClient\SqlRowUpdatingEventHandler.cs - + Microsoft\Data\SqlClient\SqlSecurityUtility.cs - + Microsoft\Data\SqlClient\SqlSequentialStream.cs - + Microsoft\Data\SqlClient\SqlStream.cs - + Microsoft\Data\SqlClient\SqlStatistics.cs - + Microsoft\Data\SqlClient\SqlSequentialTextReader.cs - + Microsoft\Data\SqlClient\SqlSymmetricKeyCache.cs - + Microsoft\Data\SqlClient\SqlUdtInfo.cs - + Microsoft\Data\SqlClient\SqlUtil.cs - + Microsoft\Data\SqlClient\TdsEnums.cs - + Microsoft\Data\SqlClient\TdsParameterSetter.cs - + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs - + Microsoft\Data\SqlClient\TdsParserStateObject.cs - + Microsoft\Data\SqlClient\TdsParserStaticMethods.cs - + Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs - + Microsoft\Data\SqlClient\TdsParserSessionPool.cs - + Microsoft\Data\SqlClient\TdsValueSetter.cs - + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs - + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs - + Microsoft\Data\SqlTypes\SQLResource.cs - + Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs - + Resources\ResCategoryAttribute.cs - + Resources\ResDescriptionAttribute.cs @@ -686,23 +686,23 @@ - + Resources\StringsHelper.cs - + Resources\Strings.Designer.cs True True Strings.resx - + Resources\Strings.resx Microsoft.Data.SqlClient.Resources.Strings.resources System ResXFileCodeGenerator Strings.Designer.cs - + Resources\%(RecursiveDir)%(Filename)%(Extension) @@ -747,7 +747,7 @@ - + From 9056f13a18b82dc2698ad04da905c16ed5d4ed3f Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Tue, 12 Mar 2024 13:31:06 -0500 Subject: [PATCH 09/53] Downgrade Xunit, Improve exception handling for Diagnonstic Tests (#2379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Description**: While doing some investigation into improving the diagnostic tracing tests, I noticed that test failures are logged very non-descriptly by remote executor. To resolve this issue, we have to downgrade xunit to v2.4.2. Here's the rationale for this change: * RemoteExecutor throws `XunitException`s from xunit.assert nuget and uses the `(string, string)` constructor * The `(string, string)` constructor was removed in >=2.5 of xunit.assert   * RemoteExecutor was fixed to inherit from Exception in newer versions, but for us to take this requires upgrading to .net 7 or 8 (which I imagine is a much larger lift) * In order to downgrade xunit.assert, we need to downgrade xunit * In order to downgrade xunit, we also need to downgrade Microsoft.DotNet.XunitExtensions * Without this change, exceptions from RemoteExecutor will fail to construct, masking all errors with "MethodNotFound" Although normally downgrading is bad for security reasons, I believe this to be a safe change since it only affects tests. This PR also makes a bunch of improvements to the `DiagnosticTest`s: * Remove conditional facts when test TDS server is used * Remove try/catch with empty catch block, replace with assert.throws * Ensure that connections are opened before trying test conditions * Document scenarios where test TDS server doesn't obey actual behavior, or where test TDS server cannot be used * Formatting improvements **Testing**: * All tests (that are expected to pass) continue to pass * In a synthetic failure of diagnostic tests, here's the before and after of the error messages: * Before: ``` System.MissingMethodException: Method not found: 'Void Xunit.Sdk.XunitException..ctor(System.String, System.String)'. System.MissingMethodException Method not found: 'Void Xunit.Sdk.XunitException..ctor(System.String, System.String)'. ``` * After: ``` Microsoft.DotNet.RemoteExecutor.RemoteExecutionException: Remote process failed with an unhandled exception. Microsoft.DotNet.RemoteExecutor.RemoteExecutionException Remote process failed with an unhandled exception. Child exception: Xunit.Sdk.FailException: Assert.Fail(): Foo at Microsoft.Data.SqlClient.ManualTesting.Tests.DiagnosticTest.<>c.b__1_0() in C:\Projects\benrr101\sqlclient\src\Microsoft.Data.SqlClient\tests\ManualTests\TracingTests\DiagnosticTest.cs:line 34 ``` ## Commits * Downgrade xunit for better error logging from remote executor * All but one test improved ... ? * Understanding why test was failing * Add arcade and xunit nugets to .net8+ special versions * Remove xunitextensions version boost (which I spelled wrong anyhow) --- .../TracingTests/DiagnosticTest.cs | 243 ++++++++---------- tools/props/Versions.props | 4 +- tools/props/VersionsNet8OrLater.props | 2 + 3 files changed, 115 insertions(+), 134 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs index 6aff5c727f..5d5c9d5ec7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs @@ -25,9 +25,8 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests public class DiagnosticTest { private const string BadConnectionString = "data source = bad; initial catalog = bad; integrated security = true; connection timeout = 1;"; - private static readonly string s_tcpConnStr = DataTestUtility.TCPConnectionString ?? string.Empty; - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteScalarTest() { RemoteExecutor.Invoke(() => @@ -41,14 +40,14 @@ public void ExecuteScalarTest() cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();"; conn.Open(); - var output = cmd.ExecuteScalar(); + cmd.ExecuteScalar(); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteScalarErrorTest() { RemoteExecutor.Invoke(() => @@ -59,19 +58,17 @@ public void ExecuteScalarErrorTest() using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.CommandText = "SELECT 1 / 0;"; conn.Open(); - try - { var output = cmd.ExecuteScalar(); } - catch { } + Assert.Throws(() => cmd.ExecuteScalar()); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteNonQueryTest() { RemoteExecutor.Invoke(() => @@ -85,14 +82,14 @@ public void ExecuteNonQueryTest() cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();"; conn.Open(); - var output = cmd.ExecuteNonQuery(); + cmd.ExecuteNonQuery(); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteNonQueryErrorTest() { RemoteExecutor.Invoke(() => @@ -100,29 +97,23 @@ public void ExecuteNonQueryErrorTest() CollectStatisticsDiagnostics(connectionString => { using (SqlConnection conn = new SqlConnection(connectionString)) + using (SqlCommand cmd = new SqlCommand()) { - using (SqlCommand cmd = new SqlCommand()) - { - cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.Connection = conn; + cmd.CommandText = "SELECT 1 / 0;"; - // Limiting the command timeout to 3 seconds. This should be lower than the Process timeout. - cmd.CommandTimeout = 3; - conn.Open(); - Console.WriteLine("SqlClient.DiagnosticTest.ExecuteNonQueryErrorTest Connection Open Successful"); + // Limiting the command timeout to 3 seconds. This should be lower than the Process timeout. + cmd.CommandTimeout = 3; + conn.Open(); - SqlException ex = Assert.Throws(() => cmd.ExecuteNonQuery()); - Console.WriteLine("SqlClient.DiagnosticTest.ExecuteNonQueryErrorTest Command Executed"); - } - Console.WriteLine("SqlClient.DiagnosticTest.ExecuteNonQueryErrorTest Command Disposed"); + Assert.Throws(() => cmd.ExecuteNonQuery()); } - Console.WriteLine("SqlClient.DiagnosticTest.ExecuteNonQueryErrorTest Connection Disposed"); }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteReaderTest() { RemoteExecutor.Invoke(() => @@ -138,14 +129,16 @@ public void ExecuteReaderTest() conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) - { } + { + // Read until end. + } } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteReaderErrorTest() { RemoteExecutor.Invoke(() => @@ -156,22 +149,18 @@ public void ExecuteReaderErrorTest() using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.CommandText = "SELECT 1 / 0;"; - try - { - SqlDataReader reader = cmd.ExecuteReader(); - while (reader.Read()) - { } - } - catch { } + conn.Open(); + // @TODO: TestTdsServer should not throw on ExecuteReader, it should throw on reader.Read + Assert.Throws(() => cmd.ExecuteReader()); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteReaderWithCommandBehaviorTest() { RemoteExecutor.Invoke(() => @@ -187,7 +176,9 @@ public void ExecuteReaderWithCommandBehaviorTest() conn.Open(); SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default); while (reader.Read()) - { } + { + // Read to end + } } }); return RemoteExecutor.SuccessExitCode; @@ -198,24 +189,27 @@ public void ExecuteReaderWithCommandBehaviorTest() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public void ExecuteXmlReaderTest() { - RemoteExecutor.Invoke(cs => + RemoteExecutor.Invoke(() => { CollectStatisticsDiagnostics(_ => { - using (SqlConnection conn = new SqlConnection(cs)) + // @TODO: Test TDS server doesn't support ExecuteXmlReader, so connect to real server as workaround + using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select top 10 * from sys.objects for xml auto, xmldata;"; + cmd.CommandText = "SELECT TOP 10 * FROM sys.objects FOR xml auto, xmldata;"; conn.Open(); XmlReader reader = cmd.ExecuteXmlReader(); while (reader.Read()) - { } + { + // Read to end + } } }); return RemoteExecutor.SuccessExitCode; - }, s_tcpConnStr).Dispose(); + }).Dispose(); } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] @@ -229,119 +223,110 @@ public void ExecuteXmlReaderErrorTest() using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select *, baddata = 1 / 0 from sys.objects for xml auto, xmldata;"; + cmd.CommandText = "SELECT *, baddata = 1 / 0 FROM sys.objects FOR xml auto, xmldata;"; - try - { - XmlReader reader = cmd.ExecuteXmlReader(); - while (reader.Read()) - { } - } - catch { } + conn.Open(); + // @TODO: TestTdsServer should not throw on ExecuteXmlReader, should throw on reader.Read + Assert.Throws(() => cmd.ExecuteXmlReader()); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteScalarAsyncTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();"; conn.Open(); - var output = await cmd.ExecuteScalarAsync(); + await cmd.ExecuteScalarAsync(); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteScalarAsyncErrorTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.CommandText = "SELECT 1 / 0;"; conn.Open(); - - try - { var output = await cmd.ExecuteScalarAsync(); } - catch { } + await Assert.ThrowsAsync(() => cmd.ExecuteScalarAsync()); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteNonQueryAsyncTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();"; conn.Open(); - var output = await cmd.ExecuteNonQueryAsync(); + await cmd.ExecuteNonQueryAsync(); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteNonQueryAsyncErrorTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.CommandText = "SELECT 1 / 0;"; conn.Open(); - try - { var output = await cmd.ExecuteNonQueryAsync(); } - catch { } + await Assert.ThrowsAsync(() => cmd.ExecuteNonQueryAsync()); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteReaderAsyncTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();"; @@ -349,35 +334,33 @@ public void ExecuteReaderAsyncTest() conn.Open(); SqlDataReader reader = await cmd.ExecuteReaderAsync(); while (reader.Read()) - { } + { + // Read to end + } } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteReaderAsyncErrorTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection conn = new SqlConnection(connectionString)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(connectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select 1 / 0;"; + cmd.CommandText = "SELECT 1 / 0;"; - try - { - SqlDataReader reader = await cmd.ExecuteReaderAsync(); - while (reader.Read()) - { } - } - catch { } + conn.Open(); + // @TODO: TestTdsServer should not throw on ExecuteReader, should throw on reader.Read + await Assert.ThrowsAsync(() => cmd.ExecuteReaderAsync()); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } @@ -386,53 +369,57 @@ public void ExecuteReaderAsyncErrorTest() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public void ExecuteXmlReaderAsyncTest() { - RemoteExecutor.Invoke(cs => + // @TODO: TestTdsServer does not handle xml reader, so connect to a real server as a workaround + RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async _ => { - using (SqlConnection conn = new SqlConnection(cs)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "select TOP 10 * from sys.objects for xml auto, xmldata;"; + cmd.CommandText = "SELECT TOP 10 * FROM sys.objects FOR xml auto, xmldata;"; conn.Open(); XmlReader reader = await cmd.ExecuteXmlReaderAsync(); while (reader.Read()) - { } + { + // Read to end + } } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; - }, s_tcpConnStr).Dispose(); + }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ExecuteXmlReaderAsyncErrorTest() { - RemoteExecutor.Invoke(cs => + // @TODO: TestTdsServer does not handle xml reader, so connect to a real server as a workaround + RemoteExecutor.Invoke(() => { + CollectStatisticsDiagnosticsAsync(async _ => { - using (SqlConnection conn = new SqlConnection(cs)) - using (SqlCommand cmd = new SqlCommand()) + await using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + await using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "select *, baddata = 1 / 0 from sys.objects for xml auto, xmldata;"; - try - { - XmlReader reader = await cmd.ExecuteXmlReaderAsync(); - while (reader.Read()) - { } - } - catch { } + // @TODO: Since this test uses a real database connection, the exception is + // thrown during reader.Read. (ie, TestTdsServer does not obey proper + // exception behavior) + await conn.OpenAsync(); + XmlReader reader = await cmd.ExecuteXmlReaderAsync(); + await Assert.ThrowsAsync(() => reader.ReadAsync()); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; - }, s_tcpConnStr).Dispose(); + }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ConnectionOpenTest() { RemoteExecutor.Invoke(() => @@ -442,17 +429,13 @@ public void ConnectionOpenTest() using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { sqlConnection.Open(); - Console.WriteLine("SqlClient.DiagnosticsTest.ConnectionOpenTest:: Connection Opened "); } - Console.WriteLine("SqlClient.DiagnosticsTest.ConnectionOpenTest:: Connection Should Be Disposed"); }, true); - - Console.WriteLine("SqlClient.DiagnosticsTest.ConnectionOpenTest:: Done with Diagnostics collection"); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ConnectionOpenErrorTest() { RemoteExecutor.Invoke(() => @@ -461,45 +444,41 @@ public void ConnectionOpenErrorTest() { using (SqlConnection sqlConnection = new SqlConnection(BadConnectionString)) { - try - { sqlConnection.Open(); } - catch { } + Assert.Throws(() => sqlConnection.Open()); } }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ConnectionOpenAsyncTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async connectionString => { - using (SqlConnection sqlConnection = new SqlConnection(connectionString)) + await using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { await sqlConnection.OpenAsync(); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [Fact] public void ConnectionOpenAsyncErrorTest() { RemoteExecutor.Invoke(() => { CollectStatisticsDiagnosticsAsync(async _ => { - using (SqlConnection sqlConnection = new SqlConnection(BadConnectionString)) + await using (SqlConnection sqlConnection = new SqlConnection(BadConnectionString)) { - try - { await sqlConnection.OpenAsync(); } - catch { } + await Assert.ThrowsAsync(() => sqlConnection.OpenAsync()); } - }).GetAwaiter().GetResult(); + }).Wait(); return RemoteExecutor.SuccessExitCode; }).Dispose(); } diff --git a/tools/props/Versions.props b/tools/props/Versions.props index c16174881d..9c58ec3889 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -61,13 +61,13 @@ - 9.0.0-beta.23613.3 + 8.0.0-beta.24123.1 3.1.6 17.8.0 13.0.1 4.3.0 6.0.1 - 2.6.3 + 2.4.2 2.5.5 1.0.3 7.0.0-beta.22316.1 diff --git a/tools/props/VersionsNet8OrLater.props b/tools/props/VersionsNet8OrLater.props index a5e1f52bb4..2c203223bd 100644 --- a/tools/props/VersionsNet8OrLater.props +++ b/tools/props/VersionsNet8OrLater.props @@ -5,5 +5,7 @@ 8.0.0 8.0.0 8.0.0 + 9.0.0-beta.24157.1 + 2.6.3 From 4e23bf94c566e04a2fa7fb930af05f3d76fb30c8 Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:44:40 -0700 Subject: [PATCH 10/53] Fix | The SqlConnection.FireInfoMessageEventOnUserErrors when set to true throws an exception (#2399) --- .../Microsoft/Data/SqlClient/SqlCommand.cs | 2 +- .../Microsoft/Data/SqlClient/SqlCommand.cs | 2 +- .../SQL/ConnectivityTests/ConnectivityTest.cs | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index 39dbb917e0..d01c686d04 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -6776,7 +6776,7 @@ internal SqlBatchCommand GetCurrentBatchCommand() } else { - return _rpcArrayOf1[0].batchCommand; + return _rpcArrayOf1?[0].batchCommand; } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs index 0ac6ed775e..94cd927c1d 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -7487,7 +7487,7 @@ internal SqlBatchCommand GetCurrentBatchCommand() } else { - return _rpcArrayOf1[0].batchCommand; + return _rpcArrayOf1?[0].batchCommand; } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs index 60260fe79f..bf26f84018 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs @@ -474,5 +474,29 @@ public static void SqlPasswordConnectionTest() using SqlConnection sqlConnection = new(b.ConnectionString); sqlConnection.Open(); } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] + public static void ConnectionFireInfoMessageEventOnUserErrorsShouldSucceed() + { + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + string command = "print"; + string commandParam = "OK"; + + connection.FireInfoMessageEventOnUserErrors = true; + + connection.InfoMessage += (sender, args) => + { + Assert.Equal(commandParam, args.Message); + }; + + connection.Open(); + + using SqlCommand cmd = connection.CreateCommand(); + cmd.CommandType = System.Data.CommandType.Text; + cmd.CommandText = $"{command} '{commandParam}'"; + cmd.ExecuteNonQuery(); + } + } } } From bdfa5d8dbe9acfc01d034bc1fe8b73ce8fe28109 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Mon, 25 Mar 2024 11:56:49 -0700 Subject: [PATCH 11/53] Regression | Revert PR #2281 SNIProxy code change (#2395) --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 6 +++--- .../ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index d39f382bd6..3df369a2f6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -653,10 +653,10 @@ private bool InferConnectionDetails() Port = port; } - // Instance Name Handling. - if (backSlashIndex > -1) + // Instance Name Handling. Only if we found a '\' and we did not find a port in the Data Source + else if (backSlashIndex > -1) { - // This means that there is a part separated by '\' + // This means that there will not be any part separated by comma. InstanceName = tokensByCommaAndSlash[1].Trim(); if (string.IsNullOrWhiteSpace(InstanceName)) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index 205b9d33f1..aa72bb6f5b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -87,6 +87,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove } #if NETCOREAPP + [ActiveIssue("27824")] // When specifying instance name and port number, this method call always returns false [ConditionalFact(nameof(IsSPNPortNumberTestForTCP))] public static void PortNumberInSPNTestForTCP() { From 30cd171e0129ccf80bd95add6191687e987bbd4d Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Mon, 25 Mar 2024 11:57:36 -0700 Subject: [PATCH 12/53] Change | Convert Netfx to SDK style (#2413) --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 10 +++---- .../Microsoft.Data.SqlClient.Tests.csproj | 7 ++++- ....Data.SqlClient.ManualTesting.Tests.csproj | 5 +++- tools/specs/Microsoft.Data.SqlClient.nuspec | 30 +++++++++---------- 4 files changed, 29 insertions(+), 23 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 0a0757731b..2bcc979352 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -1,10 +1,8 @@ - - - + {407890AC-9876-4FEF-A6F1-F36A876BAADE} Microsoft.Data.SqlClient - v4.6.2 + net462 true Microsoft.Data.SqlClient AnyCPU @@ -17,6 +15,7 @@ True + false $(DefineConstants);NETFRAMEWORK; @@ -24,7 +23,7 @@ full - $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(GeneratedSourceFileName)')) + $([System.IO.Path]::Combine('$(IntermediateOutputPath)\$(TargetFramework)','$(GeneratedSourceFileName)')) @@ -746,7 +745,6 @@ $(SystemBuffersVersion) - diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 7724f4c58e..4c011a2d55 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -122,7 +122,12 @@ - + + PreserveNewest + %(Filename)%(Extension) + + + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index b2c942dd95..676f8126c6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -347,7 +347,10 @@ - + + PreserveNewest + %(Filename)%(Extension) + diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index 57fff91307..f44a2a462d 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -143,21 +143,21 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - - - - + + + + + + + + + + - - - + + + @@ -230,8 +230,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + From 0d455647cdad87d32beea3173eef421bd1a88264 Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Thu, 28 Mar 2024 16:49:55 +0000 Subject: [PATCH 13/53] Merged PR 4422: Pipeline | Initiate YAML pipelines - A successful sample run can be found with the non-official template [here](https://dev.azure.com/SqlClientDrivers/ADO.Net/_build/results?buildId=82875&view=results) without SDL tools. - There are a few errors reported by code analyzer that need to be addressed as well. - Due to the known issue with APIScan and Onebranch, it's temporarily deactivated. Related work items: #28134 --- .config/CredScanSuppressions.json | 25 ++ .config/PolicheckExclusions.xml | 5 + .config/tsaoptions.json | 11 +- .../jobs/build-signed-package-job.yml | 80 +++++ .../jobs/run-tests-package-reference-job.yml | 59 ++++ .../jobs/verify-signed-package-job.yml | 299 ++++++++++++++++++ ...ld-all-configurations-signed-dlls-step.yml | 26 ++ .../build-and-run-tests-netcore-step.yml | 80 +++++ .../steps/build-and-run-tests-netfx-step.yml | 79 +++++ .../templates/steps/code-analyze-step.yml | 31 ++ .../steps/esrp-code-signing-step.yml | 106 +++++++ .../steps/generate-nuget-package-step.yml | 40 +++ .../common/templates/steps/pre-build-step.yml | 20 ++ .../templates/steps/prepare-test-db-step.yml | 26 ++ .../templates/steps/publish-symbols-step.yml | 29 ++ .../steps/update-config-file-step.yml | 35 ++ .../update-nuget-config-local-feed-step.yml | 78 +++++ .../dotnet-sqlclient-signing-pipeline.yml | 98 ++++++ eng/pipelines/libraries/build-variables.yml | 26 ++ .../libraries/validation-variables.yml | 32 ++ eng/pipelines/libraries/variables.yml | 17 + 21 files changed, 1198 insertions(+), 4 deletions(-) create mode 100644 .config/CredScanSuppressions.json create mode 100644 .config/PolicheckExclusions.xml create mode 100644 eng/pipelines/common/templates/jobs/build-signed-package-job.yml create mode 100644 eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml create mode 100644 eng/pipelines/common/templates/jobs/verify-signed-package-job.yml create mode 100644 eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml create mode 100644 eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml create mode 100644 eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml create mode 100644 eng/pipelines/common/templates/steps/code-analyze-step.yml create mode 100644 eng/pipelines/common/templates/steps/esrp-code-signing-step.yml create mode 100644 eng/pipelines/common/templates/steps/generate-nuget-package-step.yml create mode 100644 eng/pipelines/common/templates/steps/pre-build-step.yml create mode 100644 eng/pipelines/common/templates/steps/prepare-test-db-step.yml create mode 100644 eng/pipelines/common/templates/steps/publish-symbols-step.yml create mode 100644 eng/pipelines/common/templates/steps/update-config-file-step.yml create mode 100644 eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml create mode 100644 eng/pipelines/dotnet-sqlclient-signing-pipeline.yml create mode 100644 eng/pipelines/libraries/build-variables.yml create mode 100644 eng/pipelines/libraries/validation-variables.yml create mode 100644 eng/pipelines/libraries/variables.yml diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json new file mode 100644 index 0000000000..ffc7e87789 --- /dev/null +++ b/.config/CredScanSuppressions.json @@ -0,0 +1,25 @@ +{ + "tool": "Credential Scanner", + "suppressions": [ + { + "file": "src/Microsoft.Data.SqlClient/tests/Docker/DockerLinuxTest/Program.cs", + "justification": "Test projects should be skipped" + }, + { + "file": "src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TDSServerArguments.cs", + "justification": "Test projects should be skipped" + }, + { + "file": "src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TdsServerCertificate.pfx", + "justification": "Test projects should be skipped" + }, + { + "file": "src/docker-compose.yml", + "justification": "Docker test project should be excluded" + }, + { + "file": "doc/samples/SqlConnectionStringBuilder.cs", + "justification": "Documentation could include sample data and can be ignored" + } + ] +} diff --git a/.config/PolicheckExclusions.xml b/.config/PolicheckExclusions.xml new file mode 100644 index 0000000000..d8c47d335d --- /dev/null +++ b/.config/PolicheckExclusions.xml @@ -0,0 +1,5 @@ + + SRC/MICROSOFT.DATA.SQLCLIENT/TESTS + .YML|.MD|.SQL + NOTICE.TXT + \ No newline at end of file diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json index a9be6f5aae..c9e3a2cfb6 100644 --- a/.config/tsaoptions.json +++ b/.config/tsaoptions.json @@ -1,11 +1,14 @@ { "instanceUrl": "https://sqlclientdrivers.visualstudio.com/", - "projectName": "ADO.NET", - "areaPath": "ADO.NET", - "iterationPath": "ADO.NET", + "projectName": "ADO.Net", + "areaPath": "ADO.Net", + "iterationPath": "ADO.Net\\TSA\\SqlClient", "notificationAliases": [ "SqlClient@microsoft.com" ], "repositoryName": "SqlClient", "codebaseName": "SqlClient", "allTools": true, - "template": "MSDATA_RevolutionR" + "template": "MSDATA_RevolutionR", + "language": "csharp", + "includePathPatterns": "src/Microsoft.Data.SqlClient/*, src/Microsoft.SqlServer.Server/*, tools/*", + "excludePathPatterns": "src/Microsoft.Data.SqlClient/tests/*" } diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml new file mode 100644 index 0000000000..3244a9a0dd --- /dev/null +++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml @@ -0,0 +1,80 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: symbolsFolder + type: string + default: symbols + - name: softwareFolder + type: string + default: software + +jobs: +- job: build_signed_package + pool: + type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs + + variables: + - template: ../../../libraries/variables.yml@self + + steps: + - script: SET + displayName: 'Print Environment Variables' + - template: ../steps/build-all-configurations-signed-dlls-step.yml@self + - template: ../steps/code-analyze-step.yml@self + parameters: + analyzeType: all + - template: ../steps/esrp-code-signing-step.yml@self + parameters: + artifactType: dll + - template: ../steps/generate-nuget-package-step.yml@self + parameters: + OutputDirectory: $(artifactDirectory) + - template: ../steps/esrp-code-signing-step.yml@self + parameters: + artifactType: pkg + - powershell: | + $software = '${{parameters.softwareFolder}}' + md $software + md $software\win + md $software\win\net46 + md $software\win\net6.0 + md $software\win\net8.0 + md $software\win\netstandard2.0 + md $software\win\netstandard2.1 + + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\Microsoft.Data.SqlClient.dll" "$software\win\net46" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.dll" "$software\win\net6.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.dll" "$software\win\net8.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.dll" "$software\win\netstandard2.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.1\Microsoft.Data.SqlClient.dll" "$software\win\netstandard2.1" -recurse + + $symbols = '${{parameters.symbolsFolder}}' + md $symbols + md $symbols\win + md $symbols\win\net46 + md $symbols\win\net6.0 + md $symbols\win\net8.0 + md $symbols\win\netstandard2.0 + md $symbols\win\netstandard2.1 + + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\Microsoft.Data.SqlClient.pdb" "$symbols\win\net46" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net6.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net8.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\netstandard2.0" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.1\Microsoft.Data.SqlClient.pdb" "$symbols\win\netstandard2.1" -recurse + + Write-Host "Artifacts fetched for testing" + dir + Get-Location + displayName: 'Prepare Arifacts for Testing' + # Publish symbols to private server + - template: ../steps/publish-symbols-step.yml@self + parameters: + SymAccount: $(PrivateSymAccount) + # Publish symbols to public server + - template: ../steps/publish-symbols-step.yml@self + parameters: + SymAccount: $(PublicSymAccount) diff --git a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml new file mode 100644 index 0000000000..0739e543cc --- /dev/null +++ b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml @@ -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. # +################################################################################# +parameters: + - name: downloadPackageStep + type: step + default: + script: echo + + - name: packageFolderName + type: string + default: drop_build_build_signed_package + + - name: dependsOn + type: string + default: empty + +jobs: +- job: run_tests_package_reference + ${{ if ne(parameters.dependsOn, 'empty')}}: + dependsOn: '${{parameters.dependsOn }}' + pool: + type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs + isCustom: true + name: ADO-1ES-Pool + vmImage: 'ADO-MMS22-SQL19' + + variables: # More settings at https://aka.ms/obpipelines/yaml/jobs + - template: ../../../libraries/build-variables.yml@self + - template: ../../../libraries/validation-variables.yml@self + + steps: + - template: ../steps/pre-build-step.yml + + - ${{parameters.downloadPackageStep }} + + - template: ../steps/update-nuget-config-local-feed-step.yml + parameters: + downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.packageFolderName }} + + - template: ../steps/update-config-file-step.yml + parameters: + TCPConnectionString: $(SQL_TCP_CONN_STRING) + NPConnectionString: $(SQL_NP_CONN_STRING) + SupportsIntegratedSecurity: false + + - template: ../steps/prepare-test-db-step.yml + +# build & test + - template: ../steps/build-and-run-tests-netfx-step.yml + parameters: + referenceType: Package + + - template: ../steps/build-and-run-tests-netcore-step.yml + parameters: + referenceType: Package + cleanFirst: true diff --git a/eng/pipelines/common/templates/jobs/verify-signed-package-job.yml b/eng/pipelines/common/templates/jobs/verify-signed-package-job.yml new file mode 100644 index 0000000000..e77d2596fd --- /dev/null +++ b/eng/pipelines/common/templates/jobs/verify-signed-package-job.yml @@ -0,0 +1,299 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: downloadPackageStep + type: step + default: + script: echo + + - name: packageFolderName + type: string + default: drop_build_build_signed_package + + - name: dependsOn + type: string + default: '' + + - name: packageType + type: string + default: both + values: + - dll + - pdb + - both + + - name: assembly_file_version_netfx + type: string + default: $(AssemblyFileVersion) + + - name: assembly_file_version_core + type: string + default: $(AssemblyFileVersion) + +jobs: +- job: verify_signed_package + ${{ if ne(parameters.dependsOn, '')}}: + dependsOn: '${{parameters.dependsOn }}' + pool: + type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs + isCustom: true + name: ADO-1ES-Pool + vmImage: 'ADO-MMS22-SQL19' + + variables: # More settings at https://aka.ms/obpipelines/yaml/jobs + - template: ../../../libraries/build-variables.yml@self + - template: ../../../libraries/validation-variables.yml@self + - name: pathToDownloadedNuget # path to the downloaded nuget files + value: $(Pipeline.Workspace)\${{parameters.packageFolderName }} + + steps: + - script: SET + displayName: 'Print Environment Variables' + + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet ' + + - powershell: | + #Sets Variables for AssemblyFileVersion, AssemblyVersion and NugetPackageVersion + + [Xml] $versionprops = Get-Content -Path ".\tools\props\Versions.props" + Write-Host $versionprops.Project.PropertyGroup[0].AssemblyFileVersion + + $AssemblyVersion = $versionprops.Project.PropertyGroup[0].AssemblyVersion + + Write-Host "##vso[task.setvariable variable=ASSEMBLY_VERSION;]$AssemblyVersion" + displayName: 'Update assembly version property' + + - powershell: | + # Displays the paths of all the local cache directories + nuget locals all -List + + #Clears all files from all local cache directories + nuget locals all -Clear + displayName: 'Clear local cache' + + - ${{parameters.downloadPackageStep }} + + - powershell: | + # Install nuget package + Install-Package -Name "Microsoft.Data.SqlClient" -Destination "$(TempFolderName)" -Force -Source $(pathToDownloadedNuget) -SkipDependencies + + Write-Host "--------------------------------------------------" + Write-Host '$(TempFolderName)' + ls $(TempFolderName) + Write-Host "--------------------------------------------------" + displayName: 'Extract Nuget in temp folder' + + - powershell: | + # Artifact is stored in the Nuget folder + $packageType = '${{parameters.packageType}}' + + Write-Host "--------------------------------------------------" + Write-Host "This will verify the artifact signature" -ForegroundColor Green + Write-Host "--------------------------------------------------" + + if ($packageType -eq 'dll' -or $packageType -eq 'both') + { + nuget verify -All $(pathToDownloadedNuget)\*.nupkg + } + if ($packageType -eq 'pdb' -or $packageType -eq 'both') + { + nuget verify -All $(pathToDownloadedNuget)\*.snupkg + } + displayName: 'Verify nuget signature' + + - powershell: | + # Checks the expected folder names such as lib, ref, runtimes + Get-ChildItem -Path $(extractedNugetPath) -Directory | select Name | foreach { + if('$(expectedFolderNames)'.contains($_.Name)){ + Write-Host expected folder name verfied: $_.Name + } + } + displayName: 'Check expected folder names' + + - powershell: | + # Checks the version of DotNetFramework, NetStandard and NetCore + $countErr = 0 + $countPass = 0 + $excludNamesFromRuntimeFolder = 'lib','win','unix' + + Get-ChildItem -Path $(extractedNugetPath) -Directory | foreach { + $parentname=$_.Name + Write-Host $_.FullName -ForegroundColor yellow + + if($_.Name -ne 'runtimes') { + Get-ChildItem -Path $_.FullName -Directory | select Name | foreach { + if('$(expectedDotnetVersions)'.Contains($_.Name)){ + Write-Host "`tExpected version verified in $parentname": $_.Name -ForegroundColor green + $countPass += 1 + } + else{ + Write-Host "`tUnexpected version detected in $parentname": $_.Name + $countErr += 1 + } + } + } + + elseif ($_.Name -eq 'runtimes'){ + Get-ChildItem -Depth 3 -Path $_.FullName -Exclude $excludNamesFromRuntimeFolder -Directory | foreach{ + if('$(expectedDotnetVersions)'.Contains($_.Name)){ + Write-Host "`tExpected version verfied in $parentname": $_.Name + $countPass += 1 + } + else{ + Write-Host "`tUnexpected version detected": $_.Name -ForegroundColor Red + $countErr += 1 + } + } + } + else{ + Write-Host "`tUnknown folder " $_.Name -ForegroundColor Red + Exit -1 + } + } + + Write-Host "_______________" + Write-Host "Expected: $countPass" + Write-Host "Unexpected: $countErr" + Write-Host "_______________" + if ($countErr -ne 0) + { + Write-Host "Unexpected versions are detected!" -ForegroundColor Red + Exit -1 + } + displayName: 'Check Expected framework' + + - powershell: | + # list all the child items of created temp folder + + #Verify all DLLs unzipped match "expected" hierarchy + + foreach( $folderName in (Get-ChildItem -Path $(extractedNugetPath) -Directory).Name) + { + # List all Childerns of the Path + Get-ChildItem -Path $(extractedNugetPath)\$folderName -Recurse -File + $subFiles = Get-ChildItem -Path $(extractedNugetPath)\$folderName -Recurse -File + + foreach($file in $subFiles) + { + if($subFiles[0].Name -like "*.dll" ) + { + Write-Host $subFiles[0].Name -ForegroundColor Green + Write-Host $subFiles[1].Name -ForegroundColor Green + if(($folderName -eq 'lib') -or ($folderName -eq 'ref')) + { + if($subFiles[2].Name -like "*.dll") + { + Write-Host $subFiles[2].Name -ForegroundColor Green + } + else + { + $subFiles[2].Name + Write-Host "Expected file pattern for localization did not match to *.dll" -ForegroundColor Red + Exit -1 + } + } + } + else + { + $subFiles[0].Name + $subFiles[1].Name + Write-Host "Expected file pattern did not match to *.dll" -ForegroundColor Red + Exit -1 + } + } + } + displayName: 'Verify all DLLs unzipped match "expected" hierarchy' + + - powershell: | + # Verify all dlls status are Valid + + $dlls = Get-ChildItem -Path $(extractedNugetPath) -Recurse -Include *.dll + foreach ($status in $dlls | Get-AuthenticodeSignature) + { + if ($status.Status -eq "Valid") + { + Write-Host $status.Status $status.Path + } + else + { + Write-Host "dll status of '$status.Path' is not valid!" -ForegroundColor Red + $status + Exit -1 + } + } + displayName: 'Verify all dlls status are Valid' + + - powershell: | + # This will check for ProductVersion and FileVersion + # For NetFx we have a different FileVersion, but product versions are all the same some may have and extra numbering at the end. we only check for # first parts + + foreach ( $pVersion in Get-ChildItem *.dll -Path $(extractedNugetPath) -Recurse | ForEach-Object versioninfo ) + { + if ($pVersion.ProductVersion -Like '$(ProductVersion)*') + { + Write-Host Valid Product Version:"$pVersion.ProductVersion" $pVersion.ProductVersion detected for $pVersion.FileName -ForegroundColor Green + } + else + { + Write-Host "Wrong ProductVersion detected. Expected: '$(ProductVersion)', but Detected: "$pVersion.ProductVersion"" + Exit -1 + } + + if($pVersion.FileName -like '*lib\$(CurrentNetFxVersion)*'){ + + if($pVersion.FileVersion -eq '${{parameters.assembly_file_version_netfx }}') + { + Write-Host 'Correct File version Detected for net46,' $pVersion.FileVersion -ForegroundColor Green + } + else + { + Write-Host 'Wrong File version Detected for net46,' $pVersion.FileVersion -ForegroundColor Red + Exit -1 + } + } + else + { + + if($pVersion.FileVersion -eq '${{parameters.assembly_file_version_core}}') + { + Write-Host 'Correct File version Detected for netcore and netstandard,' $pVersion.FileVersion -ForegroundColor Green + } + else + { + Write-Host 'Wrong File version Detected for netcore and netstandard and ref folder of netfx,' $pVersion.FileVersion -ForegroundColor Red + Exit -1 + } + } + } + + Get-ChildItem *.dll -Path $(extractedNugetPath) -Recurse | ForEach-Object versioninfo + displayName: 'Verify "File Version" matches provided pipeline variable "ASSEMBLY_FILE_VERSION" for DLLs' + + - powershell: | + #Change TestMicrosoftDataSqlClientVersion + + [Xml] $versionprops = Get-Content -Path "tools/props/Versions.props" + $versionpropspath = "tools\props\Versions.props" + $versionprops.Project.PropertyGroup[$versionprops.Project.PropertyGroup.Count-1].TestMicrosoftDataSqlClientVersion ="$(NugetPackageVersion)" + Write-Host "Saving Test nuget version at $rootfolder\props ...." -ForegroundColor Green + $versionprops.Save($versionpropspath) + + displayName: 'Modify TestMicrosoftDataSqlClientVersion' + + - powershell: | + #Change TestMicrosoftDataSqlClientVersion + + [Xml] $versionprops = Get-Content -Path "tools/props/Versions.props" + $AssemblyFileVersion = $versionprops.Project.PropertyGroup[0].AssemblyFileVersion + $AssemblyVersion = $versionprops.Project.PropertyGroup[0].AssemblyVersion + + if($AssemblyFileVersion -eq $AssemblyVersion) + { + Write-Host AssemblyFileVersion: $AssemblyFileVersion should not be equal to: $AssemblyVersion + Exit -1 + } + displayName: 'Check "AssemblyFileVersion" is not same as "AssemblyVersion" in version.props' diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml new file mode 100644 index 0000000000..c5709114ac --- /dev/null +++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml @@ -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. # +################################################################################# +parameters: + - name: AssemblyFileVersion + type: string + default: $(AssemblyFileVersion) + + - name: Configuration + type: string + default: '$(Configuration)' + +steps: + - task: DownloadSecureFile@1 + displayName: 'Download Key Pair' + inputs: + secureFile: netfxKeypair.snk + retryCount: 5 + - task: MSBuild@1 + displayName: 'BuildAllConfigurations using build.proj' + inputs: + solution: '**/build.proj' + configuration: '${{parameters.Configuration }}' + msbuildArguments: '/p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} /t:BuildAllConfigurations /p:GenerateNuget=false /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' diff --git a/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml b/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml new file mode 100644 index 0000000000..f747fa57e6 --- /dev/null +++ b/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml @@ -0,0 +1,80 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: TargetNetCoreVersion + type: string + default: $(TargetNetCoreVersion) + + - name: configuration + type: string + default: $(Configuration) + + - name: referenceType + default: Project + values: + - Project + - Package + + - name: NugetPackageVersion + type: string + default: $(NugetPackageVersion) + + - name: platform + type: string + default: $(Platform) + + - name: cleanFirst + type: boolean + default: false + + - name: TestTargetOS + type: string + default: Windowsnetcoreapp + values: + - Windowsnetfx + - Windowsnetcoreapp + - Unixnetcoreapp + + - name: retryCountOnManualTests + type: number + default: 2 + +steps: +- ${{ if eq(parameters.cleanFirst, true)}}: + - task: MSBuild@1 + displayName: 'Clean artifacts folder' + inputs: + solution: build.proj + msbuildArguments: '-t:clean' + +- task: MSBuild@1 + displayName: 'Build AKV Provider .NET' + inputs: + solution: build.proj + msbuildArchitecture: x64 + msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetCore -p:ReferenceType=${{parameters.referenceType }} ' + +- task: MSBuild@1 + displayName: 'MSBuild Build Tests for ${{parameters.TargetNetCoreVersion }}' + inputs: + solution: build.proj + msbuildArchitecture: x64 + msbuildArguments: '-t:BuildTestsNetCore -p:ReferenceType=${{parameters.referenceType }} -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} -p:Configuration=${{parameters.configuration }}' + +- task: DotNetCoreCLI@2 + displayName: 'Run Functional Tests for ${{parameters.TargetNetCoreVersion }}' + inputs: + command: test + projects: 'src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj' + arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"' + +- task: DotNetCoreCLI@2 + displayName: 'Run Manual Tests for ${{parameters.TargetNetCoreVersion }}' + inputs: + command: test + projects: 'src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj' + arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests --collect "Code Coverage"' + retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }} diff --git a/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml b/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml new file mode 100644 index 0000000000..ab77af3ee9 --- /dev/null +++ b/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml @@ -0,0 +1,79 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: TargetNetFxVersion + type: string + default: $(TargetNetFxVersion) + + - name: configuration + type: string + default: $(Configuration) + + - name: referenceType + default: Project + values: + - Project + - Package + + - name: NugetPackageVersion + type: string + default: $(NugetPackageVersion) + + - name: platform + type: string + default: $(Platform) + + - name: cleanFirst + type: boolean + default: false + + - name: TestTargetOS + type: string + default: Windowsnetfx + values: + - Windowsnetfx + - Windowsnetcoreapp + - Unixnetcoreapp + + - name: retryCountOnManualTests + type: number + default: 2 + +steps: +- ${{ if eq(parameters.cleanFirst, true)}}: + - task: MSBuild@1 + displayName: 'Clean artifacts folder' + inputs: + solution: build.proj + msbuildArguments: '-t:clean' + +- task: MSBuild@1 + displayName: 'Build AKV Provider .NET Framework' + inputs: + solution: build.proj + msbuildArchitecture: x64 + msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetFx -p:ReferenceType=${{parameters.referenceType }} ' + +- task: MSBuild@1 + displayName: 'MSBuild Build Tests for ${{parameters.TargetNetFxVersion }}' + inputs: + solution: build.proj + msbuildArguments: ' -t:BuildTestsNetFx -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:Configuration=${{parameters.configuration }} -p:Platform=${{parameters.platform }}' + +- task: DotNetCoreCLI@2 + displayName: 'Run Functional Tests for ${{parameters.TargetNetFxVersion }}' + inputs: + command: test + projects: 'src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj' + arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"' + +- task: DotNetCoreCLI@2 + displayName: 'Run Manual Tests for ${{parameters.TargetNetFxVersion }}' + inputs: + command: test + projects: 'src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj' + arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"' + retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }} diff --git a/eng/pipelines/common/templates/steps/code-analyze-step.yml b/eng/pipelines/common/templates/steps/code-analyze-step.yml new file mode 100644 index 0000000000..ec6a552fcb --- /dev/null +++ b/eng/pipelines/common/templates/steps/code-analyze-step.yml @@ -0,0 +1,31 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# +parameters: + - name: analyzeType + values: + - roslyn + - inspect + - all + + - name: sourceRoot + type: string + default: $(REPOROOT) + +steps: +- ${{ if or(eq(parameters.analyzeType, 'roslyn'), eq(parameters.analyzeType, 'all')) }}: + - task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3 + displayName: 'Guardian Dotnet Analyzers ' + inputs: + msBuildVersion: 17.0 + msBuildArchitecture: x64 + setupCommandlinePicker: vs2022 + msBuildCommandline: 'msbuild ${{parameters.sourceRoot}}\build.proj -p:configuration=Release -p:GenerateNuget=false -p:BuildTools=false' + +- ${{ if or(eq(parameters.analyzeType, 'inspect'), eq(parameters.analyzeType, 'all')) }}: + - task: securedevelopmentteam.vss-secure-development-tools.build-task-codeinspector.CodeInspector@2 + displayName: 'Run Code Inspector' + inputs: + LogLevel: Error diff --git a/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml b/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml new file mode 100644 index 0000000000..02b9487cc3 --- /dev/null +++ b/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml @@ -0,0 +1,106 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: artifactType + values: + - dll + - pkg + + - name: sourceRoot + type: string + default: $(REPOROOT) + + - name: artifactDirectory + type: string + default: $(artifactDirectory) + +steps: +- ${{ if eq(parameters.artifactType, 'dll') }}: + - task: SFP.build-tasks.custom-build-task-2.EsrpMalwareScanning@4 + displayName: 'ESRP MalwareScanning' + inputs: + ConnectedServiceName: 'SqlClient ESRP Malware Scanning' + FolderPath: '${{parameters.sourceRoot }}' + Pattern: '*.dll' + Region: US + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@4 + displayName: 'ESRP CodeSigning' + inputs: + ConnectedServiceName: 'SqlClient ESRP Code Signing' + FolderPath: '${{parameters.sourceRoot }}' + Pattern: '*.dll' + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-230012", + "operationSetCode": "SigntoolSign", + "parameters": [ + { + "parameterName": "OpusName", + "parameterValue": "Microsoft Data SqlClient Data Provider for SQL Server" + }, + { + "parameterName": "OpusInfo", + "parameterValue": "http://www.microsoft.com" + }, + { + "parameterName": "FileDigest", + "parameterValue": "/fd \"SHA256\"" + }, + { + "parameterName": "PageHash", + "parameterValue": "/NPH" + }, + { + "parameterName": "TimeStamp", + "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" + } + ], + "toolName": "sign", + "toolVersion": "1.0" + }, + { + "keyCode": "CP-230012", + "operationSetCode": "SigntoolVerify", + "parameters": [ ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] + +- ${{ if eq(parameters.artifactType, 'pkg') }}: + - task: SFP.build-tasks.custom-build-task-2.EsrpMalwareScanning@4 + displayName: 'ESRP MalwareScanning Nuget Package' + inputs: + ConnectedServiceName: 'SqlClient ESRP Malware Scanning' + FolderPath: '${{parameters.artifactDirectory }}' + Pattern: '*.*nupkg' + Region: US + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@4 + displayName: 'ESRP CodeSigning Nuget Package' + inputs: + ConnectedServiceName: 'SqlClient ESRP Code Signing' + FolderPath: '${{parameters.artifactDirectory }}' + Pattern: '*.*nupkg' + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-401405", + "operationSetCode": "NuGetSign", + "parameters": [ ], + "toolName": "sign", + "toolVersion": "1.0" + }, + { + "keyCode": "CP-401405", + "operationSetCode": "NuGetVerify", + "parameters": [ ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml new file mode 100644 index 0000000000..91b4ee72e1 --- /dev/null +++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml @@ -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. # +################################################################################# +parameters: + - name: CommitHead + type: string + default: '' # the value will grab from the repo's head + + - name: nuspecPath + type: string + default: '$(nuspecPath)' + + - name: NugetPackageVersion + type: string + default: '$(NugetPackageVersion)' + + - name: OutputDirectory + type: string + default: '$(Build.SourcesDirectory)/packages' + + - name: Configuration + type: string + default: '$(Configuration)' + +steps: +- task: NuGetToolInstaller@1 + displayName: 'Install Latest Nuget' + inputs: + checkLatest: true +- powershell: | + $Commit=git rev-parse HEAD + Write-Host "##vso[task.setvariable variable=CommitHead;]$Commit" + displayName: CommitHead +- task: NuGetCommand@2 + displayName: 'NuGet pack with snupkg' + inputs: + command: custom + arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=${{parameters.CommitHead}};Configuration=${{parameters.Configuration}}"' diff --git a/eng/pipelines/common/templates/steps/pre-build-step.yml b/eng/pipelines/common/templates/steps/pre-build-step.yml new file mode 100644 index 0000000000..327b5f21a5 --- /dev/null +++ b/eng/pipelines/common/templates/steps/pre-build-step.yml @@ -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. # +################################################################################# +steps: +- script: SET + displayName: 'Print Environment Variables' + +- powershell: | + # use sqlcmd to try to connect to localdb + $svc_name = "SQLBrowser" + Get-Service $svc_name | Select-Object -Property Name, StartType, Status + Set-Service -StartupType Automatic $svc_name + net start $svc_name + Get-Service $svc_name | Select-Object -Property Name, StartType, Status + displayName: 'Start SQLBrowser' + +- task: NuGetToolInstaller@1 + displayName: 'Use NuGet ' diff --git a/eng/pipelines/common/templates/steps/prepare-test-db-step.yml b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml new file mode 100644 index 0000000000..8597a0c9e5 --- /dev/null +++ b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml @@ -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. # +################################################################################# +parameters: + - name: databaseName + type: string + default: $(Database) + + - name: targetFramework + type: string + default: net6.0 + +steps: +- task: DotNetCoreCLI@2 + displayName: 'Build Ext Utilities' + inputs: + arguments: '-f ${{parameters.targetFramework }}' + workingDirectory: src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities +- task: DotNetCoreCLI@2 + displayName: 'Create Test Database' + inputs: + command: run + arguments: '-f ${{parameters.targetFramework }} -- "CreateDatabase" ${{parameters.databaseName }} ' + workingDirectory: src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities diff --git a/eng/pipelines/common/templates/steps/publish-symbols-step.yml b/eng/pipelines/common/templates/steps/publish-symbols-step.yml new file mode 100644 index 0000000000..8dbb89db33 --- /dev/null +++ b/eng/pipelines/common/templates/steps/publish-symbols-step.yml @@ -0,0 +1,29 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# +parameters: + - name: SymAccount + type: string + + - name: PublishSymbols + type: string + default: '$(PublishSymbols)' + +steps: +- powershell: 'Write-Host "##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{parameters.SymAccount}}"' + displayName: 'Update Symbol.AccountName ${{parameters.SymAccount}}' +- task: PublishSymbols@2 + displayName: 'Publish symbols path' + inputs: + SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\Project\bin' + SearchPattern: | + Windows_NT/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb + Unix/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb + IndexSources: false + SymbolServerType: TeamServices + SymbolsMaximumWaitTime: 60 + SymbolsProduct: Microsoft.Data.SqlClient + SymbolsVersion: '$(NuGetPackageVersion)' + condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) diff --git a/eng/pipelines/common/templates/steps/update-config-file-step.yml b/eng/pipelines/common/templates/steps/update-config-file-step.yml new file mode 100644 index 0000000000..2530f35d23 --- /dev/null +++ b/eng/pipelines/common/templates/steps/update-config-file-step.yml @@ -0,0 +1,35 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# +parameters: + - name: TCPConnectionString + type: string + default: '' + + - name: NPConnectionString + type: string + default: '' + + - name: SupportsIntegratedSecurity + type: boolean + default: false + +steps: +# All properties should be added here, and this template should be used for any manipulation of the config.json file. +- powershell: | + $jdata = Get-Content -Raw "config.default.json" | ConvertFrom-Json + foreach ($p in $jdata) + { + if ("${{parameters.TCPConnectionString }}" -ne ""){ + $p.TCPConnectionString="${{parameters.TCPConnectionString }}"} + + if ("${{parameters.NPConnectionString }}" -ne ""){ + $p.NPConnectionString="${{parameters.NPConnectionString }}"} + + $p.SupportsIntegratedSecurity=[System.Convert]::ToBoolean("${{parameters.SupportsIntegratedSecurity }}") + } + $jdata | ConvertTo-Json | Set-Content "config.json" + workingDirectory: src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities + displayName: 'Update config.json' diff --git a/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml new file mode 100644 index 0000000000..61bd394af4 --- /dev/null +++ b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml @@ -0,0 +1,78 @@ +################################################################################# +# 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. # +################################################################################# +parameters: + - name: downloadedNugetPath # path to the downloaded nuget files + type: string + + - name: nugetPackageVersion + type: string + default: $(NugetPackageVersion) + +steps: +- powershell: | + # Get a list of package sources available + Get-PackageSource + + #Current location + Get-Location + + # Register the local nuget folder to be used by nuget.config + Register-PackageSource -Name "Package Source" -Location ${{parameters.downloadedNugetPath }} -Force -ProviderName NuGet -Trusted + + # Get a list of package sources available after the change + Get-PackageSource + + #Set the Nuget.config file in the project to use extracted package + $rootFolder = Get-location + [Xml] $nugetConfig = Get-Content -Path "src\Nuget.config" + $Value = Resolve-Path ${{parameters.downloadedNugetPath }} + $newAdd = $nugetConfig.CreateElement("add") + $newAdd.SetAttribute("key","Package source") + $newAdd.SetAttribute("value", "$Value\" ) + $nugetConfig.configuration.packageSources.AppendChild($newAdd) + $nugetConfig.Save("$rootFolder\src\Nuget.config") + displayName: 'Update NuGet config file to read from Nuget folder' + +- task: MSBuild@1 + displayName: 'Restore nugets' + inputs: + solution: build.proj + msbuildArchitecture: x64 + msbuildArguments: '-t:restore' + +- powershell: | + $Doc = [xml](Get-Content ".\Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj") + $parent_xpath = '/Project/ItemGroup/ProjectReference' + $node = $Doc.SelectSingleNode($parent_xpath) + $parentNode = $node.ParentNode + while($node -ne $null) { + $node.ParentNode.RemoveChild($node) + $node = $Doc.SelectSingleNode($parent_xpath) + } + + $parent_xpath = '/Project/ItemGroup/PackageReference[@Include="Microsoft.Data.SqlClient"]' + $node = $Doc.SelectSingleNode($parent_xpath) + + if($node -ne $null){ + $node.Version="${{parameters.nugetPackageVersion }}" + } + else{ + $packagerefnode = $doc.createelement("packagereference") + $value = $doc.selectsinglenode('/project/itemgroup/projectreference') + $attrinclude = $doc.createattribute("include") + $attrinclude.value = "microsoft.data.sqlclient" + $attrversion = $doc.createattribute("version") + $attrversion.value = "${{parameters.nugetPackageVersion }}" + $packagerefnode.attributes.append($attrinclude) + $packagerefnode.attributes.append($attrversion) + $parentNode.AppendChild($packageRefNode) + } + + $currentFolder = Get-Location + $filePath = Join-Path $currentFolder "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj" + $Doc.Save($filePath) + workingDirectory: 'src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider' + displayName: 'Update AKV Project Ref to Package Ref (.NET Framework/Core)' diff --git a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml new file mode 100644 index 0000000000..c9c1f9d8db --- /dev/null +++ b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml @@ -0,0 +1,98 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# + +name: $(Year:YY)$(DayOfYear)$(Rev:.rr) +trigger: none # https://aka.ms/obpipelines/triggers + +parameters: # parameters are shown up in ADO UI in a build queue time +- name: 'debug' + displayName: 'Enable debug output' + type: boolean + default: true + +variables: + - template: /eng/pipelines/libraries/variables.yml@self + - name: packageFolderName + value: drop_build_build_signed_package + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + +extends: + template: v2/OneBranch.Official.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates + parameters: + featureFlags: + WindowsHostVersion: 1ESWindows2022 + globalSdl: # https://aka.ms/obpipelines/sdl + apiscan: + enabled: true + softwareFolder: $(softwareFolder) + symbolsFolder: $(symbolsFolder) + softwarename: Microsoft.Data.SqlClient + versionNumber: $(AssemblyFileVersion) + asyncSdl: + enabled: false + tsa: + enabled: true # onebranch publish all sdl results to TSA. If TSA is disabled all SDL tools will forced into 'break' build mode. + credscan: + enabled: true + suppressionsFile: $(REPOROOT)/.config/CredScanSuppressions.json + binskim: + enabled: true + policheck: + enabled: true + break: true # always break the build on policheck issues. You can disable it by setting to 'false' + exclusionsFile: $(REPOROOT)\.config\PolicheckExclusions.xml + armory: + enabled: true + break: true + eslint: # TypeScript and JavaScript + enabled: false + roslyn: + enabled: true + break: true + publishLogs: + enabled: true + sbom: + enabled: true + packageName: Microsoft.Data.SqlClient + pacakgeVersion: $(NugetPackageVersion) + codeql: + compiled: + enabled: true + tsaOptionsPath: $(REPOROOT)\.config\tsaoptions.json + disableLegacyManifest: true + stages: + - stage: build + jobs: + - template: eng/pipelines/common/templates/jobs/build-signed-package-job.yml@self + parameters: + symbolsFolder: $(symbolsFolder) + softwareFolder: $(softwareFolder) + + - stage: package_validation + dependsOn: build + jobs: + - template: eng/pipelines/common/templates/jobs/verify-signed-package-job.yml@self + parameters: + packageFolderName: $(packageFolderName) + downloadPackageStep: + download: current + artifact: $(packageFolderName) + patterns: '**/*.*nupkg' + displayName: 'Download NuGet Package' + - template: eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml@self + parameters: + packageFolderName: $(packageFolderName) + downloadPackageStep: + download: current + artifact: $(packageFolderName) + patterns: '**/*.nupkg' + displayName: 'Download NuGet Package' diff --git a/eng/pipelines/libraries/build-variables.yml b/eng/pipelines/libraries/build-variables.yml new file mode 100644 index 0000000000..613c03a02b --- /dev/null +++ b/eng/pipelines/libraries/build-variables.yml @@ -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. # +################################################################################# + +variables: + - group: Release Variables + - name: NugetPackageVersion + value: $(Major).$(Minor).$(Patch) + - name: AssemblyFileVersion + value: '$(Major).$(Minor)$(Patch).$(Build.BuildNumber)' + - name: Configuration + value: Release + - name: CommitHead + value: '' # the value will be extracted from the repo's head + - name: REPOROOT + value: $(Build.SourcesDirectory) + - name: nuspecPath + value: '$(REPOROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec' + - name: softwareFolder + value: $(REPOROOT)/software + - name: symbolsFolder + value: $(REPOROOT)/symbols + - name: artifactDirectory + value: '$(REPOROOT)/packages' diff --git a/eng/pipelines/libraries/validation-variables.yml b/eng/pipelines/libraries/validation-variables.yml new file mode 100644 index 0000000000..32c008ef89 --- /dev/null +++ b/eng/pipelines/libraries/validation-variables.yml @@ -0,0 +1,32 @@ +################################################################################# +# 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. # +################################################################################# + +variables: + - template: build-variables.yml@self + - name: TempFolderName # extract the nuget package here + value: temp + - name: extractedNugetPath + value: $(Build.SourcesDirectory)\$(TempFolderName)\Microsoft.Data.SqlClient.$(NugetPackageVersion) + - name: expectedFolderNames + value: lib,ref,runtimes + - name: expectedDotnetVersions + value: net462,net6.0,net8.0,netstandard2.0,netstandard2.1 + - name: Database + value: Northwind + - name: platform + value: AnyCPU + - name: TargetNetFxVersion + value: net481 + - name: TargetNetCoreVersion + value: net8.0 + - name: SQLTarget + value: localhost + - name: encrypt + value: false + - name: SQL_NP_CONN_STRING + value: Data Source=np:$(SQLTarget);Initial Catalog=$(Database);Integrated Security=true;Encrypt=$(ENCRYPT);TrustServerCertificate=true; + - name: SQL_TCP_CONN_STRING + value: Data Source=tcp:$(SQLTarget);Initial Catalog=$(Database);Integrated Security=true;Encrypt=$(ENCRYPT);TrustServerCertificate=true; diff --git a/eng/pipelines/libraries/variables.yml b/eng/pipelines/libraries/variables.yml new file mode 100644 index 0000000000..57894459d3 --- /dev/null +++ b/eng/pipelines/libraries/variables.yml @@ -0,0 +1,17 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# + +variables: + - template: build-variables.yml@self + # onebranch template variables + - name: ob_outputDirectory + value: '$(artifactDirectory)' # this directory is uploaded to pipeline artifacts, reddog and cloudvault. More info at https://aka.ms/obpipelines/artifacts + - name: ob_sdl_binskim_break + value: true # https://aka.ms/obpipelines/sdl + - name: Packaging.EnableSBOMSigning + value: true + - name: WindowsContainerImage + value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project https://aka.ms/obpipelines/containers From 1594cc5fa02a942346deffb0064313b130758f6a Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Fri, 29 Mar 2024 14:23:43 -0700 Subject: [PATCH 14/53] Merge common code base for DBReferenceCollection (#2403) --- .../ProviderBase/DbReferenceCollection.cs | 263 ------------------ .../src/Microsoft.Data.SqlClient.csproj | 6 +- .../netfx/src/Microsoft.Data.SqlClient.csproj | 4 +- .../ProviderBase/DbReferenceCollection.cs | 110 ++++---- 4 files changed, 68 insertions(+), 315 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs rename src/Microsoft.Data.SqlClient/{netfx => }/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs (69%) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs deleted file mode 100644 index e7efdad252..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs +++ /dev/null @@ -1,263 +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.Diagnostics; -using System.Threading; - -namespace Microsoft.Data.ProviderBase -{ - internal abstract class DbReferenceCollection - { - private struct CollectionEntry - { - private int _tag; // information about the reference - private WeakReference _weak; // the reference itself. - - public void NewTarget(int tag, object target) - { - Debug.Assert(!TryGetTarget(out object _) , "Entry already has a valid target"); - Debug.Assert(tag != 0, "Bad tag"); - Debug.Assert(target != null, "Invalid target"); - - if (_weak == null) - { - _weak = new WeakReference(target, false); - } - else - { - _weak.SetTarget(target); - } - _tag = tag; - } - - public void RemoveTarget() - { - _tag = 0; - _weak.SetTarget(null); - } - - public int Tag => _tag; - - public bool TryGetTarget(out object target) - { - target = null; - return _tag != 0 && _weak.TryGetTarget(out target); - } - } - - private const int LockPollTime = 100; // Time to wait (in ms) between attempting to get the _itemLock - private const int DefaultCollectionSize = 20; // Default size for the collection, and the amount to grow every time the collection is full - private CollectionEntry[] _items; // The collection of items we are keeping track of - private readonly object _itemLock; // Used to synchronize access to the _items collection - private int _optimisticCount; // (#ItemsAdded - #ItemsRemoved) - This estimates the number of items that we *should* have (but doesn't take into account item targets being GC'd) - private int _lastItemIndex; // Location of the last item in _items - private volatile bool _isNotifying; // Indicates that the collection is currently being notified (and, therefore, about to be cleared) - - protected DbReferenceCollection() - { - _items = new CollectionEntry[DefaultCollectionSize]; - _itemLock = new object(); - _optimisticCount = 0; - _lastItemIndex = 0; - } - - abstract public void Add(object value, int tag); - - protected void AddItem(object value, int tag) - { - Debug.Assert(null != value && 0 != tag, "AddItem with null value or 0 tag"); - bool itemAdded = false; - - lock (_itemLock) - { - // Try to find a free spot - for (int i = 0; i <= _lastItemIndex; ++i) - { - if (_items[i].Tag == 0) - { - _items[i].NewTarget(tag, value); - Debug.Assert(_items[i].TryGetTarget(out object _), "missing expected target"); - itemAdded = true; - break; - } - } - - // No free spots, can we just add on to the end? - if ((!itemAdded) && (_lastItemIndex + 1 < _items.Length)) - { - _lastItemIndex++; - _items[_lastItemIndex].NewTarget(tag, value); - itemAdded = true; - } - - // If no free spots and no space at the end, try to find a dead item - if (!itemAdded) - { - for (int i = 0; i <= _lastItemIndex; ++i) - { - if (!_items[i].TryGetTarget(out object _)) - { - _items[i].NewTarget(tag, value); - Debug.Assert(_items[i].TryGetTarget(out object _), "missing expected target"); - itemAdded = true; - break; - } - } - } - - // If nothing was free, then resize and add to the end - if (!itemAdded) - { - Array.Resize(ref _items, _items.Length * 2); - _lastItemIndex++; - _items[_lastItemIndex].NewTarget(tag, value); - } - - _optimisticCount++; - } - } - - internal T FindItem(int tag, Func filterMethod) where T : class - { - bool lockObtained = false; - try - { - TryEnterItemLock(ref lockObtained); - if (lockObtained) - { - if (_optimisticCount > 0) - { - for (int counter = 0; counter <= _lastItemIndex; counter++) - { - // Check tag (should be easiest and quickest) - if (_items[counter].Tag == tag) - { - if (_items[counter].TryGetTarget(out object value)) - { - // Make sure the item has the correct type and passes the filtering - if (value is T tempItem && filterMethod(tempItem)) - { - return tempItem; - } - } - } - } - } - } - } - finally - { - ExitItemLockIfNeeded(lockObtained); - } - - // If we got to here, then no item was found, so return null - return null; - } - - public void Notify(int message) - { - bool lockObtained = false; - try - { - TryEnterItemLock(ref lockObtained); - if (lockObtained) - { - try - { - _isNotifying = true; - - // Loop through each live item and notify it - if (_optimisticCount > 0) - { - for (int index = 0; index <= _lastItemIndex; ++index) - { - if (_items[index].TryGetTarget(out object value)) - { - NotifyItem(message, _items[index].Tag, value); - _items[index].RemoveTarget(); - } - Debug.Assert(!_items[index].TryGetTarget(out object _), "Unexpected target after notifying"); - } - _optimisticCount = 0; - } - - // Shrink collection (if needed) - if (_items.Length > 100) - { - _lastItemIndex = 0; - _items = new CollectionEntry[DefaultCollectionSize]; - } - } - finally - { - _isNotifying = false; - } - } - } - finally - { - ExitItemLockIfNeeded(lockObtained); - } - } - - abstract protected void NotifyItem(int message, int tag, object value); - - abstract public void Remove(object value); - - protected void RemoveItem(object value) - { - Debug.Assert(null != value, "RemoveItem with null"); - - bool lockObtained = false; - try - { - TryEnterItemLock(ref lockObtained); - - if (lockObtained) - { - // Find the value, and then remove the target from our collection - if (_optimisticCount > 0) - { - for (int index = 0; index <= _lastItemIndex; ++index) - { - if (_items[index].TryGetTarget(out object target) && value == target) - { - _items[index].RemoveTarget(); - _optimisticCount--; - break; - } - } - } - } - } - finally - { - ExitItemLockIfNeeded(lockObtained); - } - } - - // This is polling lock that will abandon getting the lock if _isNotifying is set to true - private void TryEnterItemLock(ref bool lockObtained) - { - // Assume that we couldn't take the lock - lockObtained = false; - // Keep trying to take the lock until either we've taken it, or the collection is being notified - while ((!_isNotifying) && (!lockObtained)) - { - Monitor.TryEnter(_itemLock, LockPollTime, ref lockObtained); - } - } - - private void ExitItemLockIfNeeded(bool lockObtained) - { - if (lockObtained) - { - Monitor.Exit(_itemLock); - } - } - } -} - 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 eb15ff1e1a..48ab208ceb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -519,6 +519,9 @@ Common\System\Diagnostics\CodeAnalysis.cs + + Microsoft\Data\ProviderBase\DbReferenceCollection.cs + @@ -616,9 +619,6 @@ Common\Microsoft\Data\ProviderBase\DbConnectionInternal.cs - - Common\Microsoft\Data\ProviderBase\DbReferenceCollection.cs - 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 2bcc979352..4dc1ae6393 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -609,6 +609,9 @@ Resources\ResDescriptionAttribute.cs + + Microsoft\Data\ProviderBase\DbReferenceCollection.cs + @@ -630,7 +633,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs similarity index 69% rename from src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs index 1e69bcaba9..35356bfa12 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs @@ -2,74 +2,90 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; +using System.Diagnostics; +using System.Threading; + namespace Microsoft.Data.ProviderBase { - - using System; - using System.Diagnostics; - using System.Threading; - internal abstract class DbReferenceCollection { + #region Constants + // Time to wait (in ms) between attempting to get the _itemLock + private const int LockPollTime = 100; + + // Default size for the collection, and the amount to grow every time the collection is full + private const int DefaultCollectionSize = 20; + #endregion + + #region Fields + // The collection of items we are keeping track of + private CollectionEntry[] _items; + + // Used to synchronize access to the _items collection + private readonly object _itemLock; + + // (#ItemsAdded - #ItemsRemoved) - This estimates the number of items that we should have + // (but doesn't take into account item targets being GC'd) + private int _estimatedCount; + + // Location of the last item in _items + private int _lastItemIndex; + + // Indicates that the collection is currently being notified (and, therefore, about to be cleared) + private volatile bool _isNotifying; + #endregion private struct CollectionEntry { - private int _tag; // information about the reference - private WeakReference _weak; // the reference itself. + private int _refInfo; // information about the reference + private WeakReference _weakReference; // the reference itself. - public void NewTarget(int tag, object target) + public void SetNewTarget(int refInfo, object target) { Debug.Assert(!TryGetTarget(out object _), "Entry already has a valid target"); - Debug.Assert(tag != 0, "Bad tag"); + Debug.Assert(refInfo != 0, "Bad reference info"); Debug.Assert(target != null, "Invalid target"); - if (_weak == null) + if (_weakReference == null) { - _weak = new WeakReference(target, false); + _weakReference = new WeakReference(target, false); } else { - _weak.SetTarget(target); + _weakReference.SetTarget(target); } - _tag = tag; + _refInfo = refInfo; } public void RemoveTarget() { - _tag = 0; - _weak.SetTarget(null); + _refInfo = 0; + _weakReference.SetTarget(null); } - public int Tag => _tag; + public readonly int RefInfo => _refInfo; - public bool TryGetTarget(out object target) + public readonly bool TryGetTarget(out object target) { target = null; - return _tag != 0 && _weak.TryGetTarget(out target); + return _refInfo != 0 && _weakReference.TryGetTarget(out target); } } - private const int LockPollTime = 100; // Time to wait (in ms) between attempting to get the _itemLock - private const int DefaultCollectionSize = 20; // Default size for the collection, and the amount to grow every time the collection is full - private CollectionEntry[] _items; // The collection of items we are keeping track of - private readonly object _itemLock; // Used to synchronize access to the _items collection - private int _optimisticCount; // (#ItemsAdded - #ItemsRemoved) - This estimates the number of items that we *should* have (but doesn't take into account item targets being GC'd) - private int _lastItemIndex; // Location of the last item in _items - private volatile bool _isNotifying; // Indicates that the collection is currently being notified (and, therefore, about to be cleared) - protected DbReferenceCollection() { _items = new CollectionEntry[DefaultCollectionSize]; _itemLock = new object(); - _optimisticCount = 0; + _estimatedCount = 0; _lastItemIndex = 0; } - abstract public void Add(object value, int tag); + abstract public void Add(object value, int refInfo); - protected void AddItem(object value, int tag) + protected void AddItem(object value, int refInfo) { - Debug.Assert(null != value && 0 != tag, "AddItem with null value or 0 tag"); + Debug.Assert(value != null && 0 != refInfo, "AddItem with null value or 0 reference info"); bool itemAdded = false; lock (_itemLock) @@ -77,9 +93,9 @@ protected void AddItem(object value, int tag) // Try to find a free spot for (int i = 0; i <= _lastItemIndex; ++i) { - if (_items[i].Tag == 0) + if (_items[i].RefInfo == 0) { - _items[i].NewTarget(tag, value); + _items[i].SetNewTarget(refInfo, value); Debug.Assert(_items[i].TryGetTarget(out object _), "missing expected target"); itemAdded = true; break; @@ -90,7 +106,7 @@ protected void AddItem(object value, int tag) if ((!itemAdded) && (_lastItemIndex + 1 < _items.Length)) { _lastItemIndex++; - _items[_lastItemIndex].NewTarget(tag, value); + _items[_lastItemIndex].SetNewTarget(refInfo, value); itemAdded = true; } @@ -101,7 +117,7 @@ protected void AddItem(object value, int tag) { if (!_items[i].TryGetTarget(out object _)) { - _items[i].NewTarget(tag, value); + _items[i].SetNewTarget(refInfo, value); Debug.Assert(_items[i].TryGetTarget(out object _), "missing expected target"); itemAdded = true; break; @@ -114,14 +130,14 @@ protected void AddItem(object value, int tag) { Array.Resize(ref _items, _items.Length * 2); _lastItemIndex++; - _items[_lastItemIndex].NewTarget(tag, value); + _items[_lastItemIndex].SetNewTarget(refInfo, value); } - _optimisticCount++; + _estimatedCount++; } } - internal T FindItem(int tag, Func filterMethod) where T : class + internal T FindItem(int refInfo, Func filterMethod) where T : class { bool lockObtained = false; try @@ -129,13 +145,12 @@ internal T FindItem(int tag, Func filterMethod) where T : class TryEnterItemLock(ref lockObtained); if (lockObtained) { - if (_optimisticCount > 0) + if (_estimatedCount > 0) { - // Loop through the items for (int counter = 0; counter <= _lastItemIndex; counter++) { - // Check tag (should be easiest and quickest) - if (_items[counter].Tag == tag) + // Check reference info (should be easiest and quickest) + if (_items[counter].RefInfo == refInfo) { if (_items[counter].TryGetTarget(out object value)) { @@ -172,18 +187,18 @@ public void Notify(int message) _isNotifying = true; // Loop through each live item and notify it - if (_optimisticCount > 0) + if (_estimatedCount > 0) { for (int index = 0; index <= _lastItemIndex; ++index) { if (_items[index].TryGetTarget(out object value)) { - NotifyItem(message, _items[index].Tag, value); + NotifyItem(message, _items[index].RefInfo, value); _items[index].RemoveTarget(); } Debug.Assert(!_items[index].TryGetTarget(out object _), "Unexpected target after notifying"); } - _optimisticCount = 0; + _estimatedCount = 0; } // Shrink collection (if needed) @@ -205,7 +220,7 @@ public void Notify(int message) } } - abstract protected void NotifyItem(int message, int tag, object value); + abstract protected void NotifyItem(int message, int refInfo, object value); abstract public void Remove(object value); @@ -221,14 +236,14 @@ protected void RemoveItem(object value) if (lockObtained) { // Find the value, and then remove the target from our collection - if (_optimisticCount > 0) + if (_estimatedCount > 0) { for (int index = 0; index <= _lastItemIndex; ++index) { if (_items[index].TryGetTarget(out object target) && value == target) { _items[index].RemoveTarget(); - _optimisticCount--; + _estimatedCount--; break; } } @@ -262,4 +277,3 @@ private void ExitItemLockIfNeeded(bool lockObtained) } } } - From 74084b010eb0c4834476eade199f6e5e0307286b Mon Sep 17 00:00:00 2001 From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com> Date: Sat, 30 Mar 2024 03:24:58 +0530 Subject: [PATCH 15/53] Fixes UdtTestDb creating script (#2421) --- tools/testsql/createUdtTestDb.sql | Bin 200366 -> 200788 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tools/testsql/createUdtTestDb.sql b/tools/testsql/createUdtTestDb.sql index 5511f5a680c59982c58d5c8e188f06df16d7f86b..2f573faeb9db68689f84851d8d798cc7a33530dd 100644 GIT binary patch delta 206 zcmZ2Cm*>g?o((dr?!^ol4EYS@3SD5U{sw|3K<|B)-YBA89BA`jhKw1H4Rw|HH3Kl70sDzqq gFxir|RGxs!$=R&I%_gkvCajD=%(UHvmAQ%&0LH8*JOBUy delta 30 kcmcbzfM?xYo((drlM~oDnoqH{pJHPKVy5k<*qFOG0kxe9%K!iX From 740069d657d8e201973fc7b650965a830280abc1 Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Mon, 1 Apr 2024 07:42:04 -0700 Subject: [PATCH 16/53] Fix | Suppress CodeQL X509RevocationMode warning. (#2432) --- .../Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index eba8b856a2..efd18d78c6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -252,6 +252,10 @@ private bool VerifyHealthReportAgainstRootCertificate(X509Certificate2Collection chain.ChainPolicy.ExtraStore.Add(cert); } + // An Always Encrypted-enabled driver doesn't verify an expiration date or a certificate authority chain. + // A certificate is simply used as a key pair consisting of a public and private key. This is by design. + + // CodeQL [SM00395] By design. Always Encrypted certificates should not be checked. chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; if (!chain.Build(healthReportCert)) From 908f563699989d8d118c5cc3d330e59a45e9428d Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Mon, 1 Apr 2024 07:47:03 -0700 Subject: [PATCH 17/53] Fix | Suppress CodeQL warning for usage of deprecated Ssl2. (#2428) --- .../Microsoft/Data/SqlClient/TdsParserHelperClasses.cs | 10 ++++++---- .../Data/SqlClient/TdsParserStateObjectNative.cs | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs index 9a6ceb7054..d0431e1901 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs @@ -764,13 +764,14 @@ private static string ToFriendlyName(this SslProtocols protocol) { name = "TLS 1.0"; } -#pragma warning disable CS0618 // Type or member is obsolete: SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 else if ((protocol & SslProtocols.Ssl3) == SslProtocols.Ssl3) { name = "SSL 3.0"; } else if ((protocol & SslProtocols.Ssl2) == SslProtocols.Ssl2) -#pragma warning restore CS0618 // Type or member is obsolete: SSL is depricated +#pragma warning restore CS0618, CA5397 { name = "SSL 2.0"; } @@ -790,9 +791,10 @@ private static string ToFriendlyName(this SslProtocols protocol) public static string GetProtocolWarning(this SslProtocols protocol) { string message = string.Empty; -#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 if ((protocol & (SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11)) != SslProtocols.None) -#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated +#pragma warning restore CS0618, CA5397 { message = StringsHelper.Format(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index 59776956a1..80fd68d5d8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -427,13 +427,14 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_SERVER)) { -#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 protocolVersion = (int)SslProtocols.Ssl3; } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_SERVER)) { protocolVersion = (int)SslProtocols.Ssl2; -#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated +#pragma warning restore CS0618, CA5397 } else //if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE)) { From 537eba862d6c2a6e8793cbf874515424df2e8bab Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:06:05 +0000 Subject: [PATCH 18/53] Doc | update a sample description in SqlConnection (#2440) --- doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml index 7833db6f4a..8c4e2f4607 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml @@ -51,7 +51,7 @@ using (SqlConnection connection = new SqlConnection(connectionString)) ## Examples - The following example creates a and a . The is opened and set as the for the . The example then calls . To accomplish this, the is passed a connection string and a query string that is a Transact-SQL INSERT statement. The connection is closed automatically when the code exits the using block. + The following example creates a and a . The is opened and set as the for the . The example then calls . To accomplish this, the is passed a SqlConnection and a query string that is a Transact-SQL INSERT statement. The connection is closed automatically when the code exits the using block. [!code-csharp[SqlCommand_ExecuteNonQuery Example#1](~/../sqlclient/doc/samples/SqlCommand_ExecuteNonQuery.cs#1)] From 4778b8760dfc83037e259e5f79845b21ac844c7d Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Thu, 4 Apr 2024 01:02:40 +0000 Subject: [PATCH 19/53] Moved NuGet.config to the root (#2443) --- src/NuGet.config => NuGet.config | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/NuGet.config => NuGet.config (100%) diff --git a/src/NuGet.config b/NuGet.config similarity index 100% rename from src/NuGet.config rename to NuGet.config From 226b83ec0f94e2ea00834c0127886ca97a517d2d Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Thu, 4 Apr 2024 16:19:50 +0000 Subject: [PATCH 20/53] Merged PR 4462: eng | Fix pipeline netfx build change Addressing the failure on [dotnet-sqlclient-Official](https://dev.azure.com/SqlClientDrivers/ADO.Net/_build/results?buildId=84259&view=logs&j=a59e3b7b-7df8-53a3-7568-e4c5ffd2c23d&t=fa94fa55-e846-59ba-ffea-8e9b3df3ad3a) --- .../common/templates/jobs/build-signed-package-job.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml index 3244a9a0dd..8c2d41b387 100644 --- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml @@ -45,7 +45,7 @@ jobs: md $software\win\netstandard2.0 md $software\win\netstandard2.1 - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\Microsoft.Data.SqlClient.dll" "$software\win\net46" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\net462\Microsoft.Data.SqlClient.dll" "$software\win\net46" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.dll" "$software\win\net6.0" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.dll" "$software\win\net8.0" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.dll" "$software\win\netstandard2.0" -recurse @@ -60,7 +60,7 @@ jobs: md $symbols\win\netstandard2.0 md $symbols\win\netstandard2.1 - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\Microsoft.Data.SqlClient.pdb" "$symbols\win\net46" -recurse + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\net462\Microsoft.Data.SqlClient.pdb" "$symbols\win\net46" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net6.0" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net8.0" -recurse Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\netstandard2.0" -recurse From bc2a83414804ffe6f21f6778df73cfc6367cd95e Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Thu, 4 Apr 2024 16:32:45 -0700 Subject: [PATCH 21/53] Consolidate SSPI context generation to single abstraction (#2255) * Abstract the SSPI context generation This change introduces SSPIContextProvider that can generate payloads for SSPI. Specifically, this change plumbs the current SSPI context generation into this object, while later changes will continue to update the shape to be a more general purpose, public API. --- .../src/Microsoft.Data.SqlClient.csproj | 15 + .../Data/SqlClient/TdsParser.Windows.cs | 34 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 258 +-------------- .../SqlClient/TdsParserStateObject.netcore.cs | 7 +- .../SqlClient/TdsParserStateObjectManaged.cs | 39 +-- .../SqlClient/TdsParserStateObjectNative.cs | 9 +- .../netfx/src/Microsoft.Data.SqlClient.csproj | 17 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 312 +----------------- .../SqlClient/TdsParserStateObject.netfx.cs | 4 +- .../SSPI/ManagedSSPIContextProvider.cs | 23 ++ .../SSPI/NativeSSPIContextProvider.cs | 68 ++++ .../SSPI/NegotiateSSPIContextProvider.cs | 28 ++ .../SqlClient/SSPI/SSPIContextProvider.cs | 56 ++++ .../src/Microsoft/Data/SqlClient/TdsParser.cs | 265 +++++++++++++++ 14 files changed, 519 insertions(+), 616 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 48ab208ceb..f2827967b1 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -519,6 +519,18 @@ Common\System\Diagnostics\CodeAnalysis.cs + + Microsoft\Data\SqlClient\SSPI\ManagedSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\NegotiateSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\SSPIContextProvider.cs + + + Microsoft\Data\SqlClient\TdsParser.cs + Microsoft\Data\ProviderBase\DbReferenceCollection.cs @@ -771,6 +783,9 @@ Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs + + Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs index f7a0363f27..7f15666951 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs @@ -10,8 +10,6 @@ namespace Microsoft.Data.SqlClient { internal sealed partial class TdsParser { - private static volatile bool s_fSSPILoaded = false; // bool to indicate whether library has been loaded - internal void PostReadAsyncForMars() { if (TdsParserStateObjectFactory.UseManagedSNI) @@ -43,37 +41,7 @@ internal void PostReadAsyncForMars() _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); ThrowExceptionAndWarning(_physicalStateObj); } - } - - private void LoadSSPILibrary() - { - if (TdsParserStateObjectFactory.UseManagedSNI) - return; - // Outer check so we don't acquire lock once it's loaded. - if (!s_fSSPILoaded) - { - lock (s_tdsParserLock) - { - // re-check inside lock - if (!s_fSSPILoaded) - { - // use local for ref param to defer setting s_maxSSPILength until we know the call succeeded. - uint maxLength = 0; - - if (0 != SNINativeMethodWrapper.SNISecInitPackage(ref maxLength)) - SSPIError(SQLMessage.SSPIInitializeError(), TdsEnums.INIT_SSPI_PACKAGE); - - s_maxSSPILength = maxLength; - s_fSSPILoaded = true; - } - } - } - - if (s_maxSSPILength > int.MaxValue) - { - throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 - } - } + } private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersion) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 7e04f6b9c5..4d731102fe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -55,6 +55,8 @@ internal static void Assert(string message) private static int _objectTypeCount; // EventSource counter private readonly SqlClientLogger _logger = new SqlClientLogger(); + private SSPIContextProvider _authenticationProvider; + internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount); internal int ObjectID => _objectID; @@ -146,16 +148,9 @@ internal static void Assert(string message) // NIC address caching private static byte[] s_nicAddress; // cache the NIC address from the registry - // SSPI variables - - private volatile static uint s_maxSSPILength = 0; // variable to hold max SSPI data size, keep for token from server - // textptr sequence private static readonly byte[] s_longDataHeader = { 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - private static object s_tdsParserLock = new object(); - - // XML metadata substitute sequence private static readonly byte[] s_xmlMetadataSubstituteSequence = { 0xe7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -422,11 +417,12 @@ internal void Connect( } _sniSpnBuffer = null; + _authenticationProvider = null; // AD Integrated behaves like Windows integrated when connecting to a non-fedAuth server if (integratedSecurity || authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { - LoadSSPILibrary(); + _authenticationProvider = _physicalStateObj.CreateSSPIContextProvider(); SqlClientEventSource.Log.TryTraceEvent("TdsParser.Connect | SEC | SSPI or Active Directory Authentication Library loaded for SQL Server based integrated authentication"); } @@ -472,6 +468,8 @@ internal void Connect( hostNameInCertificate, serverCertificateFilename); + _authenticationProvider?.Initialize(serverInfo, _physicalStateObj, this); + if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); @@ -569,6 +567,8 @@ internal void Connect( hostNameInCertificate, serverCertificateFilename); + _authenticationProvider?.Initialize(serverInfo, _physicalStateObj, this); + if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); @@ -1286,7 +1286,7 @@ private void FireInfoMessageEvent(SqlConnection connection, SqlCommand command, sqlErs.Add(error); - SqlException exc = SqlException.CreateException(sqlErs, serverVersion, _connHandler, innerException:null, batchCommand: command?.GetCurrentBatchCommand()); + SqlException exc = SqlException.CreateException(sqlErs, serverVersion, _connHandler, innerException: null, batchCommand: command?.GetCurrentBatchCommand()); bool notified; connection.OnInfoMessage(new SqlInfoMessageEventArgs(exc), out notified); @@ -4001,7 +4001,7 @@ internal bool TryProcessError(byte token, TdsParserStateObject stateObj, SqlComm { batchIndex = command.GetCurrentBatchIndex(); } - error = new SqlError(number, state, errorClass, _server, message, procedure, line,exception: null, batchIndex: batchIndex); + error = new SqlError(number, state, errorClass, _server, message, procedure, line, exception: null, batchIndex: batchIndex); return true; } @@ -5744,7 +5744,7 @@ private bool TryReadSqlStringValue(SqlBuffer value, byte type, int length, Encod s = ""; } } - + if (buffIsRented) { // do not use clearArray:true on the rented array because it can be massively larger @@ -8108,165 +8108,6 @@ internal int WriteFedAuthFeatureRequest(FederatedAuthenticationFeatureExtensionD return len; } - internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures, SessionData recoverySessionData, FederatedAuthenticationFeatureExtensionData fedAuthFeatureExtensionData, SqlConnectionEncryptOption encrypt) - { - _physicalStateObj.SetTimeoutSeconds(rec.timeout); - - Debug.Assert(recoverySessionData == null || (requestedFeatures & TdsEnums.FeatureExtension.SessionRecovery) != 0, "Recovery session data without session recovery feature request"); - Debug.Assert(TdsEnums.MAXLEN_HOSTNAME >= rec.hostName.Length, "_workstationId.Length exceeds the max length for this value"); - - Debug.Assert(!rec.useSSPI || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Cannot use both SSPI and FedAuth"); - Debug.Assert(fedAuthFeatureExtensionData == null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) != 0, "fedAuthFeatureExtensionData provided without fed auth feature request"); - Debug.Assert(fedAuthFeatureExtensionData != null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Fed Auth feature requested without specifying fedAuthFeatureExtensionData."); - - Debug.Assert(rec.userName == null || (rec.userName != null && TdsEnums.MAXLEN_CLIENTID >= rec.userName.Length), "_userID.Length exceeds the max length for this value"); - Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTID >= rec.credential.UserId.Length), "_credential.UserId.Length exceeds the max length for this value"); - - Debug.Assert(rec.password == null || (rec.password != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.password.Length), "_password.Length exceeds the max length for this value"); - Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.credential.Password.Length), "_credential.Password.Length exceeds the max length for this value"); - - Debug.Assert(rec.credential != null || rec.userName != null || rec.password != null, "cannot mix the new secure password system and the connection string based password"); - Debug.Assert(rec.newSecurePassword != null || rec.newPassword != null, "cannot have both new secure change password and string based change password"); - Debug.Assert(TdsEnums.MAXLEN_APPNAME >= rec.applicationName.Length, "_applicationName.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_SERVERNAME >= rec.serverName.Length, "_dataSource.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_LANGUAGE >= rec.language.Length, "_currentLanguage .Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_DATABASE >= rec.database.Length, "_initialCatalog.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_ATTACHDBFILE >= rec.attachDBFilename.Length, "_attachDBFileName.Length exceeds the max length for this value"); - - Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); - _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.LoginBegin); - _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ProcessConnectionAuth); - - // get the password up front to use in sspi logic below - byte[] encryptedPassword = null; - byte[] encryptedChangePassword = null; - int encryptedPasswordLengthInBytes; - int encryptedChangePasswordLengthInBytes; - bool useFeatureExt = (requestedFeatures != TdsEnums.FeatureExtension.None); - - string userName; - - if (rec.credential != null) - { - userName = rec.credential.UserId; - encryptedPasswordLengthInBytes = rec.credential.Password.Length * 2; - } - else - { - userName = rec.userName; - encryptedPassword = TdsParserStaticMethods.ObfuscatePassword(rec.password); - encryptedPasswordLengthInBytes = encryptedPassword.Length; // password in clear text is already encrypted and its length is in byte - } - - if (rec.newSecurePassword != null) - { - encryptedChangePasswordLengthInBytes = rec.newSecurePassword.Length * 2; - } - else - { - encryptedChangePassword = TdsParserStaticMethods.ObfuscatePassword(rec.newPassword); - encryptedChangePasswordLengthInBytes = encryptedChangePassword.Length; - } - - // set the message type - _physicalStateObj._outputMessageType = TdsEnums.MT_LOGIN7; - - // length in bytes - int length = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; - - string clientInterfaceName = TdsEnums.SQL_PROVIDER_NAME; - Debug.Assert(TdsEnums.MAXLEN_CLIENTINTERFACE >= clientInterfaceName.Length, "cchCltIntName can specify at most 128 unicode characters. See Tds spec"); - - // add up variable-len portions (multiply by 2 for byte len of char strings) - // - checked - { - length += (rec.hostName.Length + rec.applicationName.Length + - rec.serverName.Length + clientInterfaceName.Length + - rec.language.Length + rec.database.Length + - rec.attachDBFilename.Length) * 2; - if (useFeatureExt) - { - length += 4; - } - } - - // allocate memory for SSPI variables - byte[] rentedSSPIBuff = null; - byte[] outSSPIBuff = null; - uint outSSPILength = 0; - - // only add lengths of password and username if not using SSPI or requesting federated authentication info - if (!rec.useSSPI && !(_connHandler._federatedAuthenticationInfoRequested || _connHandler._federatedAuthenticationRequested)) - { - checked - { - length += (userName.Length * 2) + encryptedPasswordLengthInBytes - + encryptedChangePasswordLengthInBytes; - } - } - else - { - if (rec.useSSPI) - { - // now allocate proper length of buffer, and set length - rentedSSPIBuff = ArrayPool.Shared.Rent((int)s_maxSSPILength); - outSSPIBuff = rentedSSPIBuff; - outSSPILength = s_maxSSPILength; - - // Call helper function for SSPI data and actual length. - // Since we don't have SSPI data from the server, send null for the - // byte[] buffer and 0 for the int length. - Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'"); - _physicalStateObj.SniContext = SniContext.Snix_LoginSspi; - - SSPIData(null, 0, ref outSSPIBuff, ref outSSPILength); - - if (outSSPILength > int.MaxValue) - { - throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 - } - _physicalStateObj.SniContext = SniContext.Snix_Login; - - checked - { - length += (int)outSSPILength; - } - } - } - - int feOffset = length; - // calculate and reserve the required bytes for the featureEx - length = ApplyFeatureExData(requestedFeatures, recoverySessionData, fedAuthFeatureExtensionData, useFeatureExt, length); - - WriteLoginData(rec, - requestedFeatures, - recoverySessionData, - fedAuthFeatureExtensionData, - encrypt, - encryptedPassword, - encryptedChangePassword, - encryptedPasswordLengthInBytes, - encryptedChangePasswordLengthInBytes, - useFeatureExt, - userName, - length, - feOffset, - clientInterfaceName, - outSSPIBuff, - outSSPILength); - - if (rentedSSPIBuff != null) - { - ArrayPool.Shared.Return(rentedSSPIBuff, clearArray: true); - } - - _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); - _physicalStateObj.ResetSecurePasswordsInformation(); - _physicalStateObj.HasPendingData = true; - _physicalStateObj._messageStatus = 0; - }// tdsLogin - private void WriteLoginData(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures, SessionData recoverySessionData, @@ -8617,81 +8458,6 @@ internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) _connHandler._federatedAuthenticationRequested = true; } - private void SSPIData(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength) - { - if (TdsParserStateObjectFactory.UseManagedSNI) - { - try - { - _physicalStateObj.GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer); - } - catch (Exception e) - { - SSPIError(e.Message + Environment.NewLine + e.StackTrace, TdsEnums.GEN_CLIENT_CONTEXT); - } - } - else - { - if (receivedBuff == null) - { - // if we do not have SSPI data coming from server, send over 0's for pointer and length - receivedLength = 0; - } - - // we need to respond to the server's message with SSPI data - if (0 != _physicalStateObj.GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer)) - { - SSPIError(SQLMessage.SSPIGenerateError(), TdsEnums.GEN_CLIENT_CONTEXT); - } - } - } - - private void ProcessSSPI(int receivedLength) - { - SniContext outerContext = _physicalStateObj.SniContext; - _physicalStateObj.SniContext = SniContext.Snix_ProcessSspi; - // allocate received buffer based on length from SSPI message - byte[] receivedBuff = ArrayPool.Shared.Rent(receivedLength); - - // read SSPI data received from server - Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); - bool result = _physicalStateObj.TryReadByteArray(receivedBuff, receivedLength); - if (!result) - { - throw SQL.SynchronousCallMayNotPend(); - } - - // allocate send buffer and initialize length - byte[] rentedSendBuff = ArrayPool.Shared.Rent((int)s_maxSSPILength); - byte[] sendBuff = rentedSendBuff; - uint sendLength = s_maxSSPILength; - - // make call for SSPI data - SSPIData(receivedBuff, (uint)receivedLength, ref sendBuff, ref sendLength); - - // DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA! - _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0); - - ArrayPool.Shared.Return(rentedSendBuff, clearArray: true); - ArrayPool.Shared.Return(receivedBuff, clearArray: true); - - // set message type so server knows its a SSPI response - _physicalStateObj._outputMessageType = TdsEnums.MT_SSPI; - - // send to server - _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); - _physicalStateObj.SniContext = outerContext; - } - - private void SSPIError(string error, string procedure) - { - Debug.Assert(!string.IsNullOrEmpty(procedure), "TdsParser.SSPIError called with an empty or null procedure string"); - Debug.Assert(!string.IsNullOrEmpty(error), "TdsParser.SSPIError called with an empty or null error string"); - - _physicalStateObj.AddError(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, _server, error, procedure, 0)); - ThrowExceptionAndWarning(_physicalStateObj); - } - internal byte[] GetDTCAddress(int timeout, TdsParserStateObject stateObj) { // If this fails, the server will return a server error - Sameet Agarwal confirmed. @@ -9240,7 +9006,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout { // Throw an exception if ForceColumnEncryption is set on a parameter and the ColumnEncryption is not enabled on SqlConnection or SqlCommand if ( - !(cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.Enabled + !(cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.Enabled || (cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.UseConnectionSetting && cmd.Connection.IsColumnEncryptionSettingEnabled))) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs index b1bb4065c8..520367963d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs @@ -62,7 +62,7 @@ internal TdsParserStateObject(TdsParser parser, TdsParserStateObject physicalCon AddError(parser.ProcessSNIError(this)); ThrowExceptionAndWarning(); } - + // we post a callback that represents the call to dispose; once the // object is disposed, the next callback will cause the GC Handle to // be released. @@ -75,6 +75,7 @@ internal TdsParserStateObject(TdsParser parser, TdsParserStateObject physicalCon //////////////// internal abstract uint DisableSsl(); + internal abstract SSPIContextProvider CreateSSPIContextProvider(); internal abstract uint EnableMars(ref uint info); @@ -83,6 +84,8 @@ internal abstract uint Status get; } + internal abstract Guid? SessionId { get; } + internal abstract SessionHandle SessionHandle { get; @@ -236,8 +239,6 @@ internal abstract void CreatePhysicalSNIHandle( protected abstract void RemovePacketFromPendingList(PacketHandle pointer); - internal abstract uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); - internal int DecrementPendingCallbacks(bool release) { int remaining = Interlocked.Decrement(ref _pendingCallbacks); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs index 1e0141dd58..7d879ae4d5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -21,11 +21,7 @@ internal sealed class TdsParserStateObjectManaged : TdsParserStateObject { private SNIMarsConnection? _marsConnection; private SNIHandle? _sessionHandle; -#if NET7_0_OR_GREATER - private NegotiateAuthentication? _negotiateAuth = null; -#else - private SspiClientContextStatus? _sspiClientContextStatus; -#endif + public TdsParserStateObjectManaged(TdsParser parser) : base(parser) { } internal TdsParserStateObjectManaged(TdsParser parser, TdsParserStateObject physicalConnection, bool async) : @@ -232,6 +228,8 @@ internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint protected override PacketHandle EmptyReadPacket => PacketHandle.FromManagedPacket(null); + internal override Guid? SessionId => _sessionHandle?.ConnectionId; + internal override bool IsPacketEmpty(PacketHandle packet) => packet.ManagedPacket == null; internal override void ReleasePacket(PacketHandle syncReadPacket) @@ -389,30 +387,6 @@ internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize) return TdsEnums.SNI_SUCCESS; } - internal override uint GenerateSspiClientContext(byte[] receivedBuff, - uint receivedLength, - ref byte[] sendBuff, - ref uint sendLength, - byte[][] _sniSpnBuffer) - { -#if NET7_0_OR_GREATER - _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) }); - sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!; - SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _sessionHandle?.ConnectionId, statusCode); - if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) - { - throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode); - } -#else - _sspiClientContextStatus ??= new SspiClientContextStatus(); - - SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); - SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _sessionHandle?.ConnectionId); -#endif - sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); - return 0; - } - internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) { protocolVersion = GetSessionSNIHandleHandleOrThrow().ProtocolVersion; @@ -432,5 +406,12 @@ private SNIHandle GetSessionSNIHandleHandleOrThrow() [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] // this forces the exception throwing code not to be inlined for performance private void ThrowClosedConnection() => throw ADP.ClosedConnectionError(); + + internal override SSPIContextProvider CreateSSPIContextProvider() +#if NET7_0_OR_GREATER + => new NegotiateSSPIContextProvider(); +#else + => new ManagedSSPIContextProvider(); +#endif } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index 80fd68d5d8..6f26250072 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -167,7 +167,7 @@ internal override void CreatePhysicalSNIHandle( byte[] srvSPN = Encoding.Unicode.GetBytes(serverSPN); Trace.Assert(srvSPN.Length <= SNINativeMethodWrapper.SniMaxComposedSpnLength, "Length of the provided SPN exceeded the buffer size."); spnBuffer[0] = srvSPN; - SqlClientEventSource.Log.TryTraceEvent("<{0}.{1}|SEC> Server SPN `{2}` from the connection string is used.",nameof(TdsParserStateObjectNative), nameof(CreatePhysicalSNIHandle), serverSPN); + SqlClientEventSource.Log.TryTraceEvent("<{0}.{1}|SEC> Server SPN `{2}` from the connection string is used.", nameof(TdsParserStateObjectNative), nameof(CreatePhysicalSNIHandle), serverSPN); } else { @@ -272,6 +272,8 @@ internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint protected override PacketHandle EmptyReadPacket => PacketHandle.FromNativePointer(default); + internal override Guid? SessionId => default; + internal override bool IsPacketEmpty(PacketHandle readPacket) { Debug.Assert(readPacket.Type == PacketHandle.NativePointerType || readPacket.Type == 0, "unexpected packet type when requiring NativePointer"); @@ -398,9 +400,6 @@ internal override uint EnableSsl(ref uint info, bool tlsFirst, string serverCert internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize) => SNINativeMethodWrapper.SNISetInfo(Handle, SNINativeMethodWrapper.QTypes.SNI_QUERY_CONN_BUFSIZE, ref unsignedPacketSize); - internal override uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) - => SNINativeMethodWrapper.SNISecGenClientContext(Handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer[0]); - internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) { uint returnValue = SNINativeMethodWrapper.SNIWaitForSSLHandshakeToComplete(Handle, GetTimeoutRemaining(), out uint nativeProtocolVersion); @@ -452,6 +451,8 @@ internal override void DisposePacketCache() } } + internal override SSPIContextProvider CreateSSPIContextProvider() => new NativeSSPIContextProvider(); + internal sealed class WritePacketCache : IDisposable { private bool _disposed; 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 4dc1ae6393..2dd8d69b08 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -153,6 +153,21 @@ Microsoft\Data\ProviderBase\TimeoutTimer.cs + + Microsoft\Data\SqlClient\SSPI\ManagedSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\NegotiateSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\SSPIContextProvider.cs + + + Microsoft\Data\SqlClient\TdsParser.cs + Microsoft\Data\Sql\SqlDataSourceEnumerator.cs @@ -751,4 +766,4 @@ - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 7a9bbfdfd3..6d49a79051 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -28,14 +28,15 @@ namespace Microsoft.Data.SqlClient { - // The TdsParser Object controls reading/writing to the netlib, parsing the tds, // and surfacing objects to the user. - sealed internal class TdsParser + sealed internal partial class TdsParser { private static int _objectTypeCount; // EventSource Counter private readonly SqlClientLogger _logger = new SqlClientLogger(); + private SSPIContextProvider _authenticationProvider; + internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); static Task completedTask; @@ -236,16 +237,9 @@ internal static void Assert(string message) // NIC address caching private static byte[] s_nicAddress; // cache the NIC address from the registry - // SSPI variables - private static bool s_fSSPILoaded = false; // bool to indicate whether library has been loaded - - private volatile static UInt32 s_maxSSPILength = 0; // variable to hold max SSPI data size, keep for token from server - // textptr sequence private static readonly byte[] s_longDataHeader = { 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - private static object s_tdsParserLock = new object(); - // Various other statics private const int ATTENTION_TIMEOUT = 5000; // internal attention timeout, in ticks @@ -549,7 +543,8 @@ internal void Connect(ServerInfo serverInfo, // AD Integrated behaves like Windows integrated when connecting to a non-fedAuth server if (integratedSecurity || authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { - LoadSSPILibrary(); + _authenticationProvider = _physicalStateObj.CreateSSPIContextProvider(); + if (!string.IsNullOrEmpty(serverInfo.ServerSPN)) { // Native SNI requires the Unicode encoding and any other encoding like UTF8 breaks the code. @@ -567,7 +562,9 @@ internal void Connect(ServerInfo serverInfo, } else { + _authenticationProvider = null; _sniSpnBuffer = null; + switch (authType) { case SqlAuthenticationMethod.ActiveDirectoryPassword: @@ -655,6 +652,8 @@ internal void Connect(ServerInfo serverInfo, FQDNforDNSCache, hostNameInCertificate); + _authenticationProvider?.Initialize(serverInfo, _physicalStateObj, this); + if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); @@ -760,6 +759,8 @@ internal void Connect(ServerInfo serverInfo, serverInfo.ResolvedServerName, hostNameInCertificate); + _authenticationProvider?.Initialize(serverInfo, _physicalStateObj, this); + if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); @@ -2547,7 +2548,7 @@ internal bool TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataRead (error.Class <= TdsEnums.MAX_USER_CORRECTABLE_ERROR_CLASS)) { // Fire SqlInfoMessage here - FireInfoMessageEvent(connection,cmdHandler, stateObj, error); + FireInfoMessageEvent(connection, cmdHandler, stateObj, error); } else { @@ -8904,205 +8905,6 @@ internal int WriteFedAuthFeatureRequest(FederatedAuthenticationFeatureExtensionD return len; } - internal void TdsLogin(SqlLogin rec, - TdsEnums.FeatureExtension requestedFeatures, - SessionData recoverySessionData, - FederatedAuthenticationFeatureExtensionData fedAuthFeatureExtensionData, - SqlClientOriginalNetworkAddressInfo originalNetworkAddressInfo, - SqlConnectionEncryptOption encrypt) - { - _physicalStateObj.SetTimeoutSeconds(rec.timeout); - - Debug.Assert(recoverySessionData == null || (requestedFeatures & TdsEnums.FeatureExtension.SessionRecovery) != 0, "Recovery session data without session recovery feature request"); - Debug.Assert(TdsEnums.MAXLEN_HOSTNAME >= rec.hostName.Length, "_workstationId.Length exceeds the max length for this value"); - - Debug.Assert(!(rec.useSSPI && _connHandler._fedAuthRequired), "Cannot use SSPI when server has responded 0x01 for FedAuthRequired PreLogin Option."); - Debug.Assert(!rec.useSSPI || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Cannot use both SSPI and FedAuth"); - Debug.Assert(fedAuthFeatureExtensionData == null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) != 0, "fedAuthFeatureExtensionData provided without fed auth feature request"); - Debug.Assert(fedAuthFeatureExtensionData != null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Fed Auth feature requested without specifying fedAuthFeatureExtensionData."); - - Debug.Assert(rec.userName == null || (rec.userName != null && TdsEnums.MAXLEN_CLIENTID >= rec.userName.Length), "_userID.Length exceeds the max length for this value"); - Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTID >= rec.credential.UserId.Length), "_credential.UserId.Length exceeds the max length for this value"); - - Debug.Assert(rec.password == null || (rec.password != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.password.Length), "_password.Length exceeds the max length for this value"); - Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.credential.Password.Length), "_credential.Password.Length exceeds the max length for this value"); - - Debug.Assert(rec.credential != null || rec.userName != null || rec.password != null, "cannot mix the new secure password system and the connection string based password"); - Debug.Assert(rec.newSecurePassword != null || rec.newPassword != null, "cannot have both new secure change password and string based change password"); - Debug.Assert(TdsEnums.MAXLEN_APPNAME >= rec.applicationName.Length, "_applicationName.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_SERVERNAME >= rec.serverName.Length, "_dataSource.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_LANGUAGE >= rec.language.Length, "_currentLanguage .Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_DATABASE >= rec.database.Length, "_initialCatalog.Length exceeds the max length for this value"); - Debug.Assert(TdsEnums.MAXLEN_ATTACHDBFILE >= rec.attachDBFilename.Length, "_attachDBFileName.Length exceeds the max length for this value"); - - Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); - _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.LoginBegin); - _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ProcessConnectionAuth); - - // Add CTAIP Provider - // - if (originalNetworkAddressInfo != null) - { - SNINativeMethodWrapper.CTAIPProviderInfo cauthInfo = new SNINativeMethodWrapper.CTAIPProviderInfo(); - cauthInfo.originalNetworkAddress = originalNetworkAddressInfo.Address.GetAddressBytes(); - cauthInfo.fromDataSecurityProxy = originalNetworkAddressInfo.IsFromDataSecurityProxy; - - UInt32 error = SNINativeMethodWrapper.SNIAddProvider(_physicalStateObj.Handle, SNINativeMethodWrapper.ProviderEnum.CTAIP_PROV, cauthInfo); - if (error != TdsEnums.SNI_SUCCESS) - { - _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); - ThrowExceptionAndWarning(_physicalStateObj); - } - - try - { } // EmptyTry/Finally to avoid FXCop violation - finally - { - _physicalStateObj.ClearAllWritePackets(); - } - } - - // get the password up front to use in sspi logic below - byte[] encryptedPassword = null; - byte[] encryptedChangePassword = null; - int encryptedPasswordLengthInBytes; - int encryptedChangePasswordLengthInBytes; - bool useFeatureExt = (requestedFeatures != TdsEnums.FeatureExtension.None); - - string userName; - - if (rec.credential != null) - { - userName = rec.credential.UserId; - encryptedPasswordLengthInBytes = rec.credential.Password.Length * 2; - } - else - { - userName = rec.userName; - encryptedPassword = TdsParserStaticMethods.ObfuscatePassword(rec.password); - encryptedPasswordLengthInBytes = encryptedPassword.Length; // password in clear text is already encrypted and its length is in byte - } - - if (rec.newSecurePassword != null) - { - encryptedChangePasswordLengthInBytes = rec.newSecurePassword.Length * 2; - } - else - { - encryptedChangePassword = TdsParserStaticMethods.ObfuscatePassword(rec.newPassword); - encryptedChangePasswordLengthInBytes = encryptedChangePassword.Length; - } - - - // set the message type - _physicalStateObj._outputMessageType = TdsEnums.MT_LOGIN7; - - // length in bytes - int length = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; - - string clientInterfaceName = TdsEnums.SQL_PROVIDER_NAME; - Debug.Assert(TdsEnums.MAXLEN_CLIENTINTERFACE >= clientInterfaceName.Length, "cchCltIntName can specify at most 128 unicode characters. See Tds spec"); - - // add up variable-len portions (multiply by 2 for byte len of char strings) - // - checked - { - length += (rec.hostName.Length + rec.applicationName.Length + - rec.serverName.Length + clientInterfaceName.Length + - rec.language.Length + rec.database.Length + - rec.attachDBFilename.Length) * 2; - if (useFeatureExt) - { - length += 4; - } - } - - // allocate memory for SSPI variables - byte[] outSSPIBuff = null; - UInt32 outSSPILength = 0; - - // only add lengths of password and username if not using SSPI or requesting federated authentication info - if (!rec.useSSPI && !(_connHandler._federatedAuthenticationInfoRequested || _connHandler._federatedAuthenticationRequested)) - { - checked - { - length += (userName.Length * 2) + encryptedPasswordLengthInBytes - + encryptedChangePasswordLengthInBytes; - } - } - else - { - if (rec.useSSPI) - { - // now allocate proper length of buffer, and set length - outSSPIBuff = new byte[s_maxSSPILength]; - outSSPILength = s_maxSSPILength; - - // Call helper function for SSPI data and actual length. - // Since we don't have SSPI data from the server, send null for the - // byte[] buffer and 0 for the int length. - Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'"); - _physicalStateObj.SniContext = SniContext.Snix_LoginSspi; - SSPIData(null, 0, outSSPIBuff, ref outSSPILength); - if (outSSPILength > int.MaxValue) - { - throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 - } - _physicalStateObj.SniContext = SniContext.Snix_Login; - - checked - { - length += (int)outSSPILength; - } - } - } - - int feOffset = length; - // calculate and reserve the required bytes for the featureEx - length = ApplyFeatureExData(requestedFeatures, recoverySessionData, fedAuthFeatureExtensionData, useFeatureExt, length); - - WriteLoginData(rec, - requestedFeatures, - recoverySessionData, - fedAuthFeatureExtensionData, - encrypt, - encryptedPassword, - encryptedChangePassword, - encryptedPasswordLengthInBytes, - encryptedChangePasswordLengthInBytes, - useFeatureExt, - userName, - length, - feOffset, - clientInterfaceName, - outSSPIBuff, - outSSPILength); - - _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); - _physicalStateObj.ResetSecurePasswordsInformation(); // Password information is needed only from Login process; done with writing login packet and should clear information - _physicalStateObj.HasPendingData = true; - _physicalStateObj._messageStatus = 0; - - // Remvove CTAIP Provider after login record is sent. - // - if (originalNetworkAddressInfo != null) - { - UInt32 error = SNINativeMethodWrapper.SNIRemoveProvider(_physicalStateObj.Handle, SNINativeMethodWrapper.ProviderEnum.CTAIP_PROV); - if (error != TdsEnums.SNI_SUCCESS) - { - _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); - ThrowExceptionAndWarning(_physicalStateObj); - } - - try - { } // EmptyTry/Finally to avoid FXCop violation - finally - { - _physicalStateObj.ClearAllWritePackets(); - } - } - }// tdsLogin - private void WriteLoginData(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures, SessionData recoverySessionData, @@ -9472,94 +9274,6 @@ internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) _connHandler._federatedAuthenticationRequested = true; } - private void SSPIData(byte[] receivedBuff, UInt32 receivedLength, byte[] sendBuff, ref UInt32 sendLength) - { - SNISSPIData(receivedBuff, receivedLength, sendBuff, ref sendLength); - } - - private void SNISSPIData(byte[] receivedBuff, UInt32 receivedLength, byte[] sendBuff, ref UInt32 sendLength) - { - if (receivedBuff == null) - { - // we do not have SSPI data coming from server, so send over 0's for pointer and length - receivedLength = 0; - } - // we need to respond to the server's message with SSPI data - if (0 != SNINativeMethodWrapper.SNISecGenClientContext(_physicalStateObj.Handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer)) - { - SSPIError(SQLMessage.SSPIGenerateError(), TdsEnums.GEN_CLIENT_CONTEXT); - } - } - - - private void ProcessSSPI(int receivedLength) - { - SniContext outerContext = _physicalStateObj.SniContext; - _physicalStateObj.SniContext = SniContext.Snix_ProcessSspi; - // allocate received buffer based on length from SSPI message - byte[] receivedBuff = new byte[receivedLength]; - - // read SSPI data received from server - Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); - bool result = _physicalStateObj.TryReadByteArray(receivedBuff, receivedLength); - if (!result) - { throw SQL.SynchronousCallMayNotPend(); } - - // allocate send buffer and initialize length - byte[] sendBuff = new byte[s_maxSSPILength]; - UInt32 sendLength = s_maxSSPILength; - - // make call for SSPI data - SSPIData(receivedBuff, (UInt32)receivedLength, sendBuff, ref sendLength); - - // DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA! - _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0); - - // set message type so server knows its a SSPI response - _physicalStateObj._outputMessageType = TdsEnums.MT_SSPI; - - // send to server - _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); - _physicalStateObj.SniContext = outerContext; - } - - private void SSPIError(string error, string procedure) - { - Debug.Assert(!ADP.IsEmpty(procedure), "TdsParser.SSPIError called with an empty or null procedure string"); - Debug.Assert(!ADP.IsEmpty(error), "TdsParser.SSPIError called with an empty or null error string"); - - _physicalStateObj.AddError(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, _server, error, procedure, 0)); - ThrowExceptionAndWarning(_physicalStateObj); - } - - private void LoadSSPILibrary() - { - // Outer check so we don't acquire lock once once it's loaded. - if (!s_fSSPILoaded) - { - lock (s_tdsParserLock) - { - // re-check inside lock - if (!s_fSSPILoaded) - { - // use local for ref param to defer setting s_maxSSPILength until we know the call succeeded. - UInt32 maxLength = 0; - if (0 != SNINativeMethodWrapper.SNISecInitPackage(ref maxLength)) - SSPIError(SQLMessage.SSPIInitializeError(), TdsEnums.INIT_SSPI_PACKAGE); - - s_maxSSPILength = maxLength; - s_fSSPILoaded = true; - - } - } - } - - if (s_maxSSPILength > Int32.MaxValue) - { - throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 - } - } - internal byte[] GetDTCAddress(int timeout, TdsParserStateObject stateObj) { // If this fails, the server will return a server error - Sameet Agarwal confirmed. @@ -10123,7 +9837,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout { // Throw an exception if ForceColumnEncryption is set on a parameter and the ColumnEncryption is not enabled on SqlConnection or SqlCommand if ( - !(cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.Enabled + !(cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.Enabled || (cmd.ColumnEncryptionSetting == SqlCommandColumnEncryptionSetting.UseConnectionSetting && cmd.Connection.IsColumnEncryptionSettingEnabled)) ) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs index 5d4a332665..9ce3c4ec11 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs @@ -100,6 +100,8 @@ internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bo _lastSuccessfulIOTimer = parser._physicalStateObj._lastSuccessfulIOTimer; } + internal SSPIContextProvider CreateSSPIContextProvider() => new NativeSSPIContextProvider(); + //////////////// // Properties // //////////////// @@ -110,7 +112,7 @@ internal SNIHandle Handle return _sessionHandle; } } - + internal uint Status { get diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs new file mode 100644 index 0000000000..25fb2cadae --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -0,0 +1,23 @@ +#if !NETFRAMEWORK && !NET7_0_OR_GREATER + +using Microsoft.Data.SqlClient.SNI; + +#nullable enable + +namespace Microsoft.Data.SqlClient +{ + internal sealed class ManagedSSPIContextProvider : SSPIContextProvider + { + private SspiClientContextStatus? _sspiClientContextStatus; + + internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + { + _sspiClientContextStatus ??= new SspiClientContextStatus(); + + SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _physicalStateObj.SessionId); + sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); + } + } +} +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs new file mode 100644 index 0000000000..718608d136 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs @@ -0,0 +1,68 @@ +using System; +using System.Diagnostics; + +#nullable enable + +namespace Microsoft.Data.SqlClient +{ + internal sealed class NativeSSPIContextProvider : SSPIContextProvider + { + private static readonly object s_tdsParserLock = new(); + + // bool to indicate whether library has been loaded + private static bool s_fSSPILoaded; + + // variable to hold max SSPI data size, keep for token from server + private volatile static uint s_maxSSPILength; + + internal override uint MaxSSPILength => s_maxSSPILength; + + private protected override void Initialize() + { + LoadSSPILibrary(); + } + + private void LoadSSPILibrary() + { + // Outer check so we don't acquire lock once it's loaded. + if (!s_fSSPILoaded) + { + lock (s_tdsParserLock) + { + // re-check inside lock + if (!s_fSSPILoaded) + { + // use local for ref param to defer setting s_maxSSPILength until we know the call succeeded. + uint maxLength = 0; + + if (0 != SNINativeMethodWrapper.SNISecInitPackage(ref maxLength)) + SSPIError(SQLMessage.SSPIInitializeError(), TdsEnums.INIT_SSPI_PACKAGE); + + s_maxSSPILength = maxLength; + s_fSSPILoaded = true; + } + } + } + + if (s_maxSSPILength > int.MaxValue) + { + throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 + } + } + + internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + { +#if NETFRAMEWORK + SNIHandle handle = _physicalStateObj.Handle; +#else + Debug.Assert(_physicalStateObj.SessionHandle.Type == SessionHandle.NativeHandleType); + SNIHandle handle = _physicalStateObj.SessionHandle.NativeHandle; +#endif + if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer[0])) + { + throw new InvalidOperationException(SQLMessage.SSPIGenerateError()); + } + } + } +} + diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs new file mode 100644 index 0000000000..bc11cf29c9 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -0,0 +1,28 @@ +#if NET7_0_OR_GREATER + +using System; +using System.Text; +using System.Net.Security; + +#nullable enable + +namespace Microsoft.Data.SqlClient +{ + internal sealed class NegotiateSSPIContextProvider : SSPIContextProvider + { + private NegotiateAuthentication? _negotiateAuth = null; + + internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + { + _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) }); + sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!; + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _physicalStateObj.SessionId, statusCode); + if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) + { + throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode); + } + sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); + } + } +} +#endif 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 new file mode 100644 index 0000000000..fa8c27e3ab --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs @@ -0,0 +1,56 @@ +using System; +using System.Diagnostics; +using Microsoft.Data.Common; + +#nullable enable + +namespace Microsoft.Data.SqlClient +{ + internal abstract class SSPIContextProvider + { + private TdsParser _parser = null!; + private ServerInfo _serverInfo = null!; + private protected TdsParserStateObject _physicalStateObj = null!; + + internal virtual uint MaxSSPILength => 4096; // TODO: what is a good default here? + + internal void Initialize(ServerInfo serverInfo, TdsParserStateObject physicalStateObj, TdsParser parser) + { + _parser = parser; + _physicalStateObj = physicalStateObj; + _serverInfo = serverInfo; + + Initialize(); + } + + private protected virtual void Initialize() + { + } + + internal abstract void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); + + internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer) + => SSPIData(receivedBuff, receivedLength, ref sendBuff, ref sendLength, new[] { sniSpnBuffer }); + + internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) + { + try + { + GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, sniSpnBuffer); + } + catch (Exception e) + { + SSPIError(e.Message + Environment.NewLine + e.StackTrace, TdsEnums.GEN_CLIENT_CONTEXT); + } + } + + protected void SSPIError(string error, string procedure) + { + Debug.Assert(!ADP.IsEmpty(procedure), "TdsParser.SSPIError called with an empty or null procedure string"); + Debug.Assert(!ADP.IsEmpty(error), "TdsParser.SSPIError called with an empty or null error string"); + + _physicalStateObj.AddError(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, _serverInfo.ResolvedServerName, error, procedure, 0)); + _parser.ThrowExceptionAndWarning(_physicalStateObj); + } + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs new file mode 100644 index 0000000000..4366b4665a --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -0,0 +1,265 @@ +using System; +using System.Buffers; +using System.Diagnostics; + +#nullable enable + +namespace Microsoft.Data.SqlClient +{ + internal partial class TdsParser + { + internal void ProcessSSPI(int receivedLength) + { + Debug.Assert(_authenticationProvider is not null); + + SniContext outerContext = _physicalStateObj.SniContext; + _physicalStateObj.SniContext = SniContext.Snix_ProcessSspi; + // allocate received buffer based on length from SSPI message + byte[] receivedBuff = ArrayPool.Shared.Rent(receivedLength); + + // read SSPI data received from server + Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); + bool result = _physicalStateObj.TryReadByteArray(receivedBuff, receivedLength); + if (!result) + { + throw SQL.SynchronousCallMayNotPend(); + } + + // allocate send buffer and initialize length + byte[] rentedSendBuff = ArrayPool.Shared.Rent((int)_authenticationProvider!.MaxSSPILength); + byte[] sendBuff = rentedSendBuff; // need to track these separately in case someone updates the ref parameter + uint sendLength = _authenticationProvider.MaxSSPILength; + + // make call for SSPI data + _authenticationProvider.SSPIData(receivedBuff, (uint)receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer); + + // DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA! + _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0); + + ArrayPool.Shared.Return(rentedSendBuff, clearArray: true); + ArrayPool.Shared.Return(receivedBuff, clearArray: true); + + // set message type so server knows its a SSPI response + _physicalStateObj._outputMessageType = TdsEnums.MT_SSPI; + + // send to server + _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); + _physicalStateObj.SniContext = outerContext; + } + +#nullable disable + + internal void TdsLogin( + SqlLogin rec, + TdsEnums.FeatureExtension requestedFeatures, + SessionData recoverySessionData, + FederatedAuthenticationFeatureExtensionData fedAuthFeatureExtensionData, +#if NETFRAMEWORK + SqlClientOriginalNetworkAddressInfo originalNetworkAddressInfo, +#endif + SqlConnectionEncryptOption encrypt) + { + _physicalStateObj.SetTimeoutSeconds(rec.timeout); + + Debug.Assert(recoverySessionData == null || (requestedFeatures & TdsEnums.FeatureExtension.SessionRecovery) != 0, "Recovery session data without session recovery feature request"); + Debug.Assert(TdsEnums.MAXLEN_HOSTNAME >= rec.hostName.Length, "_workstationId.Length exceeds the max length for this value"); + + Debug.Assert(!(rec.useSSPI && _connHandler._fedAuthRequired), "Cannot use SSPI when server has responded 0x01 for FedAuthRequired PreLogin Option."); + Debug.Assert(!rec.useSSPI || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Cannot use both SSPI and FedAuth"); + Debug.Assert(fedAuthFeatureExtensionData == null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) != 0, "fedAuthFeatureExtensionData provided without fed auth feature request"); + Debug.Assert(fedAuthFeatureExtensionData != null || (requestedFeatures & TdsEnums.FeatureExtension.FedAuth) == 0, "Fed Auth feature requested without specifying fedAuthFeatureExtensionData."); + + Debug.Assert(rec.userName == null || (rec.userName != null && TdsEnums.MAXLEN_CLIENTID >= rec.userName.Length), "_userID.Length exceeds the max length for this value"); + Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTID >= rec.credential.UserId.Length), "_credential.UserId.Length exceeds the max length for this value"); + + Debug.Assert(rec.password == null || (rec.password != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.password.Length), "_password.Length exceeds the max length for this value"); + Debug.Assert(rec.credential == null || (rec.credential != null && TdsEnums.MAXLEN_CLIENTSECRET >= rec.credential.Password.Length), "_credential.Password.Length exceeds the max length for this value"); + + Debug.Assert(rec.credential != null || rec.userName != null || rec.password != null, "cannot mix the new secure password system and the connection string based password"); + Debug.Assert(rec.newSecurePassword != null || rec.newPassword != null, "cannot have both new secure change password and string based change password"); + Debug.Assert(TdsEnums.MAXLEN_APPNAME >= rec.applicationName.Length, "_applicationName.Length exceeds the max length for this value"); + Debug.Assert(TdsEnums.MAXLEN_SERVERNAME >= rec.serverName.Length, "_dataSource.Length exceeds the max length for this value"); + Debug.Assert(TdsEnums.MAXLEN_LANGUAGE >= rec.language.Length, "_currentLanguage .Length exceeds the max length for this value"); + Debug.Assert(TdsEnums.MAXLEN_DATABASE >= rec.database.Length, "_initialCatalog.Length exceeds the max length for this value"); + Debug.Assert(TdsEnums.MAXLEN_ATTACHDBFILE >= rec.attachDBFilename.Length, "_attachDBFileName.Length exceeds the max length for this value"); + + Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); + _connHandler!.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.LoginBegin); + _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ProcessConnectionAuth); + +#if NETFRAMEWORK + // Add CTAIP Provider + // + if (originalNetworkAddressInfo != null) + { + SNINativeMethodWrapper.CTAIPProviderInfo cauthInfo = new SNINativeMethodWrapper.CTAIPProviderInfo(); + cauthInfo.originalNetworkAddress = originalNetworkAddressInfo.Address.GetAddressBytes(); + cauthInfo.fromDataSecurityProxy = originalNetworkAddressInfo.IsFromDataSecurityProxy; + + UInt32 error = SNINativeMethodWrapper.SNIAddProvider(_physicalStateObj.Handle, SNINativeMethodWrapper.ProviderEnum.CTAIP_PROV, cauthInfo); + if (error != TdsEnums.SNI_SUCCESS) + { + _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); + ThrowExceptionAndWarning(_physicalStateObj); + } + + try + { } // EmptyTry/Finally to avoid FXCop violation + finally + { + _physicalStateObj.ClearAllWritePackets(); + } + } +#endif + + // get the password up front to use in sspi logic below + byte[] encryptedPassword = null; + byte[] encryptedChangePassword = null; + int encryptedPasswordLengthInBytes; + int encryptedChangePasswordLengthInBytes; + bool useFeatureExt = (requestedFeatures != TdsEnums.FeatureExtension.None); + + string userName; + + if (rec.credential != null) + { + userName = rec.credential.UserId; + encryptedPasswordLengthInBytes = rec.credential.Password.Length * 2; + } + else + { + userName = rec.userName; + encryptedPassword = TdsParserStaticMethods.ObfuscatePassword(rec.password); + encryptedPasswordLengthInBytes = encryptedPassword.Length; // password in clear text is already encrypted and its length is in byte + } + + if (rec.newSecurePassword != null) + { + encryptedChangePasswordLengthInBytes = rec.newSecurePassword.Length * 2; + } + else + { + encryptedChangePassword = TdsParserStaticMethods.ObfuscatePassword(rec.newPassword); + encryptedChangePasswordLengthInBytes = encryptedChangePassword.Length; + } + + // set the message type + _physicalStateObj._outputMessageType = TdsEnums.MT_LOGIN7; + + // length in bytes + int length = TdsEnums.SQL2005_LOG_REC_FIXED_LEN; + + string clientInterfaceName = TdsEnums.SQL_PROVIDER_NAME; + Debug.Assert(TdsEnums.MAXLEN_CLIENTINTERFACE >= clientInterfaceName.Length, "cchCltIntName can specify at most 128 unicode characters. See Tds spec"); + + // add up variable-len portions (multiply by 2 for byte len of char strings) + // + checked + { + length += (rec.hostName.Length + rec.applicationName.Length + + rec.serverName.Length + clientInterfaceName.Length + + rec.language.Length + rec.database.Length + + rec.attachDBFilename.Length) * 2; + if (useFeatureExt) + { + length += 4; + } + } + + // allocate memory for SSPI variables + byte[] rentedSSPIBuff = null; + byte[] outSSPIBuff = null; // track the rented buffer as a separate variable in case it is updated via the ref parameter + uint outSSPILength = 0; + + // only add lengths of password and username if not using SSPI or requesting federated authentication info + if (!rec.useSSPI && !(_connHandler._federatedAuthenticationInfoRequested || _connHandler._federatedAuthenticationRequested)) + { + checked + { + length += (userName.Length * 2) + encryptedPasswordLengthInBytes + + encryptedChangePasswordLengthInBytes; + } + } + else + { + if (rec.useSSPI) + { + // now allocate proper length of buffer, and set length + outSSPILength = _authenticationProvider.MaxSSPILength; + rentedSSPIBuff = ArrayPool.Shared.Rent((int)outSSPILength); + outSSPIBuff = rentedSSPIBuff; + + // Call helper function for SSPI data and actual length. + // Since we don't have SSPI data from the server, send null for the + // byte[] buffer and 0 for the int length. + Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'"); + _physicalStateObj.SniContext = SniContext.Snix_LoginSspi; + _authenticationProvider.SSPIData(Array.Empty(), 0, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer); + + if (outSSPILength > int.MaxValue) + { + throw SQL.InvalidSSPIPacketSize(); // SqlBu 332503 + } + _physicalStateObj.SniContext = SniContext.Snix_Login; + + checked + { + length += (int)outSSPILength; + } + } + } + + int feOffset = length; + // calculate and reserve the required bytes for the featureEx + length = ApplyFeatureExData(requestedFeatures, recoverySessionData, fedAuthFeatureExtensionData, useFeatureExt, length); + + WriteLoginData(rec, + requestedFeatures, + recoverySessionData, + fedAuthFeatureExtensionData, + encrypt, + encryptedPassword, + encryptedChangePassword, + encryptedPasswordLengthInBytes, + encryptedChangePasswordLengthInBytes, + useFeatureExt, + userName, + length, + feOffset, + clientInterfaceName, + outSSPIBuff, + outSSPILength); + + if (rentedSSPIBuff != null) + { + ArrayPool.Shared.Return(rentedSSPIBuff, clearArray: true); + } + + _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH); + _physicalStateObj.ResetSecurePasswordsInformation(); // Password information is needed only from Login process; done with writing login packet and should clear information + _physicalStateObj.HasPendingData = true; + _physicalStateObj._messageStatus = 0; + +#if NETFRAMEWORK + // Remvove CTAIP Provider after login record is sent. + // + if (originalNetworkAddressInfo != null) + { + UInt32 error = SNINativeMethodWrapper.SNIRemoveProvider(_physicalStateObj.Handle, SNINativeMethodWrapper.ProviderEnum.CTAIP_PROV); + if (error != TdsEnums.SNI_SUCCESS) + { + _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); + ThrowExceptionAndWarning(_physicalStateObj); + } + + try + { } // EmptyTry/Finally to avoid FXCop violation + finally + { + _physicalStateObj.ClearAllWritePackets(); + } + } +#endif + }// tdsLogin + } +} From 9645c01a1ef235cb2342a3847f508f5887dc76b7 Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Fri, 5 Apr 2024 13:37:36 -0500 Subject: [PATCH 22/53] Add true (#2446) --- .../tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj | 1 + .../Microsoft.Data.SqlClient.ManualTesting.Tests.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 4c011a2d55..d6b8a8565c 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -11,6 +11,7 @@ NETSTANDARDREFERNCE $(ObjFolder)$(Configuration).$(Platform).$(AssemblyName) $(BinFolder)$(Configuration).$(Platform).$(AssemblyName) + true diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 676f8126c6..1ed87d83cb 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -12,6 +12,7 @@ $(DefineConstants);NETFRAMEWORK $(ObjFolder)$(Configuration).$(Platform).$(AssemblyName) $(BinFolder)$(Configuration).$(Platform).$(AssemblyName) + true From 9811c657db1cd1ddc270addc9221579df32af6ba Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:03:34 +0000 Subject: [PATCH 23/53] eng | Fix production pipeline (#2450) --- .../templates/steps/update-nuget-config-local-feed-step.yml | 4 ++-- .../Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml index 61bd394af4..5258a3941d 100644 --- a/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml +++ b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml @@ -27,13 +27,13 @@ steps: #Set the Nuget.config file in the project to use extracted package $rootFolder = Get-location - [Xml] $nugetConfig = Get-Content -Path "src\Nuget.config" + [Xml] $nugetConfig = Get-Content -Path "Nuget.config" $Value = Resolve-Path ${{parameters.downloadedNugetPath }} $newAdd = $nugetConfig.CreateElement("add") $newAdd.SetAttribute("key","Package source") $newAdd.SetAttribute("value", "$Value\" ) $nugetConfig.configuration.packageSources.AppendChild($newAdd) - $nugetConfig.Save("$rootFolder\src\Nuget.config") + $nugetConfig.Save("$rootFolder\Nuget.config") displayName: 'Update NuGet config file to read from Nuget folder' - task: MSBuild@1 diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index efd18d78c6..cfbe531e82 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -255,8 +255,10 @@ private bool VerifyHealthReportAgainstRootCertificate(X509Certificate2Collection // An Always Encrypted-enabled driver doesn't verify an expiration date or a certificate authority chain. // A certificate is simply used as a key pair consisting of a public and private key. This is by design. + #pragma warning disable IA5352 // CodeQL [SM00395] By design. Always Encrypted certificates should not be checked. chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + #pragma warning restore IA5352 if (!chain.Build(healthReportCert)) { From 1bf025afeb76eef9eddfdddd306241730d1d61af Mon Sep 17 00:00:00 2001 From: Trayan Zapryanov Date: Mon, 8 Apr 2024 22:19:37 +0300 Subject: [PATCH 24/53] Rent byte buffers in SqlSequentialTextReader (#2356) --- .../Data/SqlClient/SqlSequentialTextReader.cs | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSequentialTextReader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSequentialTextReader.cs index 9ea820000e..a563d0dfc6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSequentialTextReader.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSequentialTextReader.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Buffers; using System.Buffers.Binary; using System.Diagnostics; using System.Text; @@ -18,7 +19,8 @@ sealed internal class SqlSequentialTextReader : System.IO.TextReader private readonly int _columnIndex; // The index of out column in the table private readonly Encoding _encoding; // Encoding for this character stream private readonly Decoder _decoder; // Decoder based on the encoding (NOTE: Decoders are stateful as they are designed to process streams of data) - private byte[] _leftOverBytes; // Bytes leftover from the last Read() operation - this can be null if there were no bytes leftover (Possible optimization: re-use the same array?) + private byte[] _leftOverBytes; // Bytes leftover from the last Read() operation - this can be null if there were no bytes leftover + private int _leftOverByteBufferUsed; //Number of bytes used from _leftOverBytes buffer - will be zero in case of null buffer private int _peekedChar; // The last character that we peeked at (or -1 if we haven't peeked at anything) private Task _currentTask; // The current async task private readonly CancellationTokenSource _disposalTokenSource; // Used to indicate that a cancellation is requested due to disposal @@ -357,23 +359,18 @@ private byte[] PrepareByteBuffer(int numberOfChars, out int byteBufferUsed) if (_leftOverBytes != null) { - // If we have more leftover bytes than we need for this conversion, then just re-use the leftover buffer - if (_leftOverBytes.Length > byteBufferSize) - { - byteBuffer = _leftOverBytes; - byteBufferUsed = byteBuffer.Length; - } - else - { - // Otherwise, copy over the leftover buffer - byteBuffer = new byte[byteBufferSize]; - Buffer.BlockCopy(_leftOverBytes, 0, byteBuffer, 0, _leftOverBytes.Length); - byteBufferUsed = _leftOverBytes.Length; - } + // Copy over the leftover buffer + byteBuffer = ArrayPool.Shared.Rent(byteBufferSize); + Buffer.BlockCopy(_leftOverBytes, 0, byteBuffer, 0, _leftOverByteBufferUsed); + byteBufferUsed = _leftOverByteBufferUsed; + //return _leftOverBytes and clean _leftOverBytes reference + ArrayPool.Shared.Return(_leftOverBytes); + _leftOverBytes = null; + _leftOverByteBufferUsed = 0; } else { - byteBuffer = new byte[byteBufferSize]; + byteBuffer = ArrayPool.Shared.Rent(byteBufferSize); byteBufferUsed = 0; } } @@ -402,14 +399,26 @@ private int DecodeBytesToChars(byte[] inBuffer, int inBufferCount, char[] outBuf // completed may be false and there is no spare bytes if the Decoder has stored bytes to use later if ((!completed) && (bytesUsed < inBufferCount)) { - _leftOverBytes = new byte[inBufferCount - bytesUsed]; - Buffer.BlockCopy(inBuffer, bytesUsed, _leftOverBytes, 0, _leftOverBytes.Length); + _leftOverByteBufferUsed = inBufferCount - bytesUsed; + _leftOverBytes = ArrayPool.Shared.Rent(_leftOverByteBufferUsed); + + Buffer.BlockCopy(inBuffer, bytesUsed, _leftOverBytes, 0, _leftOverByteBufferUsed); } else { // If Convert() sets completed to true, then it must have used all of the bytes we gave it Debug.Assert(bytesUsed >= inBufferCount, "Converted completed, but not all bytes were used"); - _leftOverBytes = null; + if (_leftOverBytes != null) + { + ArrayPool.Shared.Return(_leftOverBytes); + _leftOverBytes = null; + _leftOverByteBufferUsed = 0; + } + } + + if (inBuffer.Length > 0) + { + ArrayPool.Shared.Return(inBuffer); } Debug.Assert(((_reader == null) || (_reader.ColumnDataBytesRemaining() > 0) || (!completed) || (_leftOverBytes == null)), "Stream has run out of data and the decoder finished, but there are leftover bytes"); From 4e6853e2dd61be2d0cde181c4c85e61dd7a2d2b5 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 9 Apr 2024 20:32:27 +0200 Subject: [PATCH 25/53] Update Microsoft.Identity dependencies (#2429) --- tools/props/Versions.props | 4 ++-- tools/specs/Microsoft.Data.SqlClient.nuspec | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/props/Versions.props b/tools/props/Versions.props index 9c58ec3889..222ad1c1e6 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -29,8 +29,8 @@ 1.10.3 4.56.0 - 6.35.0 - 6.35.0 + 7.5.0 + 7.5.0 4.5.1 6.0.0 8.0.0 diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index f44a2a462d..c2c4353999 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -31,8 +31,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -42,8 +42,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -52,8 +52,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -62,8 +62,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -80,8 +80,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + From 8c9b6992aa812cad39d21460314cd68f5a989b45 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 9 Apr 2024 20:33:07 +0200 Subject: [PATCH 26/53] Extend DateOnly/TimeOnly support to include DataTable as structured parameter (#2258) --- .../SqlClient/Server/ExtendedClrTypeCode.cs | 4 ++ .../Data/SqlClient/Server/MetadataUtilsSmi.cs | 31 +++++++++++ .../Data/SqlClient/Server/ValueUtilsSmi.cs | 16 ++++++ .../SQL/ParameterTest/ParametersTest.cs | 53 +++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ExtendedClrTypeCode.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ExtendedClrTypeCode.cs index 28818a16f1..953a5d5e55 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ExtendedClrTypeCode.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ExtendedClrTypeCode.cs @@ -49,6 +49,10 @@ internal enum ExtendedClrTypeCode IEnumerableOfSqlDataRecord, // System.Collections.Generic.IEnumerable TimeSpan, // System.TimeSpan DateTimeOffset, // System.DateTimeOffset +#if NET6_0_OR_GREATER + DateOnly, // System.DateOnly + TimeOnly, // System.TimeOnly +#endif Stream, // System.IO.Stream TextReader, // System.IO.TextReader XmlReader, // System.Xml.XmlReader diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs index 590429222a..bd771f7ab1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs @@ -75,6 +75,10 @@ internal class MetaDataUtilsSmi SqlDbType.Structured, // System.Collections.Generic.IEnumerable SqlDbType.Time, // System.TimeSpan SqlDbType.DateTimeOffset, // System.DateTimeOffset +#if NET6_0_OR_GREATER + SqlDbType.Date, // System.DateOnly + SqlDbType.Time, // System.TimeOnly +#endif }; @@ -86,7 +90,11 @@ internal class MetaDataUtilsSmi private static Dictionary CreateTypeToExtendedTypeCodeMap() { +#if NET6_0_OR_GREATER + int Count = 44; +#else int Count = 42; +#endif // Keep this initialization list in the same order as ExtendedClrTypeCode for ease in validating! var dictionary = new Dictionary(Count) { @@ -132,6 +140,10 @@ private static Dictionary CreateTypeToExtendedTypeCod { typeof(IEnumerable), ExtendedClrTypeCode.IEnumerableOfSqlDataRecord }, { typeof(TimeSpan), ExtendedClrTypeCode.TimeSpan }, { typeof(DateTimeOffset), ExtendedClrTypeCode.DateTimeOffset }, +#if NET6_0_OR_GREATER + { typeof(DateOnly), ExtendedClrTypeCode.DateOnly }, + { typeof(TimeOnly), ExtendedClrTypeCode.TimeOnly }, +#endif }; return dictionary; } @@ -244,6 +256,16 @@ Type udtType extendedCode = ExtendedClrTypeCode.Char; break; case SqlDbType.Date: +#if NET6_0_OR_GREATER + if (value.GetType() == typeof(DateOnly)) + extendedCode = ExtendedClrTypeCode.DateOnly; + else if (value.GetType() == typeof(DateTime)) + extendedCode = ExtendedClrTypeCode.DateTime; + else if (value.GetType() == typeof(SqlDateTime)) + extendedCode = ExtendedClrTypeCode.SqlDateTime; + + break; +#endif case SqlDbType.DateTime2: #if NETFRAMEWORK if (smiVersion >= SmiContextFactory.Sql2008Version) @@ -330,6 +352,14 @@ Type udtType extendedCode = ExtendedClrTypeCode.Invalid; } break; +#if NET6_0_OR_GREATER + case SqlDbType.Time: + if (value.GetType() == typeof(TimeOnly)) + extendedCode = ExtendedClrTypeCode.TimeOnly; + else if (value.GetType() == typeof(TimeSpan)) + extendedCode = ExtendedClrTypeCode.TimeSpan; + break; +#else case SqlDbType.Time: if (value.GetType() == typeof(TimeSpan) #if NETFRAMEWORK @@ -338,6 +368,7 @@ Type udtType ) extendedCode = ExtendedClrTypeCode.TimeSpan; break; +#endif case SqlDbType.DateTimeOffset: if (value.GetType() == typeof(DateTimeOffset) #if NETFRAMEWORK diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 61bcec417f..4662bc6012 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -1542,6 +1542,14 @@ value is DataFeed SetCompatibleValue(sink, setters, ordinal, metaData, charsValue, ExtendedClrTypeCode.CharArray, 0); break; } +#if NET6_0_OR_GREATER + case ExtendedClrTypeCode.DateOnly: + SetDateTime_Checked(sink, setters, ordinal, metaData, ((DateOnly)value).ToDateTime(new TimeOnly(0, 0))); + break; + case ExtendedClrTypeCode.TimeOnly: + SetTimeSpan_Checked(sink, (SmiTypedGetterSetter)setters, ordinal, metaData, ((TimeOnly)value).ToTimeSpan()); + break; +#endif case ExtendedClrTypeCode.DateTime: SetDateTime_Checked(sink, setters, ordinal, metaData, (DateTime)value); break; @@ -2899,6 +2907,10 @@ int length /*EnSDR*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*IEnurerable*/ /*TmSpn*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeSpan*/ /*DTOst*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , X , },/*DateTimeOffset*/ +#if NET6_0_OR_GREATER +/*DOnly*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateOnly*/ +/*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ +#endif /*Strm */{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Stream*/ /*TxRdr*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/ /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/ @@ -2951,6 +2963,10 @@ int length /*EnSDR*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*IEnurerable*/ /*TmSpn*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeSpan*/ /*DTOst*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , X , },/*DateTimeOffset*/ +#if NET6_0_OR_GREATER +/*DOnly*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateOnly*/ +/*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ +#endif /*Strm */{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Stream*/ /*TxRdr*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/ /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/ diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs index 3b71cbf851..378a32c07c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs @@ -9,6 +9,9 @@ using System.Data.SqlTypes; using System.Threading; using Xunit; +#if NET6_0_OR_GREATER +using Microsoft.Data.SqlClient.Server; +#endif namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -306,6 +309,56 @@ public static void TestParametersWithDatatablesTVPInsert() } } +#if NET6_0_OR_GREATER + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] + public static void TestDateOnlyTVPDataTable_CommandSP() + { + string tableTypeName = "[dbo]." + DataTestUtility.GetUniqueNameForSqlServer("UDTTTestDateOnlyTVP"); + string spName = DataTestUtility.GetUniqueNameForSqlServer("spTestDateOnlyTVP"); + SqlConnection connection = new(s_connString); + try + { + connection.Open(); + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandType = CommandType.Text; + cmd.CommandText = $"CREATE TYPE {tableTypeName} AS TABLE ([DateColumn] date NULL, [TimeColumn] time NULL)"; + cmd.ExecuteNonQuery(); + cmd.CommandText = $"CREATE PROCEDURE {spName} (@dates {tableTypeName} READONLY) AS SELECT COUNT(*) FROM @dates"; + cmd.ExecuteNonQuery(); + } + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandText = spName; + cmd.CommandType = CommandType.StoredProcedure; + + DataTable dtTest = new(); + dtTest.Columns.Add(new DataColumn("DateColumn", typeof(DateOnly))); + dtTest.Columns.Add(new DataColumn("TimeColumn", typeof(TimeOnly))); + var dataRow = dtTest.NewRow(); + dataRow["DateColumn"] = new DateOnly(2023, 11, 15); + dataRow["TimeColumn"] = new TimeOnly(12, 30, 45); + dtTest.Rows.Add(dataRow); + + cmd.Parameters.Add(new SqlParameter + { + ParameterName = "@dates", + SqlDbType = SqlDbType.Structured, + TypeName = tableTypeName, + Value = dtTest, + }); + + cmd.ExecuteNonQuery(); + } + } + finally + { + DataTestUtility.DropStoredProcedure(connection, spName); + DataTestUtility.DropUserDefinedType(connection, tableTypeName); + } + } +#endif + #region Scaled Decimal Parameter & TVP Test [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] [InlineData("CAST(1.0 as decimal(38, 37))", "1.0000000000000000000000000000")] From f5df519f5e9783d6a726fb370678e05a04a3084b Mon Sep 17 00:00:00 2001 From: Evgeny Akhtimirov Date: Tue, 9 Apr 2024 15:04:53 -0400 Subject: [PATCH 27/53] Fix | SqlBuffer.SqlGuid (#2310) --- .gitignore | 3 + .../src/Microsoft/Data/SqlClient/SqlBuffer.cs | 2 +- .../Microsoft.Data.SqlClient.Tests.csproj | 1 + .../tests/FunctionalTests/SqlBufferTests.cs | 253 ++++++++++++++++++ 4 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs diff --git a/.gitignore b/.gitignore index daeaf68c7a..bb6f58f9bd 100644 --- a/.gitignore +++ b/.gitignore @@ -353,6 +353,9 @@ healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ +# JetBrains Rider (cross platform .NET IDE) working folder +.idea/ + # Ionide (cross platform F# VS Code tools) working folder .ionide/ diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs index 9cfc077da4..31678a3107 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -811,7 +811,7 @@ internal SqlGuid SqlGuid { if (StorageType.Guid == _type) { - return new SqlGuid(_value._guid); + return IsNull ? SqlGuid.Null : new SqlGuid(_value._guid); } else if (StorageType.SqlGuid == _type) { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index d6b8a8565c..8cd1972ded 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -33,6 +33,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs new file mode 100644 index 0000000000..6aef4b60b2 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs @@ -0,0 +1,253 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Linq; +using System.Reflection; +using Xunit; + +namespace Microsoft.Data.SqlClient.Tests +{ + public sealed class SqlBufferTests + { + static SqlBufferTests() + { + const string sqlBufferTypeFullName = "Microsoft.Data.SqlClient.SqlBuffer"; + const string storageTypeName = nameof(SqlBufferProxy.StorageType); + + var assembly = typeof(SqlClientFactory).Assembly; + _sqlBufferType = assembly.GetType(sqlBufferTypeFullName) + ?? throw new Exception($"Type not found [{sqlBufferTypeFullName}]"); + _storageTypeType = _sqlBufferType.GetNestedTypes(BindingFlags.NonPublic) + .FirstOrDefault(x => x.Name == storageTypeName) + ?? throw new Exception($"Type not found [{sqlBufferTypeFullName}+{storageTypeName}]"); + } + + private static readonly Type _sqlBufferType; + private static readonly Type _storageTypeType; + private readonly SqlBufferProxy _target = new(); + + public static IEnumerable GetStorageTypeValues() + { +#if NET6_0_OR_GREATER + return Enum.GetValues() + .Select(x => new object[] { x }); +#else + return Enum.GetValues(typeof(SqlBufferProxy.StorageType)) + .OfType() + .Select(x => new object[] { x }); +#endif + } + + [Theory] + [MemberData(nameof(GetStorageTypeValues))] + public void StorageTypeInProxyShouldHaveTheSameValueAsOriginal(SqlBufferProxy.StorageType expected) + { + var originalEnumName = Enum.GetName(_storageTypeType, (int)expected); + + Assert.Equal(expected.ToString(), originalEnumName); + } + + [Fact] + public void GuidShouldThrowWhenSqlGuidNullIsSet() + { + _target.SqlGuid = SqlGuid.Null; + + Assert.Throws(() => _target.Guid); + } + + [Theory] + [InlineData(SqlBufferProxy.StorageType.Guid)] + [InlineData(SqlBufferProxy.StorageType.SqlGuid)] + public void GuidShouldThrowWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType) + { + _target.SetToNullOfType(storageType); + + Assert.Throws(() => _target.Guid); + } + + [Fact] + public void GuidShouldReturnWhenGuidIsSet() + { + var expected = Guid.NewGuid(); + _target.Guid = expected; + + Assert.Equal(expected, _target.Guid); + } + + [Fact] + public void GuidShouldReturnExpectedWhenSqlGuidIsSet() + { + var expected = Guid.NewGuid(); + _target.SqlGuid = expected; + + Assert.Equal(expected, _target.Guid); + } + + [Theory] + [InlineData(SqlBufferProxy.StorageType.Guid)] + [InlineData(SqlBufferProxy.StorageType.SqlGuid)] + public void SqlGuidShouldReturnSqlNullWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType) + { + _target.SetToNullOfType(storageType); + + Assert.Equal(SqlGuid.Null, _target.SqlGuid); + } + + [Fact] + public void SqlGuidShouldReturnSqlGuidNullWhenSqlGuidNullIsSet() + { + _target.SqlGuid = SqlGuid.Null; + + Assert.Equal(SqlGuid.Null, _target.SqlGuid); + } + + [Fact] + public void SqlGuidShouldReturnExpectedWhenGuidIsSet() + { + var guid = Guid.NewGuid(); + SqlGuid expected = guid; + _target.Guid = guid; + + Assert.Equal(expected, _target.SqlGuid); + } + + [Fact] + public void SqlGuidShouldReturnExpectedWhenSqlGuidIsSet() + { + SqlGuid expected = Guid.NewGuid(); + _target.SqlGuid = expected; + + Assert.Equal(expected, _target.SqlGuid); + } + + [Fact] + public void SqlValueShouldReturnExpectedWhenGuidIsSet() + { + var guid = Guid.NewGuid(); + SqlGuid expected = guid; + _target.Guid = guid; + + Assert.Equal(expected, _target.SqlValue); + } + + [Fact] + public void SqlValueShouldReturnExpectedWhenSqlGuidIsSet() + { + SqlGuid expected = Guid.NewGuid(); + _target.SqlGuid = expected; + + Assert.Equal(expected, _target.SqlValue); + } + + public sealed class SqlBufferProxy + { + public enum StorageType + { + Empty = 0, + Boolean, + Byte, + DateTime, + Decimal, + Double, + Int16, + Int32, + Int64, + Guid, + Money, + Single, + String, + SqlBinary, + SqlCachedBuffer, + SqlGuid, + SqlXml, + Date, + DateTime2, + DateTimeOffset, + Time, + } + + private static readonly PropertyInfo _guidProperty; + private static readonly PropertyInfo _sqlGuidProperty; + private static readonly PropertyInfo _sqlValueProperty; + private static readonly MethodInfo _setToNullOfTypeMethod; + private readonly object _instance; + + static SqlBufferProxy() + { + var flags = BindingFlags.NonPublic | BindingFlags.Instance; + _guidProperty = _sqlBufferType.GetProperty(nameof(Guid), flags); + _sqlGuidProperty = _sqlBufferType.GetProperty(nameof(SqlGuid), flags); + _sqlValueProperty = _sqlBufferType.GetProperty(nameof(SqlValue), flags); + _setToNullOfTypeMethod = _sqlBufferType.GetMethod(nameof(SetToNullOfType), flags); + } + + public SqlBufferProxy() + { + _instance = Activator.CreateInstance(_sqlBufferType, true); + } + + public Guid Guid + { + get => GetPropertyValue(_guidProperty); + set => SetPropertyValue(_guidProperty, value); + } + + public SqlGuid SqlGuid + { + get => GetPropertyValue(_sqlGuidProperty); + set => SetPropertyValue(_sqlGuidProperty, value); + } + + public object SqlValue + { + get => GetPropertyValue(_sqlValueProperty); + } + + public void SetToNullOfType(StorageType storageType) + { +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + _setToNullOfTypeMethod + .Invoke(_instance, BindingFlags.DoNotWrapExceptions, null, new object[] { (int)storageType }, null); +#else + _setToNullOfTypeMethod.Invoke(_instance, new object[] { (int)storageType }); +#endif + } + + private T GetPropertyValue(PropertyInfo property) + { +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return (T)property.GetValue(_instance, BindingFlags.DoNotWrapExceptions, null, null, null); +#else + try + { + return (T)property.GetValue(_instance); + } + catch (TargetInvocationException e) + { + throw e.InnerException!; + } +#endif + } + + private void SetPropertyValue(PropertyInfo property, object value) + { +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + property.SetValue(_instance, value, BindingFlags.DoNotWrapExceptions, null, null, null); +#else + try + { + property.SetValue(_instance, value); + } + catch (TargetInvocationException e) + { + throw e.InnerException!; + } +#endif + } + } + } +} From 61e89f9570bbe53dff0e4c750ccbdb7a46b274b0 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 9 Apr 2024 21:27:44 +0200 Subject: [PATCH 28/53] Fix | ArgumentNullException on SqlDataRecord.GetValue when using Udt data type (#2448) --- .../Data/SqlClient/Server/MetadataUtilsSmi.cs | 4 --- .../Microsoft.Data.SqlClient.Tests.csproj | 2 ++ .../FunctionalTests/SqlDataRecordTest.cs | 35 ++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs index bd771f7ab1..d3c01546ce 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs @@ -531,11 +531,7 @@ internal static SmiExtendedMetaData SqlMetaDataToSmiExtendedMetaData(SqlMetaData source.Scale, source.LocaleId, source.CompareOptions, -#if NETFRAMEWORK source.Type, -#else - null, -#endif source.Name, typeSpecificNamePart1, typeSpecificNamePart2, diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 8cd1972ded..aedae160a7 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -96,6 +96,8 @@ + + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs index 87f6c167ec..0e748c5d74 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs @@ -8,6 +8,7 @@ using System.Data; using System.Data.SqlTypes; using Microsoft.Data.SqlClient.Server; +using Microsoft.SqlServer.Types; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -318,6 +319,19 @@ public void GetChar_ThrowsNotSupported() Assert.Throws(() => record.GetChar(0)); } + [Theory] + [ClassData(typeof(GetUdtTypeTestData))] + public void GetUdt_ReturnsValue(Type udtType, object value, string serverTypeName) + { + SqlMetaData[] metadata = new SqlMetaData[] { new SqlMetaData(nameof(udtType.Name), SqlDbType.Udt, udtType, serverTypeName) }; + + SqlDataRecord record = new SqlDataRecord(metadata); + + record.SetValue(0, value); + + Assert.Equal(value.ToString(), record.GetValue(0).ToString()); + } + [Theory] [ClassData(typeof(GetXXXBadTypeTestData))] public void GetXXX_ThrowsIfBadType(Func getXXX) @@ -342,8 +356,8 @@ public void GetXXX_ReturnValue(SqlDbType dbType, object value, Func + { + public IEnumerator GetEnumerator() + { + yield return new object[] { typeof(SqlGeography), SqlGeography.Point(43, -81, 4326), "Geography" }; + yield return new object[] { typeof(SqlGeometry), SqlGeometry.Point(43, -81, 4326), "Geometry" }; + yield return new object[] { typeof(SqlHierarchyId), SqlHierarchyId.Parse("/"), "HierarchyId" }; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + public class GetXXXCheckValueTestData : IEnumerable { public IEnumerator GetEnumerator() @@ -383,6 +412,10 @@ public IEnumerator GetEnumerator() yield return new object[] { SqlDbType.DateTime, DateTime.Now, new Func(r => r.GetDateTime(0)) }; yield return new object[] { SqlDbType.DateTimeOffset, new DateTimeOffset(DateTime.Now), new Func(r => r.GetDateTimeOffset(0)) }; yield return new object[] { SqlDbType.Time, TimeSpan.FromHours(1), new Func(r => r.GetTimeSpan(0)) }; + yield return new object[] { SqlDbType.Date, DateTime.Now.Date, new Func(r => r.GetDateTime(0)) }; + yield return new object[] { SqlDbType.Bit, bool.Parse(bool.TrueString), new Func(r => r.GetBoolean(0)) }; + yield return new object[] { SqlDbType.SmallDateTime, DateTime.Now, new Func(r => r.GetDateTime(0)) }; + yield return new object[] { SqlDbType.TinyInt, (byte)1, new Func(r => r.GetByte(0)) }; } IEnumerator IEnumerable.GetEnumerator() From ea7ad53b26ce24fcb22e643691f50eb6627f35a4 Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Mon, 15 Apr 2024 19:57:54 +0000 Subject: [PATCH 29/53] Merged PR 4474: eng | Add AKV provider signed package --- .../jobs/build-signed-akv-package-job.yml | 64 +++++++++++ .../jobs/build-signed-package-job.yml | 47 ++------ .../jobs/run-tests-package-reference-job.yml | 3 +- ...ob.yml => validate-signed-package-job.yml} | 6 +- ...ld-all-configurations-signed-dlls-step.yml | 47 +++++++- .../templates/steps/code-analyze-step.yml | 34 ++++-- .../steps/copy-dlls-for-test-step.yml | 108 ++++++++++++++++++ .../steps/generate-nuget-package-step.yml | 8 +- .../templates/steps/publish-symbols-step.yml | 60 +++++++--- .../dotnet-sqlclient-signing-pipeline.yml | 40 ++++++- eng/pipelines/libraries/akv-variables.yml | 15 +++ eng/pipelines/libraries/build-variables.yml | 22 +--- eng/pipelines/libraries/common-variables.yml | 19 +++ ...ables.yml => mds-validation-variables.yml} | 4 +- eng/pipelines/libraries/mds-variables.yml | 15 +++ ...waysEncrypted.AzureKeyVaultProvider.nuspec | 52 ++++----- 16 files changed, 424 insertions(+), 120 deletions(-) create mode 100644 eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml rename eng/pipelines/common/templates/jobs/{verify-signed-package-job.yml => validate-signed-package-job.yml} (98%) create mode 100644 eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml create mode 100644 eng/pipelines/libraries/akv-variables.yml create mode 100644 eng/pipelines/libraries/common-variables.yml rename eng/pipelines/libraries/{validation-variables.yml => mds-validation-variables.yml} (94%) create mode 100644 eng/pipelines/libraries/mds-variables.yml diff --git a/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml new file mode 100644 index 0000000000..ecd07a41c9 --- /dev/null +++ b/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml @@ -0,0 +1,64 @@ +################################################################################# +# 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. # +################################################################################# +jobs: +- job: build_signed_akv_package + pool: + type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs + + variables: + - template: ../../../libraries/variables.yml@self + + steps: + - script: SET + displayName: 'Print Environment Variables' + + - template: ../steps/build-all-configurations-signed-dlls-step.yml@self + parameters: + product: AKV + nugetPackageRefVersion: $(MDS_PackageRef_Version) + AssemblyFileVersion: $(AKVAssemblyFileVersion) + + - template: ../steps/code-analyze-step.yml@self + parameters: + analyzeType: all + product: AKV + nugetPackageRefVersion: $(MDS_PackageRef_Version) + + - template: ../steps/esrp-code-signing-step.yml@self + parameters: + artifactType: dll + + - template: ../steps/generate-nuget-package-step.yml@self + parameters: + OutputDirectory: $(artifactDirectory) + nuspecPath: ${{variables.akvNuspecPath }} + NugetPackageVersion: ${{variables.AKVNuGetPackageVersion }} + referenceType: package + + - template: ../steps/esrp-code-signing-step.yml@self + parameters: + artifactType: pkg + + - template: ../steps/copy-dlls-for-test-step.yml@self + parameters: + product: AKV + referenceType: package + + # Publish symbols to private server + - template: ../steps/publish-symbols-step.yml@self + parameters: + SymAccount: $(PrivateSymAccount) + referenceType: package + symbolsVersion: ${{variables.AKVNuGetPackageVersion }} + product: AKV + + # Publish symbols to public server + - template: ../steps/publish-symbols-step.yml@self + parameters: + SymAccount: $(PublicSymAccount) + referenceType: package + symbolsVersion: ${{variables.AKVNuGetPackageVersion }} + product: AKV diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml index 8c2d41b387..26ab9fa236 100644 --- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml @@ -17,59 +17,34 @@ jobs: type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs variables: - - template: ../../../libraries/variables.yml@self + - template: ../../../libraries/variables.yml@self steps: - script: SET displayName: 'Print Environment Variables' + - template: ../steps/build-all-configurations-signed-dlls-step.yml@self + - template: ../steps/code-analyze-step.yml@self parameters: analyzeType: all + - template: ../steps/esrp-code-signing-step.yml@self parameters: artifactType: dll + - template: ../steps/generate-nuget-package-step.yml@self parameters: OutputDirectory: $(artifactDirectory) + - template: ../steps/esrp-code-signing-step.yml@self parameters: artifactType: pkg - - powershell: | - $software = '${{parameters.softwareFolder}}' - md $software - md $software\win - md $software\win\net46 - md $software\win\net6.0 - md $software\win\net8.0 - md $software\win\netstandard2.0 - md $software\win\netstandard2.1 - - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\net462\Microsoft.Data.SqlClient.dll" "$software\win\net46" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.dll" "$software\win\net6.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.dll" "$software\win\net8.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.dll" "$software\win\netstandard2.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.1\Microsoft.Data.SqlClient.dll" "$software\win\netstandard2.1" -recurse - - $symbols = '${{parameters.symbolsFolder}}' - md $symbols - md $symbols\win - md $symbols\win\net46 - md $symbols\win\net6.0 - md $symbols\win\net8.0 - md $symbols\win\netstandard2.0 - md $symbols\win\netstandard2.1 - - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\net462\Microsoft.Data.SqlClient.pdb" "$symbols\win\net46" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net6.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net6.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\net8.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.0\Microsoft.Data.SqlClient.pdb" "$symbols\win\netstandard2.0" -recurse - Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\netstandard2.1\Microsoft.Data.SqlClient.pdb" "$symbols\win\netstandard2.1" -recurse - - Write-Host "Artifacts fetched for testing" - dir - Get-Location - displayName: 'Prepare Arifacts for Testing' + + - template: ../steps/copy-dlls-for-test-step.yml@self + parameters: + product: MDS + # Publish symbols to private server - template: ../steps/publish-symbols-step.yml@self parameters: diff --git a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml index 0739e543cc..f764a55201 100644 --- a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml +++ b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml @@ -28,8 +28,7 @@ jobs: vmImage: 'ADO-MMS22-SQL19' variables: # More settings at https://aka.ms/obpipelines/yaml/jobs - - template: ../../../libraries/build-variables.yml@self - - template: ../../../libraries/validation-variables.yml@self + - template: ../../../libraries/mds-validation-variables.yml@self steps: - template: ../steps/pre-build-step.yml diff --git a/eng/pipelines/common/templates/jobs/verify-signed-package-job.yml b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml similarity index 98% rename from eng/pipelines/common/templates/jobs/verify-signed-package-job.yml rename to eng/pipelines/common/templates/jobs/validate-signed-package-job.yml index e77d2596fd..9f12f42e92 100644 --- a/eng/pipelines/common/templates/jobs/verify-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml @@ -34,7 +34,7 @@ parameters: default: $(AssemblyFileVersion) jobs: -- job: verify_signed_package +- job: validate_signed_package ${{ if ne(parameters.dependsOn, '')}}: dependsOn: '${{parameters.dependsOn }}' pool: @@ -44,8 +44,8 @@ jobs: vmImage: 'ADO-MMS22-SQL19' variables: # More settings at https://aka.ms/obpipelines/yaml/jobs - - template: ../../../libraries/build-variables.yml@self - - template: ../../../libraries/validation-variables.yml@self + - template: ../../../libraries/mds-validation-variables.yml@self + - name: pathToDownloadedNuget # path to the downloaded nuget files value: $(Pipeline.Workspace)\${{parameters.packageFolderName }} diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml index c5709114ac..f61dd48767 100644 --- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml +++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml @@ -12,15 +12,50 @@ parameters: type: string default: '$(Configuration)' + - name: nugetPackageRefVersion + type: string + default: '' + + - name: product + default: MDS + values: + - MDS + - AKV + - MSS + steps: - - task: DownloadSecureFile@1 - displayName: 'Download Key Pair' - inputs: - secureFile: netfxKeypair.snk - retryCount: 5 +- task: DownloadSecureFile@1 + displayName: 'Download Key Pair' + inputs: + secureFile: netfxKeypair.snk + retryCount: 5 + +- ${{ if eq(parameters.product, 'MDS') }}: - task: MSBuild@1 displayName: 'BuildAllConfigurations using build.proj' inputs: solution: '**/build.proj' configuration: '${{parameters.Configuration }}' - msbuildArguments: '/p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} /t:BuildAllConfigurations /p:GenerateNuget=false /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' + msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' + +- ${{ if eq(parameters.product, 'AKV') }}: + - task: MSBuild@1 + displayName: 'BuildAKVNetStAllOS using build.proj' + inputs: + solution: '**/build.proj' + configuration: '$(Configuration)' + msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAKVNetStAllOS -p:NugetPackageVersion=${{parameters.nugetPackageRefVersion }} -p:ReferenceType=Package -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' + + - task: MSBuild@1 + displayName: 'BuildAKVNetFx using build.proj' + inputs: + solution: '**/build.proj' + configuration: '$(Configuration)' + msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAKVNetFx -p:NugetPackageVersion=${{parameters.nugetPackageRefVersion }} -p:ReferenceType=Package -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' + + - task: MSBuild@1 + displayName: 'BuildAKVNetCoreAllOS using build.proj' + inputs: + solution: '**/build.proj' + configuration: '$(Configuration)' + msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAKVNetCoreAllOS -p:NugetPackageVersion=${{parameters.nugetPackageRefVersion }} -p:ReferenceType=Package -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' diff --git a/eng/pipelines/common/templates/steps/code-analyze-step.yml b/eng/pipelines/common/templates/steps/code-analyze-step.yml index ec6a552fcb..92be8eabf6 100644 --- a/eng/pipelines/common/templates/steps/code-analyze-step.yml +++ b/eng/pipelines/common/templates/steps/code-analyze-step.yml @@ -14,15 +14,35 @@ parameters: type: string default: $(REPOROOT) + - name: nugetPackageRefVersion + type: string + default: '' + + - name: product + default: MDS + values: + - MDS + - AKV + - MSS + steps: - ${{ if or(eq(parameters.analyzeType, 'roslyn'), eq(parameters.analyzeType, 'all')) }}: - - task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3 - displayName: 'Guardian Dotnet Analyzers ' - inputs: - msBuildVersion: 17.0 - msBuildArchitecture: x64 - setupCommandlinePicker: vs2022 - msBuildCommandline: 'msbuild ${{parameters.sourceRoot}}\build.proj -p:configuration=Release -p:GenerateNuget=false -p:BuildTools=false' + - ${{ if eq(parameters.product, 'MDS') }}: + - task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3 + displayName: 'Guardian Dotnet Analyzers ' + inputs: + msBuildVersion: 17.0 + msBuildArchitecture: x64 + setupCommandlinePicker: vs2022 + msBuildCommandline: 'msbuild ${{parameters.sourceRoot}}\build.proj -p:configuration=Release -p:GenerateNuget=false -p:BuildTools=false' + - ${{ if eq(parameters.product, 'AKV') }}: + - task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3 + displayName: 'Guardian Dotnet Analyzers ' + inputs: + msBuildVersion: 17.0 + msBuildArchitecture: x64 + setupCommandlinePicker: vs2022 + msBuildCommandline: 'msbuild ${{parameters.sourceRoot}}\build.proj -p:configuration=Release -p:GenerateNuget=false -p:BuildTools=false -p:NugetPackageVersion=${{parameters.nugetPackageRefVersion }} -p:ReferenceType=Package -t:BuildAKVNetCoreAllOS' - ${{ if or(eq(parameters.analyzeType, 'inspect'), eq(parameters.analyzeType, 'all')) }}: - task: securedevelopmentteam.vss-secure-development-tools.build-task-codeinspector.CodeInspector@2 diff --git a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml new file mode 100644 index 0000000000..6b0c1fa3ab --- /dev/null +++ b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml @@ -0,0 +1,108 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# +parameters: + - name: Configuration + type: string + default: '$(Configuration)' + + - name: symbolsFolder + type: string + default: symbols + + - name: softwareFolder + type: string + default: software + + - name: referenceType + default: project + values: + - project + - package + + - name: listOfTF + type: object + default: + - net462 + - net6.0 + - net8.0 + - netstandard2.0 + - netstandard2.1 + + - name: product + default: MDS + values: + - MDS + - AKV + - MSS + +steps: +- powershell: | + $software = '${{parameters.softwareFolder}}' + $symbols = '${{parameters.symbolsFolder}}' + + md $software + md $software\win + + md $symbols + md $symbols\win + displayName: 'Make base directories' + +- ${{ each targetFramework in parameters.listOfTF }}: + - ${{ if eq(parameters.product, 'MDS') }}: + - powershell: | + $software = '${{parameters.softwareFolder}}' + $tf = '${{ targetFramework }}' + md $software\win\$tf + + if ($tf.StartsWith('net4')) + { + Copy-Item "artifacts\${{parameters.referenceType }}\bin\Windows_NT\${{parameters.Configuration }}.AnyCPU\Microsoft.Data.SqlClient\netfx\$tf\Microsoft.Data.SqlClient.dll" "$software\win\$tf" -recurse + } + else + { + Copy-Item "artifacts\${{parameters.referenceType }}\bin\Windows_NT\${{parameters.Configuration }}.AnyCPU\Microsoft.Data.SqlClient\netcore\$tf\Microsoft.Data.SqlClient.dll" "$software\win\$tf" -recurse + } + + $symbols = '${{parameters.symbolsFolder}}' + md $symbols\win\$tf + + if ($tf.StartsWith('net4')) + { + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\$tf\Microsoft.Data.SqlClient.pdb" "$symbols\win\$tf" -recurse + } + else + { + Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\$tf\Microsoft.Data.SqlClient.pdb" "$symbols\win\$tf" -recurse + } + + Write-Host "Artifacts fetched for testing" + Get-Location + displayName: 'Prepare ${{ targetFramework }} Arifacts for Testing' + + - ${{ if eq(parameters.product, 'AKV') }}: + - powershell: | + $software = '${{parameters.softwareFolder}}' + $tf = '${{ targetFramework }}' + md $software\win\$tf + + Copy-Item "artifacts\${{parameters.referenceType }}\bin\Windows_NT\${{parameters.Configuration }}.AnyCPU\AzureKeyVaultProvider\$tf\Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.dll" "$software\win\$tf" -recurse + + $symbols = '${{parameters.symbolsFolder}}' + md $symbols\win\$tf + + Copy-Item "artifacts\${{parameters.referenceType }}\bin\Windows_NT\${{parameters.Configuration }}.AnyCPU\AzureKeyVaultProvider\$tf\Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.pdb" "$symbols\win\$tf" -recurse + + Write-Host "Artifacts fetched for testing" + Get-Location + displayName: 'Prepare ${{ targetFramework }} Arifacts for Testing' + +- powershell: | + $software = '${{parameters.softwareFolder}}' + $symbols = '${{parameters.symbolsFolder}}' + + Get-ChildItem -recurse "$software\*.dll" + Get-ChildItem -recurse "$symbols\*.pdb" + displayName: 'List the prepared files' diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml index 91b4ee72e1..3736c0e828 100644 --- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml +++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml @@ -23,6 +23,12 @@ parameters: - name: Configuration type: string default: '$(Configuration)' + + - name: referenceType + default: project + values: + - project + - package steps: - task: NuGetToolInstaller@1 @@ -37,4 +43,4 @@ steps: displayName: 'NuGet pack with snupkg' inputs: command: custom - arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=${{parameters.CommitHead}};Configuration=${{parameters.Configuration}}"' + arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=${{parameters.CommitHead}};Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"' diff --git a/eng/pipelines/common/templates/steps/publish-symbols-step.yml b/eng/pipelines/common/templates/steps/publish-symbols-step.yml index 8dbb89db33..ea48c87ab8 100644 --- a/eng/pipelines/common/templates/steps/publish-symbols-step.yml +++ b/eng/pipelines/common/templates/steps/publish-symbols-step.yml @@ -11,19 +11,53 @@ parameters: type: string default: '$(PublishSymbols)' + - name: symbolsVersion + type: string + default: '$(NuGetPackageVersion)' + + - name: referenceType + default: project + values: + - project + - package + + - name: product + default: MDS + values: + - MDS + - AKV + - MSS + steps: - powershell: 'Write-Host "##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{parameters.SymAccount}}"' displayName: 'Update Symbol.AccountName ${{parameters.SymAccount}}' -- task: PublishSymbols@2 - displayName: 'Publish symbols path' - inputs: - SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\Project\bin' - SearchPattern: | - Windows_NT/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb - Unix/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb - IndexSources: false - SymbolServerType: TeamServices - SymbolsMaximumWaitTime: 60 - SymbolsProduct: Microsoft.Data.SqlClient - SymbolsVersion: '$(NuGetPackageVersion)' - condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) + +- ${{ if eq(parameters.product, 'MDS') }}: + - task: PublishSymbols@2 + displayName: 'Publish symbols path' + inputs: + SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\${{parameters.referenceType }}\bin' + SearchPattern: | + Windows_NT/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb + Unix/$(Configuration).AnyCPU/**/Microsoft.Data.SqlClient.pdb + IndexSources: false + SymbolServerType: TeamServices + SymbolsMaximumWaitTime: 60 + SymbolsProduct: Microsoft.Data.SqlClient + SymbolsVersion: '{{parameters.symbolsVersion }}' + condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) + +- ${{ if eq(parameters.product, 'AKV') }}: + - task: PublishSymbols@2 + displayName: 'Publish symbols path' + inputs: + SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\${{parameters.referenceType }}\bin' + SearchPattern: | + Windows_NT/$(Configuration).AnyCPU/AzureKeyVaultProvider/**/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.pdb + AnyOS/$(Configuration).AnyCPU/AzureKeyVaultProvider/**/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.pdb + IndexSources: false + SymbolServerType: TeamServices + SymbolsMaximumWaitTime: 60 + SymbolsProduct: Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider + SymbolsVersion: '{{parameters.symbolsVersion }}' + condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) diff --git a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml index c9c1f9d8db..4d64fc502d 100644 --- a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml +++ b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml @@ -5,7 +5,27 @@ ################################################################################# name: $(Year:YY)$(DayOfYear)$(Rev:.rr) -trigger: none # https://aka.ms/obpipelines/triggers +trigger: + branches: + include: + - internal/main + paths: + exclude: + - src + - eng + - tools + - .config + - build.proj + - Nuget.config + - '*.cmd' + - '*.sh' + +schedules: +- cron: '30 21 * * 0' + displayName: Weekly Sunday 9:30 pm Build + branches: + include: + - internal/main parameters: # parameters are shown up in ADO UI in a build queue time - name: 'debug' @@ -16,7 +36,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time variables: - template: /eng/pipelines/libraries/variables.yml@self - name: packageFolderName - value: drop_build_build_signed_package + value: drop_buildMDS_build_signed_package resources: repositories: @@ -70,17 +90,24 @@ extends: tsaOptionsPath: $(REPOROOT)\.config\tsaoptions.json disableLegacyManifest: true stages: - - stage: build + - stage: buildAKV + jobs: + - template: eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml@self + parameters: + symbolsFolder: $(symbolsFolder) + softwareFolder: $(softwareFolder) + + - stage: buildMDS jobs: - template: eng/pipelines/common/templates/jobs/build-signed-package-job.yml@self parameters: symbolsFolder: $(symbolsFolder) softwareFolder: $(softwareFolder) - + - stage: package_validation - dependsOn: build + dependsOn: buildMDS jobs: - - template: eng/pipelines/common/templates/jobs/verify-signed-package-job.yml@self + - template: eng/pipelines/common/templates/jobs/validate-signed-package-job.yml@self parameters: packageFolderName: $(packageFolderName) downloadPackageStep: @@ -88,6 +115,7 @@ extends: artifact: $(packageFolderName) patterns: '**/*.*nupkg' displayName: 'Download NuGet Package' + - template: eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml@self parameters: packageFolderName: $(packageFolderName) diff --git a/eng/pipelines/libraries/akv-variables.yml b/eng/pipelines/libraries/akv-variables.yml new file mode 100644 index 0000000000..259ae19dba --- /dev/null +++ b/eng/pipelines/libraries/akv-variables.yml @@ -0,0 +1,15 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# + +variables: + - group: AKV Release Variables + + - name: AKVNugetPackageVersion + value: $(AKVMajor).$(AKVMinor).$(AKVPatch) + - name: AKVAssemblyFileVersion + value: '$(AKVMajor).$(AKVMinor)$(AKVPatch).$(Build.BuildNumber)' + - name: akvNuspecPath + value: tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec diff --git a/eng/pipelines/libraries/build-variables.yml b/eng/pipelines/libraries/build-variables.yml index 613c03a02b..1c26f26a69 100644 --- a/eng/pipelines/libraries/build-variables.yml +++ b/eng/pipelines/libraries/build-variables.yml @@ -5,22 +5,6 @@ ################################################################################# variables: - - group: Release Variables - - name: NugetPackageVersion - value: $(Major).$(Minor).$(Patch) - - name: AssemblyFileVersion - value: '$(Major).$(Minor)$(Patch).$(Build.BuildNumber)' - - name: Configuration - value: Release - - name: CommitHead - value: '' # the value will be extracted from the repo's head - - name: REPOROOT - value: $(Build.SourcesDirectory) - - name: nuspecPath - value: '$(REPOROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec' - - name: softwareFolder - value: $(REPOROOT)/software - - name: symbolsFolder - value: $(REPOROOT)/symbols - - name: artifactDirectory - value: '$(REPOROOT)/packages' + - template: common-variables.yml@self + - template: akv-variables.yml@self + - template: mds-variables.yml@self diff --git a/eng/pipelines/libraries/common-variables.yml b/eng/pipelines/libraries/common-variables.yml new file mode 100644 index 0000000000..fb85f70d36 --- /dev/null +++ b/eng/pipelines/libraries/common-variables.yml @@ -0,0 +1,19 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# + +variables: + - name: Configuration + value: Release + - name: CommitHead + value: '' # the value will be extracted from the repo's head + - name: REPOROOT + value: $(Build.SourcesDirectory) + - name: softwareFolder + value: $(REPOROOT)/software + - name: symbolsFolder + value: $(REPOROOT)/symbols + - name: artifactDirectory + value: '$(REPOROOT)/packages' diff --git a/eng/pipelines/libraries/validation-variables.yml b/eng/pipelines/libraries/mds-validation-variables.yml similarity index 94% rename from eng/pipelines/libraries/validation-variables.yml rename to eng/pipelines/libraries/mds-validation-variables.yml index 32c008ef89..3c711364a3 100644 --- a/eng/pipelines/libraries/validation-variables.yml +++ b/eng/pipelines/libraries/mds-validation-variables.yml @@ -5,7 +5,9 @@ ################################################################################# variables: - - template: build-variables.yml@self + - template: common-variables.yml@self + - template: mds-variables.yml@self + - name: TempFolderName # extract the nuget package here value: temp - name: extractedNugetPath diff --git a/eng/pipelines/libraries/mds-variables.yml b/eng/pipelines/libraries/mds-variables.yml new file mode 100644 index 0000000000..3da3172fa3 --- /dev/null +++ b/eng/pipelines/libraries/mds-variables.yml @@ -0,0 +1,15 @@ +################################################################################# +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################# + +variables: + - group: Release Variables + + - name: NugetPackageVersion + value: $(Major).$(Minor).$(Patch) + - name: AssemblyFileVersion + value: '$(Major).$(Minor)$(Patch).$(Build.BuildNumber)' + - name: nuspecPath + value: '$(REPOROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec' diff --git a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec index 6c2ea69cbf..b651ad91b8 100644 --- a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec +++ b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec @@ -58,42 +58,42 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti - - - - - + + + + + - - - + + + - - - + + + - + - - - + + + - - - + + + - + - - - + + + - - - + + + - + From abff6630e79ed9fa15c63355a88a5f90819ba199 Mon Sep 17 00:00:00 2001 From: MerlinBot Date: Wed, 17 Apr 2024 15:42:10 +0000 Subject: [PATCH 30/53] Merge pull request 4357 from dependabot/docker/dotnet_docker_images/1708216907 into internal/main --- .../tests/Docker/DockerLinuxTest/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/Docker/DockerLinuxTest/Dockerfile b/src/Microsoft.Data.SqlClient/tests/Docker/DockerLinuxTest/Dockerfile index 04640c06a5..4d48876e33 100644 --- a/src/Microsoft.Data.SqlClient/tests/Docker/DockerLinuxTest/Dockerfile +++ b/src/Microsoft.Data.SqlClient/tests/Docker/DockerLinuxTest/Dockerfile @@ -1,9 +1,9 @@ #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. -FROM mcr.microsoft.com/dotnet/runtime:8.0@sha256:bb9e61f07f93945ab97391b1dcbcc41136b03310583f36e52b3ec2815111e58a AS base +FROM mcr.microsoft.com/dotnet/runtime:8.0@sha256:113324d7d68c23885ee6ce61f192f5cd2bed7a42d80a2038f26538b5653a1250 AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:8.0@sha256:8e77ad6fb7c33c17f026424d3bef05ea2ee15d1621e28f312adeab4dc1005866 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.101@sha256:1b99a629b4f55a496db835d9c3347737aa4a1d995d43ffe5ab92d04bee69adeb AS build WORKDIR /sqlclient COPY . . From 68d35bb5f116feb2fd10f6b0b2d09a4a835562d5 Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Thu, 18 Apr 2024 15:35:25 -0500 Subject: [PATCH 31/53] Change | Simplify Conditional File Inclusion (#2425) * Wrap files in appropriate `#if` and simplify project file * Sorting file includes * Pulling over changes from a different branch from before rebase * Merge changes that should've come in during merge ... * Add true * Change that should've been brought in on merge :thinking: --- .../Windows/Kernel32/Interop.CloseHandle.cs | 4 + .../src/Interop/Unix/Interop.Libraries.cs | 4 + .../Interop.GssApiException.cs | 6 +- .../Interop.GssBuffer.cs | 6 +- .../Interop.NetSecurityNative.cs | 5 +- .../Windows/Crypt32/Interop.certificates.cs | 4 + .../Crypt32/Interop.certificates_types.cs | 4 + .../SChannel/Interop.SECURITY_STATUS.cs | 4 + .../SChannel/SecPkgContext_ConnectionInfo.cs | 5 +- .../src/Interop/Windows/sspicli/GlobalSSPI.cs | 4 + .../Interop/Windows/sspicli/Interop.SSPI.cs | 4 + .../Windows/sspicli/NegotiationInfoClass.cs | 4 + .../Interop/Windows/sspicli/SSPIAuthType.cs | 4 + .../Interop/Windows/sspicli/SSPIInterface.cs | 4 + .../Windows/sspicli/SSPISecureChannelType.cs | 4 + .../Interop/Windows/sspicli/SSPIWrapper.cs | 4 + .../Windows/sspicli/SafeDeleteContext.cs | 6 +- .../Windows/sspicli/SecPkgContext_Bindings.cs | 4 + .../sspicli/SecPkgContext_NegotiationInfoW.cs | 4 + .../Windows/sspicli/SecPkgContext_Sizes.cs | 5 +- .../sspicli/SecPkgContext_StreamSizes.cs | 5 +- .../Windows/sspicli/SecurityPackageInfo.cs | 4 + .../sspicli/SecurityPackageInfoClass.cs | 4 + .../Windows/sspicli/SecuritySafeHandles.cs | 5 +- .../Win32/SafeHandles/GssSafeHandles.cs | 4 + .../Generic/BidirectionalDictionary.cs | 4 + .../System/Net/ContextFlagsAdapterPal.Unix.cs | 4 +- .../Net/ContextFlagsAdapterPal.Windows.cs | 4 +- .../Common/src/System/Net/ContextFlagsPal.cs | 4 +- .../DebugCriticalHandleMinusOneIsInvalid.cs | 6 +- ...ugCriticalHandleZeroOrMinusOneIsInvalid.cs | 6 +- .../Common/src/System/Net/DebugSafeHandle.cs | 7 +- .../System/Net/Logging/DebugThreadTracking.cs | 4 + .../src/System/Net/NegotiationInfoClass.cs | 4 + .../Net/Security/NegotiateStreamPal.Unix.cs | 4 + .../Security/NegotiateStreamPal.Windows.cs | 4 + .../NetEventSource.Security.Windows.cs | 4 + .../Net/Security/NetEventSource.Security.cs | 8 +- .../src/System/Net/Security/SecurityBuffer.cs | 5 +- .../System/Net/Security/SecurityBufferType.cs | 4 + .../Security/SecurityContextTokenHandle.cs | 5 +- .../Net/Security/Unix/SafeDeleteContext.cs | 4 + .../Security/Unix/SafeDeleteNegoContext.cs | 4 + .../Net/Security/Unix/SafeFreeCredentials.cs | 4 + .../Security/Unix/SafeFreeNegoCredentials.cs | 4 + .../Net/SecurityStatusAdapterPal.Windows.cs | 4 + .../src/System/Net/SecurityStatusPal.cs | 4 + .../src/Microsoft.Data.SqlClient.csproj | 571 ++++++++---------- .../DbConnectionPool.NetCoreApp.cs | 7 +- ...waysEncryptedKeyConverter.CrossPlatform.cs | 4 + .../Data/SqlClient/SNI/SNIStreams.Task.cs | 4 + .../SqlClient/SNI/SNIStreams.ValueTask.cs | 4 + .../SNI/SslOverTdsStream.NetCoreApp.cs | 4 + .../SNI/SslOverTdsStream.NetStandard.cs | 4 + .../SqlClient/SNI/SspiClientContextStatus.cs | 4 + ...uthenticationProviderManager.NetCoreApp.cs | 4 + ...thenticationProviderManager.NetStandard.cs | 4 + .../SqlClientEventSource.NetCoreApp.cs | 4 + .../SqlClient/SqlClientFactory.NetCoreApp.cs | 4 + ...umnEncryptionEnclaveProvider.NetCoreApp.cs | 4 + ...qlConnectionFactory.AssemblyLoadContext.cs | 6 +- .../SqlDelegatedTransaction.NetCoreApp.cs | 6 +- .../SqlDelegatedTransaction.NetStandard.cs | 6 +- .../Data/SqlClient/TdsParser.NetCoreApp.cs | 4 + .../Data/SqlClient/TdsParser.NetStandard.cs | 4 + .../AlwaysEncryptedEnclaveProviderUtils.cs | 4 + .../AzureAttestationBasedEnclaveProvider.cs | 4 + .../Data/SqlClient/EnclaveDelegate.Crypto.cs | 4 + .../SqlClient/EnclaveDelegate.NotSupported.cs | 5 +- .../Data/SqlClient/EnclaveProviderBase.cs | 4 + .../Data/SqlClient/EnclaveSessionCache.cs | 9 +- .../NoneAttestationEnclaveProvider.cs | 4 + .../SqlBatchCommand.Net8OrGreater.cs | 4 + .../SqlDependencyUtils.AssemblyLoadContext.cs | 4 + .../SqlEnclaveAttestationParameters.Crypto.cs | 4 + ...claveAttestationParameters.NotSupported.cs | 4 + .../VirtualSecureModeEnclaveProvider.cs | 4 + .../VirtualSecureModeEnclaveProviderBase.cs | 4 + 78 files changed, 578 insertions(+), 340 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/CoreLib/Interop/Windows/Kernel32/Interop.CloseHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/CoreLib/Interop/Windows/Kernel32/Interop.CloseHandle.cs index ff41f939f1..f133f10156 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/CoreLib/Interop/Windows/Kernel32/Interop.CloseHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/CoreLib/Interop/Windows/Kernel32/Interop.CloseHandle.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 !NET8_0_OR_GREATER + using System; using System.Runtime.InteropServices; @@ -13,3 +15,5 @@ internal partial class Kernel32 internal static extern bool CloseHandle(IntPtr handle); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/Interop.Libraries.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/Interop.Libraries.cs index c4f2f36493..7b74001a4f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/Interop.Libraries.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/Interop.Libraries.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 !NET8_0_OR_GREATER + internal static partial class Interop { internal static partial class Libraries @@ -10,3 +12,5 @@ internal static partial class Libraries internal const string NetSecurityNative = "System.Net.Security.Native"; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs index b08b41aeb2..34bc0b18dd 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Data; +#if !NET8_0_OR_GREATER + using System; using System.Runtime.InteropServices; +using Microsoft.Data; internal static partial class Interop { @@ -56,3 +58,5 @@ private static string GetGssApiDisplayStatus(Status status, bool isMinor) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs index 0f479a8c62..112289bc7d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs @@ -2,10 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Data; +#if !NET8_0_OR_GREATER + using System; using System.Diagnostics; using System.Runtime.InteropServices; +using Microsoft.Data; internal static partial class Interop { @@ -74,3 +76,5 @@ static GssBuffer() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs index 489d1cf8a9..f5e7d18f24 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.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 !NET8_0_OR_GREATER + using System; -using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; @@ -126,3 +127,5 @@ static NetSecurityNative() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates.cs index 2fb8e48a1d..6b8e616894 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates.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 !NET8_0_OR_GREATER + using System; using System.Runtime.InteropServices; @@ -24,3 +26,5 @@ internal static extern bool CertVerifyCertificateChainPolicy( [In, Out] ref CERT_CHAIN_POLICY_STATUS pPolicyStatus); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs index cbf5c3309e..c120f1ba71 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Crypt32/Interop.certificates_types.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 !NET8_0_OR_GREATER + using System; using System.Runtime.InteropServices; @@ -125,3 +127,5 @@ internal unsafe struct CERT_CHAIN_POLICY_STATUS } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs index 435de74c59..dfd98621d6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.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 !NET8_0_OR_GREATER + internal static partial class Interop { internal enum SECURITY_STATUS @@ -358,3 +360,5 @@ internal static string MapSecurityStatus(uint statusCode) } #endif // TRACE_VERBOSE } + +#endif // !NET8_OR_GREATER diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs index 57b6eb3405..762c3ea146 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.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. -using System.Diagnostics; +#if !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -45,3 +46,5 @@ internal unsafe SecPkgContext_ConnectionInfo(byte[] nativeBuffer) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/GlobalSSPI.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/GlobalSSPI.cs index 78571c5c96..6077ba5a77 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/GlobalSSPI.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/GlobalSSPI.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 !NET8_0_OR_GREATER + namespace System.Net { internal static class GlobalSSPI @@ -10,3 +12,5 @@ internal static class GlobalSSPI internal static readonly SSPIInterface SSPISecureChannel = new SSPISecureChannelType(); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs index 8ceed0e870..bb8d1ede6a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.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 !NET8_0_OR_GREATER + using System; using System.Net.Security; using System.Runtime.InteropServices; @@ -388,3 +390,5 @@ internal static extern unsafe SECURITY_STATUS SspiEncodeStringsAsAuthIdentity( [Out] out SafeSspiAuthDataHandle authData); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/NegotiationInfoClass.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/NegotiationInfoClass.cs index f5f7ab1b07..133c935174 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/NegotiationInfoClass.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/NegotiationInfoClass.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 !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -59,3 +61,5 @@ internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs index cdb3819605..4a86701ffd 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.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 !NET8_0_OR_GREATER + using System.Net.Security; using System.Runtime.InteropServices; using Microsoft.Data; @@ -199,3 +201,5 @@ public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs index 655dcec07a..22e9a3c93d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIInterface.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 !NET8_0_OR_GREATER + using System.Net.Security; using System.Runtime.InteropServices; @@ -30,3 +32,5 @@ internal interface SSPIInterface int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs index 4152a89a7d..e6c213d241 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.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 !NET8_0_OR_GREATER + using System.Net.Security; using System.Runtime.InteropServices; using Microsoft.Data; @@ -155,3 +157,5 @@ public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs index f8231f9069..389cd83df3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.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 !NET8_0_OR_GREATER + using System.ComponentModel; using System.Globalization; using System.Net.Security; @@ -595,3 +597,5 @@ public static string ErrorDescription(int errorCode) } } // class SSPIWrapper } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SafeDeleteContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SafeDeleteContext.cs index cc9f80164f..7701689286 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SafeDeleteContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SafeDeleteContext.cs @@ -2,11 +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 !NET8_0_OR_GREATER -using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Authentication.ExtendedProtection; namespace System.Net.Security { @@ -53,3 +51,5 @@ public override string ToString() #endif } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs index eb31544de1..f5bbb448eb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.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 !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -14,3 +16,5 @@ internal struct SecPkgContext_Bindings internal IntPtr Bindings; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs index 4dc03b53a6..a5c71068eb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.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 !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -14,3 +16,5 @@ internal struct SecPkgContext_NegotiationInfoW internal uint NegotiationState; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs index 48cdd54d2a..17fce36c6d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.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. -using System.Diagnostics; +#if !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -40,3 +41,5 @@ internal unsafe SecPkgContext_Sizes(byte[] memory) public static readonly int SizeOf = Marshal.SizeOf(); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs index 519b607da7..98ec1a1d60 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.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. -using System.Diagnostics; +#if !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -42,3 +43,5 @@ internal unsafe SecPkgContext_StreamSizes(byte[] memory) public static readonly int SizeOf = Marshal.SizeOf(); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfo.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfo.cs index 3ec3c7fda6..73e9c8635c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfo.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfo.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 !NET8_0_OR_GREATER + using System.Runtime.InteropServices; namespace System.Net @@ -18,3 +20,5 @@ internal struct SecurityPackageInfo internal IntPtr Comment; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfoClass.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfoClass.cs index 74fca62e89..433904171e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfoClass.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecurityPackageInfoClass.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 !NET8_0_OR_GREATER + using System.Globalization; using System.Runtime.InteropServices; @@ -76,3 +78,5 @@ public override string ToString() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs index f78b10697d..428e0e39eb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs @@ -2,12 +2,13 @@ // 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 !NET8_0_OR_GREATER using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using System.Security.Authentication.ExtendedProtection; +using Microsoft.Win32.SafeHandles; namespace System.Net.Security { @@ -1279,3 +1280,5 @@ protected override bool ReleaseHandle() } } } + +#endif // !NET8_OR_GREATER diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Win32/SafeHandles/GssSafeHandles.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Win32/SafeHandles/GssSafeHandles.cs index 6921ef6aba..6a5a8b17c8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Win32/SafeHandles/GssSafeHandles.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Win32/SafeHandles/GssSafeHandles.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 !NET8_0_OR_GREATER + using System; using System.Diagnostics; using System.Runtime.InteropServices; @@ -135,3 +137,5 @@ protected override bool ReleaseHandle() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Collections/Generic/BidirectionalDictionary.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Collections/Generic/BidirectionalDictionary.cs index 32c4463433..2bf8459e1b 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Collections/Generic/BidirectionalDictionary.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Collections/Generic/BidirectionalDictionary.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 !NET8_0_OR_GREATER + using System.Diagnostics; namespace System.Collections.Generic @@ -59,3 +61,5 @@ IEnumerator IEnumerable.GetEnumerator() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Unix.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Unix.cs index 599bd4ab7d..148e0bb76d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Unix.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.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. -using System; +#if !NET8_0_OR_GREATER namespace System.Net { @@ -84,3 +84,5 @@ internal static Interop.NetSecurityNative.GssFlags GetInteropFromContextFlagsPal } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Windows.cs index 5ed6e347d8..036f24d4ed 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsAdapterPal.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. -using System; +#if !NET8_0_OR_GREATER namespace System.Net { @@ -75,3 +75,5 @@ internal static Interop.SspiCli.ContextFlags GetInteropFromContextFlagsPal(Conte } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsPal.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsPal.cs index d4df40b597..f0df3bd677 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsPal.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/ContextFlagsPal.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. -using System; +#if !NET8_0_OR_GREATER namespace System.Net { @@ -33,3 +33,5 @@ internal enum ContextFlagsPal UnverifiedTargetName = 0x20000000, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs index 1949341de2..a9d0965324 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if DEBUG && !NET8_0_OR_GREATER + using Microsoft.Win32.SafeHandles; namespace System.Net { -#if DEBUG // // This is a helper class for debugging GC-ed handles that we define. // As a general rule normal code path should always destroy handles explicitly @@ -38,5 +39,6 @@ private void Trace() NetEventSource.Info(this, _trace); } } -#endif // DEBUG } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs index c28a7107b1..fcb485d568 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if DEBUG && !NET8_0_OR_GREATER + using Microsoft.Win32.SafeHandles; namespace System.Net { -#if DEBUG // // This is a helper class for debugging GC-ed handles that we define. // As a general rule normal code path should always destroy handles explicitly @@ -38,5 +39,6 @@ private void Trace() NetEventSource.Info(this, _trace); } } -#endif // DEBUG } + +#endif // !NET8_0_OR_GREATER diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugSafeHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugSafeHandle.cs index b0646f92e9..55d5bd8a6f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugSafeHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/DebugSafeHandle.cs @@ -2,17 +2,17 @@ // 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 DEBUG && !NET8_0_OR_GREATER using System.Net.NetworkInformation; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using Microsoft.Win32.SafeHandles; namespace System.Net { -#if DEBUG // // This is a helper class for debugging GC-ed handles that we define. // As a general rule normal code path should always destroy handles explicitly @@ -47,5 +47,6 @@ private void Trace() NetEventSource.Info(this, _trace); } } -#endif // DEBUG } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/DebugThreadTracking.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/DebugThreadTracking.cs index 78d8d48ac6..cd66ff2287 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/DebugThreadTracking.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/DebugThreadTracking.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 !NET8_0_OR_GREATER + using System.Collections.Generic; namespace System.Net @@ -162,3 +164,5 @@ internal enum ThreadKinds ThreadPool = CompletionPort | Worker, // Like Thread.CurrentThread.IsThreadPoolThread } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/NegotiationInfoClass.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/NegotiationInfoClass.cs index 560098ef4c..d931c7c70d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/NegotiationInfoClass.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/NegotiationInfoClass.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 !NET8_0_OR_GREATER + namespace System.Net { // This class is used to determine if NTLM or @@ -14,3 +16,5 @@ internal partial class NegotiationInfoClass internal const string Basic = "Basic"; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs index 70c1a74377..f670a086cf 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.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 !NET8_0_OR_GREATER + using System.ComponentModel; using System.Diagnostics; using Microsoft.Win32.SafeHandles; @@ -246,3 +248,5 @@ internal static SafeFreeCredentials AcquireCredentialsHandle(string package, boo } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs index fe56d8ed91..2ce87ac951 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NegotiateStreamPal.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 !NET8_0_OR_GREATER + using System.Globalization; using System.ComponentModel; using Microsoft.Data; @@ -215,3 +217,5 @@ internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buff } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.Windows.cs index f229b6845a..e28cc18296 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.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 !NET8_0_OR_GREATER + using System.Diagnostics.Tracing; using System.Net.Security; @@ -88,3 +90,5 @@ public void SecurityContextInputBuffers(string context, int inputBuffersSize, in } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.cs index b003ce8b7e..e785fe016d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/NetEventSource.Security.cs @@ -2,11 +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 !NET8_0_OR_GREATER + using System.Diagnostics.Tracing; -using System.Globalization; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; namespace System.Net { @@ -34,3 +32,5 @@ public void SspiPackageNotFound(string packageName) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBuffer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBuffer.cs index b507449f1e..54c060a6e1 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBuffer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBuffer.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. -using System.Diagnostics; +#if !NET8_0_OR_GREATER + using System.Runtime.InteropServices; using System.Security.Authentication.ExtendedProtection; @@ -61,3 +62,5 @@ public SecurityBuffer(ChannelBinding binding) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBufferType.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBufferType.cs index 51174938a1..ca29feac84 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBufferType.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityBufferType.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 !NET8_0_OR_GREATER + namespace System.Net.Security { // sspi.h @@ -26,3 +28,5 @@ internal enum SecurityBufferType SECBUFFER_READONLY_WITH_CHECKSUM = 0x10000000 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityContextTokenHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityContextTokenHandle.cs index 00e5b3ac60..3d146e5bcc 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityContextTokenHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/SecurityContextTokenHandle.cs @@ -2,9 +2,10 @@ // 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 !NET8_0_OR_GREATER using System.Threading; +using Microsoft.Win32.SafeHandles; namespace System.Net.Security { @@ -39,3 +40,5 @@ protected override bool ReleaseHandle() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs index c3c75790b9..16636afd29 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteContext.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 !NET8_0_OR_GREATER + using System.Diagnostics; using System.Runtime.InteropServices; @@ -44,3 +46,5 @@ protected override bool ReleaseHandle() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs index b98e9ac80b..53fe8e5ad9 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.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 !NET8_0_OR_GREATER + using System.Diagnostics; using Microsoft.Win32.SafeHandles; @@ -75,3 +77,5 @@ protected override void Dispose(bool disposing) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeCredentials.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeCredentials.cs index 51d6869a8d..254d9d127a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeCredentials.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeCredentials.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 !NET8_0_OR_GREATER + using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; @@ -71,3 +73,5 @@ protected override bool ReleaseHandle() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs index 217c787619..19ad2e2451 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.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 !NET8_0_OR_GREATER + using System.Diagnostics; using Microsoft.Win32.SafeHandles; @@ -84,3 +86,5 @@ protected override bool ReleaseHandle() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusAdapterPal.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusAdapterPal.Windows.cs index b7ce1e6b1e..c3b13d549f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusAdapterPal.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusAdapterPal.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 !NET8_0_OR_GREATER + using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -101,3 +103,5 @@ internal static Interop.SECURITY_STATUS GetInteropFromSecurityStatusPal(Security } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusPal.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusPal.cs index 54b380e74f..5bbe78bd00 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusPal.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/SecurityStatusPal.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 !NET8_0_OR_GREATER + namespace System.Net { internal readonly struct SecurityStatusPal @@ -71,3 +73,5 @@ internal enum SecurityStatusPalErrorCode ApplicationProtocolMismatch } } + +#endif 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 f2827967b1..122fcaa089 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -30,6 +30,49 @@ + + Common\CoreLib\System\Threading\Tasks\TaskToApm.cs + + + Common\Microsoft\Data\ProviderBase\DbConnectionClosed.cs + + + Common\Microsoft\Data\ProviderBase\DbConnectionFactory.cs + + + Common\Microsoft\Data\ProviderBase\DbConnectionInternal.cs + + + Common\System\Net\ContextFlagsPal.cs + + + Common\System\Net\DebugCriticalHandleMinusOneIsInvalid.cs + + + Common\System\Net\DebugSafeHandle.cs + + + Common\System\Net\InternalException.cs + + + Common\System\Net\Logging\DebugThreadTracking.cs + + + Common\System\Net\Logging\NetEventSource.Common.cs + + + Common\System\Net\NegotiationInfoClass.cs + + + Common\System\Net\Security\SecurityBuffer.cs + + + Common\System\Net\Security\SecurityBufferType.cs + + + Common\System\Net\SecurityStatusPal.cs + + Microsoft\Data\Common\ActivityCorrelator.cs @@ -81,6 +124,9 @@ Microsoft\Data\ProviderBase\DbMetaDataFactory.cs + + Common\Microsoft\Data\ProviderBase\DbReferenceCollection.cs + Microsoft\Data\ProviderBase\FieldNameLookup.cs @@ -105,12 +151,18 @@ Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationTimeoutRetryHelper.cs + + Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs + Microsoft\Data\SqlClient\ApplicationIntent.cs Microsoft\Data\SqlClient\AssemblyRef.cs + + Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs + Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs @@ -123,12 +175,27 @@ Microsoft\Data\SqlClient\EnclaveDelegate.cs + + Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs + + + Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs + Microsoft\Data\SqlClient\EnclavePackage.cs + + Microsoft\Data\SqlClient\EnclaveProviderBase.cs + + + Microsoft\Data\SqlClient\EnclaveSessionCache.cs + Microsoft\Data\SqlClient\LocalAppContextSwitches.cs + + Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs + Microsoft\Data\SqlClient\OnChangedEventHandler.cs @@ -177,9 +244,6 @@ Microsoft\Data\SqlClient\RowsCopiedEventHandler.cs - - Microsoft\Data\SqlClient\SqlSequentialTextReader.cs - Microsoft\Data\SqlClient\Server\ExtendedClrTypeCode.cs @@ -246,8 +310,8 @@ Microsoft\Data\SqlClient\Server\SqlRecordBuffer.cs - - Microsoft\Data\SqlClient\SqlTransaction.Common.cs + + Microsoft\Data\SqlClient\Server\SqlSer.cs Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs @@ -273,9 +337,6 @@ Microsoft\Data\SqlClient\SqlAuthenticationProvider.cs - - Microsoft\Data\SqlClient\SqlBuffer.cs - Microsoft\Data\SqlClient\SqlAuthenticationToken.cs @@ -285,9 +346,15 @@ Microsoft\Data\SqlClient\SqlBatchCommand.cs + + Microsoft\Data\SqlClient\SqlBatchCommand.Net8OrGreater.cs + Microsoft\Data\SqlClient\SqlBatchCommandCollection.cs + + Microsoft\Data\SqlClient\SqlBuffer.cs + Microsoft\Data\SqlClient\SqlBulkCopyColumnMapping.cs @@ -333,12 +400,12 @@ Microsoft\Data\SqlClient\SqlCollation.cs - - Microsoft\Data\SqlClient\SqlColumnEncryptionKeyStoreProvider.cs - Microsoft\Data\SqlClient\SqlCommandBuilder.cs + + Microsoft\Data\SqlClient\SqlColumnEncryptionKeyStoreProvider.cs + Microsoft\Data\SqlClient\SqlCommandSet.cs @@ -384,6 +451,15 @@ Microsoft\Data\SqlClient\SqlDependencyUtils.AppDomain.cs + + Microsoft\Data\SqlClient\SqlDependencyUtils.AssemblyLoadContext.cs + + + Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs + + + Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs + Microsoft\Data\SqlClient\SqlEnclaveSession.cs @@ -465,12 +541,15 @@ Microsoft\Data\SqlClient\SqlSequentialStream.cs - - Microsoft\Data\SqlClient\Server\SqlSer.cs + + Microsoft\Data\SqlClient\SqlSequentialTextReader.cs Microsoft\Data\SqlClient\SqlStatistics.cs + + Microsoft\Data\SqlClient\SqlStream.cs + Microsoft\Data\SqlClient\SqlSymmetricKeyCache.cs @@ -480,12 +559,27 @@ Microsoft\Data\SqlClient\SqlUtil.cs + + Microsoft\Data\SqlClient\SqlTransaction.Common.cs + + + Microsoft\Data\SqlClient\SSPI\ManagedSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\NegotiateSSPIContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\SSPIContextProvider.cs + Microsoft\Data\SqlClient\TdsEnums.cs Microsoft\Data\SqlClient\TdsParameterSetter.cs + + Microsoft\Data\SqlClient\TdsParser.cs + Microsoft\Data\SqlClient\TdsParserStateObject.cs @@ -501,16 +595,19 @@ Microsoft\Data\SqlClient\TdsValueSetter.cs + + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs + + + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs + Microsoft\Data\SQLTypes\SQLResource.cs Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs - - Microsoft\Data\SqlClient\SqlStream.cs - - + Resources\ResCategoryAttribute.cs @@ -519,132 +616,23 @@ Common\System\Diagnostics\CodeAnalysis.cs - - Microsoft\Data\SqlClient\SSPI\ManagedSSPIContextProvider.cs - - - Microsoft\Data\SqlClient\SSPI\NegotiateSSPIContextProvider.cs - - - Microsoft\Data\SqlClient\SSPI\SSPIContextProvider.cs - - - Microsoft\Data\SqlClient\TdsParser.cs - - - Microsoft\Data\ProviderBase\DbReferenceCollection.cs - - - - - - - - Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs - - - Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs - - - - - - - - - - - - Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs - - - Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs - - - Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs - - - Microsoft\Data\SqlClient\EnclaveProviderBase.cs - - - Microsoft\Data\SqlClient\EnclaveSessionCache.cs - - - Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs - - - Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs - - - Microsoft\Data\SqlClient\NoneAttestationEnclaveProvider.cs - - - Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs - - - - - - - - - - - - - Microsoft\Data\SqlClient\SqlDependencyUtils.AssemblyLoadContext.cs - - - - - - - Resources\StringsHelper.cs - - - Resources\Strings.Designer.cs - True - True - Strings.resx - - - Resources\Strings.resx - Microsoft.Data.SqlClient.Resources.Strings.resources - ResXFileCodeGenerator - Strings.Designer.cs - System - - - Resources\%(RecursiveDir)%(Filename)%(Extension) - - - - - Common\CoreLib\System\Threading\Tasks\TaskToApm.cs - - - Common\Microsoft\Data\ProviderBase\DbConnectionClosed.cs - - - Common\Microsoft\Data\ProviderBase\DbConnectionFactory.cs - - - Common\Microsoft\Data\ProviderBase\DbConnectionInternal.cs - - + + + + @@ -654,16 +642,26 @@ + + - + + + + + + + + + @@ -671,68 +669,55 @@ + + + + - - - + + - - Microsoft\Data\Common\AdapterUtil.Windows.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs - - - - - - Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs - - - - - - Microsoft\Data\Common\AdapterUtil.Unix.cs - - - - - - - - - - - - - Common\CoreLib\Interop\Windows\kernel32\Interop.FileTypes.cs + + Common\CoreLib\Interop\Windows\kernel32\Interop.FileTypes.cs Common\CoreLib\Interop\Windows\kernel32\Interop.GetFileType_SafeHandle.cs + + Common\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs + Common\CoreLib\Interop\Windows\kernel32\Interop.SetThreadErrorMode.cs + + Common\CoreLib\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs + Common\CoreLib\System\IO\PathInternal.Windows.cs + + Common\Interop\Windows\Crypt32\Interop.certificates.cs + + + Common\Interop\Windows\Crypt32\Interop.certificates_types.cs + Common\Interop\Windows\Interop.Errors.cs + + Common\Interop\Windows\Interop.Libraries.cs + Common\Interop\Windows\Interop.UNICODE_STRING.cs @@ -742,6 +727,12 @@ Common\Interop\Windows\Kernel32\Interop.DeviceIoControl.cs + + Common\Interop\Windows\kernel32\Interop.FreeLibrary.cs + + + Common\Interop\Windows\kernel32\Interop.GetProcAddress.cs + Common\Interop\Windows\Kernel32\Interop.IoControlCodeAccess.cs @@ -760,89 +751,6 @@ Common\Interop\Windows\NtDll\Interop.RtlNtStatusToDosError.cs - - - - - - - - - - - - - - - - - - - - - - Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs - - - Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs - - - - - - - - - - - Common\CoreLib\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs - - - Common\Interop\Windows\kernel32\Interop.FreeLibrary.cs - - - Common\Interop\Windows\kernel32\Interop.GetProcAddress.cs - - - - - - - Common\Interop\Windows\Interop.Libraries.cs - - - - - - Common\System\Net\InternalException.cs - - - Common\System\Net\Logging\NetEventSource.Common.cs - - - - - - - - - - - - - - - - - - Common\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs - - - Common\Interop\Windows\Crypt32\Interop.certificates.cs - - - Common\Interop\Windows\Crypt32\Interop.certificates_types.cs - Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs @@ -852,30 +760,6 @@ Common\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs - - Common\System\Collections\Generic\BidirectionalDictionary.cs - - - Common\System\Net\ContextFlagsAdapterPal.Windows.cs - - - Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs - - - Common\System\Net\Security\SecurityContextTokenHandle.cs - - - Common\System\Net\SecurityStatusAdapterPal.Windows.cs - - - Common\System\Net\Security\NegotiateStreamPal.Windows.cs - - - Common\System\Net\Security\NetEventSource.Security.cs - - - Common\System\Net\Security\NetEventSource.Security.Windows.cs - Common\Interop\Windows\sspicli\GlobalSSPI.cs @@ -921,37 +805,56 @@ Common\Interop\Windows\sspicli\SSPIWrapper.cs - - - - - Common\System\Net\ContextFlagsPal.cs + + Common\System\Collections\Generic\BidirectionalDictionary.cs - - Common\System\Net\DebugCriticalHandleMinusOneIsInvalid.cs + + Common\System\Net\ContextFlagsAdapterPal.Windows.cs - - Common\System\Net\DebugSafeHandle.cs + + Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs - - Common\System\Net\Logging\DebugThreadTracking.cs + + Common\System\Net\Security\NegotiateStreamPal.Windows.cs - - Common\System\Net\NegotiationInfoClass.cs + + Common\System\Net\Security\NetEventSource.Security.cs - - Common\System\Net\Security\SecurityBuffer.cs + + Common\System\Net\Security\NetEventSource.Security.Windows.cs - - Common\System\Net\Security\SecurityBufferType.cs + + Common\System\Net\Security\SecurityContextTokenHandle.cs - - Common\System\Net\SecurityStatusPal.cs + + Common\System\Net\SecurityStatusAdapterPal.Windows.cs - + + + Microsoft\Data\Common\AdapterUtil.Windows.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs + + + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs + + + + + + + + + + - - + + + Common\Interop\Unix\Interop.Libraries.cs @@ -985,24 +888,82 @@ Common\System\Net\Security\NegotiateStreamPal.Unix.cs + + + Microsoft\Data\Common\AdapterUtil.Unix.cs + + + + + + + + + + + + + + + - - + + + + + + + + - - - Microsoft\Data\SqlClient\SqlBatchCommand.Net8OrGreater.cs + + + + + Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs + + Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs + + + + + + + - - - - + + + + Resources\StringsHelper.cs + + + Resources\Strings.Designer.cs + True + True + Strings.resx + + + Resources\Strings.resx + Microsoft.Data.SqlClient.Resources.Strings.resources + ResXFileCodeGenerator + Strings.Designer.cs + System + + + Resources\%(RecursiveDir)%(Filename)%(Extension) + Microsoft.Data.SqlClient.SqlMetaData.xml + + + + + + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs index c85d042b2a..9f330c3dcc 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs @@ -2,14 +2,15 @@ // 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 NETCOREAPP + using System.Diagnostics; using Microsoft.Data.Common; using Microsoft.Data.SqlClient; namespace Microsoft.Data.ProviderBase { - sealed internal partial class DbConnectionPool + internal sealed partial class DbConnectionPool { private bool IsBlockingPeriodEnabled() { @@ -44,3 +45,5 @@ private bool IsBlockingPeriodEnabled() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs index 8b3def875c..81b90debeb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.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 !NETSTANDARD2_0 + using System; using System.Diagnostics; using System.Security.Cryptography; @@ -133,3 +135,5 @@ internal static RSA GetRSAFromCertificate(X509Certificate2 certificate) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs index a1bf4a9e0e..399c43cb9b 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.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 NETSTANDARD2_0 + using System.Threading; using System.Threading.Tasks; @@ -91,3 +93,5 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs index f5f38f0efe..03b071eac2 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.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 !NETSTANDARD2_0 + using System.Threading; using System.Threading.Tasks; using System; @@ -107,3 +109,5 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs index be8d1a0160..655fc91d7c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.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 !NETSTANDARD2_0 + using System; using System.Buffers; using System.Threading; @@ -293,3 +295,5 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs index 60bb597974..e411c2955e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.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 NETSTANDARD2_0 + using System; using System.Buffers; using System.IO; @@ -221,3 +223,5 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SspiClientContextStatus.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SspiClientContextStatus.cs index b557bfa0be..d9aabab16b 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SspiClientContextStatus.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SspiClientContextStatus.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 !NET8_0_OR_GREATER + using System.Net; using System.Net.Security; @@ -28,3 +30,5 @@ public ContextFlagsPal ContextFlags } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs index dd57c60da8..9170614927 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.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 !NETSTANDARD2_0 + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -195,3 +197,5 @@ internal class SqlClientAuthenticationProviderConfigurationSection : SqlAuthenti } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs index 01a84342f8..0fa64d0cef 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.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 NETSTANDARD2_0 + namespace Microsoft.Data.SqlClient { internal partial class SqlAuthenticationProviderManager @@ -13,3 +15,5 @@ static SqlAuthenticationProviderManager() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs index c0312ca219..6dc531f766 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.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 !NETSTANDARD2_0 + using System; using System.Diagnostics.Tracing; using System.Threading; @@ -394,3 +396,5 @@ internal override void ReclaimedConnectionRequest() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs index 4b0d4a8b2d..a48179b621 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs @@ -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 NET6_0_OR_GREATER + using System.Data.Common; namespace Microsoft.Data.SqlClient @@ -18,3 +20,5 @@ public sealed partial class SqlClientFactory : DbProviderFactory public override DbBatchCommand CreateBatchCommand() => new SqlBatchCommand(); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs index fd81db557d..da5a516004 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.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 !NETSTANDARD2_0 + using System.Security.Cryptography; namespace Microsoft.Data.SqlClient @@ -23,3 +25,5 @@ internal abstract void CreateEnclaveSession(byte[] enclaveAttestationInfo, ECDif out SqlEnclaveSession sqlEnclaveSession, out long counter); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs index 7338b8d4d2..38411594af 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs @@ -2,13 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NETCOREAPP + using System; using System.Reflection; using System.Runtime.Loader; namespace Microsoft.Data.SqlClient { - sealed internal partial class SqlConnectionFactory + internal sealed partial class SqlConnectionFactory { partial void SubscribeToAssemblyLoadContextUnload() { @@ -21,3 +23,5 @@ private void SqlConnectionFactoryAssemblyLoadContext_Unloading(AssemblyLoadConte } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs index c4655c4355..ea27ceabe0 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs @@ -2,15 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if !NETSTANDARD2_0 + using System; using System.Transactions; namespace Microsoft.Data.SqlClient { - sealed internal partial class SqlDelegatedTransaction : IPromotableSinglePhaseNotification + internal sealed partial class SqlDelegatedTransaction : IPromotableSinglePhaseNotification { // Get the server-side Global Transaction Id from the PromotedDTCToken // Skip first 4 bytes since they contain the version private Guid GetGlobalTxnIdentifierFromToken() => new Guid(new ReadOnlySpan(_connection.PromotedDTCToken, _globalTransactionsTokenVersionSizeInBytes, 16)); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs index cb97c4d677..ba50ca5d14 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs @@ -2,12 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NETSTANDARD2_0 + using System; using System.Transactions; namespace Microsoft.Data.SqlClient { - sealed internal partial class SqlDelegatedTransaction : IPromotableSinglePhaseNotification + internal sealed partial class SqlDelegatedTransaction : IPromotableSinglePhaseNotification { // Get the server-side Global Transaction Id from the PromotedDTCToken // Skip first 4 bytes since they contain the version @@ -20,3 +22,5 @@ private Guid GetGlobalTxnIdentifierFromToken() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs index 95dd0d9731..2c7554a0cb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.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 !NETSTANDARD2_0 + using System; using System.Diagnostics; using System.Buffers.Binary; @@ -23,3 +25,5 @@ internal static Guid ConstructGuid(ReadOnlySpan bytes) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs index 72c0b77b19..2327f92b72 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.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 NETSTANDARD2_0 + using System; using System.Buffers; using System.Diagnostics; @@ -39,3 +41,5 @@ internal static Guid ConstructGuid(ReadOnlySpan bytes) } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs index ff84ab3310..890af0206f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.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 !NETSTANDARD2_0 + using System; namespace Microsoft.Data.SqlClient @@ -49,3 +51,5 @@ internal enum EnclaveType Sgx = 2 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs index 7b1b2bf2e4..70f6bc5f91 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.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 !NETSTANDARD2_0 + using System; using System.Collections.Generic; using System.Diagnostics; @@ -540,3 +542,5 @@ private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, byte[] nonce, #endregion } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs index db1bdea90f..fc87127b04 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.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 !NETSTANDARD2_0 + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -211,3 +213,5 @@ internal byte[] GetSerializedAttestationParameters(SqlEnclaveAttestationParamete } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs index 461bfdf6d7..3c3afac335 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs @@ -2,9 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if NETSTANDARD2_0 + using System; using System.Collections.Concurrent; -using System.Collections.Generic; namespace Microsoft.Data.SqlClient { @@ -54,3 +55,5 @@ internal SqlEnclaveAttestationParameters GetAttestationParameters(SqlConnectionA } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs index b8a52b9e4b..1a2bcaeb03 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.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 !NETSTANDARD2_0 + using System; using System.Runtime.Caching; using System.Security.Cryptography; @@ -213,3 +215,5 @@ protected SqlEnclaveSession AddEnclaveSessionToCache(EnclaveSessionParameters en } #endregion } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs index f76191fec8..d60c3ad5ba 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.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 !NETSTANDARD2_0 + using System; using System.Runtime.Caching; using System.Threading; @@ -12,7 +14,7 @@ namespace Microsoft.Data.SqlClient internal class EnclaveSessionCache { private readonly MemoryCache enclaveMemoryCache = new MemoryCache("EnclaveMemoryCache"); - private readonly Object enclaveCacheLock = new Object(); + private readonly object enclaveCacheLock = new object(); // Nonce for each message sent by the client to the server to prevent replay attacks by the server, // given that for Always Encrypted scenarios, the server is considered an "untrusted" man-in-the-middle. @@ -37,8 +39,7 @@ internal void InvalidateSession(EnclaveSessionParameters enclaveSessionParameter lock (enclaveCacheLock) { - long counter; - SqlEnclaveSession enclaveSession = GetEnclaveSession(enclaveSessionParameters, out counter); + SqlEnclaveSession enclaveSession = GetEnclaveSession(enclaveSessionParameters, out _); if (enclaveSession != null && enclaveSession.SessionId == enclaveSessionToInvalidate.SessionId) { @@ -73,3 +74,5 @@ private string GenerateCacheKey(EnclaveSessionParameters enclaveSessionParameter } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs index fabd69c976..9ef8a77d19 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.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 !NETSTANDARD2_0 + using System; using System.Diagnostics; using System.Security.Cryptography; @@ -104,3 +106,5 @@ internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclave } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.cs index d31480afc7..d81a378ecf 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.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 NET8_0_OR_GREATER + using System.Data.Common; namespace Microsoft.Data.SqlClient @@ -15,3 +17,5 @@ public partial class SqlBatchCommand public override bool CanCreateParameter => true; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs index 47f62fc5ac..c3f82f0047 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs @@ -2,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 NETCOREAPP + using System; using System.Reflection; using System.Runtime.Loader; @@ -24,3 +26,5 @@ private void SqlDependencyPerAppDomainDispatcher_Unloading(AssemblyLoadContext o } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs index c2e9739237..2abb408d41 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.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 !NETSTANDARD2_0 + using System; using System.Security.Cryptography; @@ -50,3 +52,5 @@ internal byte[] GetInput() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs index 0ae67d4a94..64d5d19655 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.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 NETSTANDARD2_0 + namespace Microsoft.Data.SqlClient { /// @@ -17,3 +19,5 @@ internal byte[] GetInput() } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs index fd180d12d6..7ebad456f5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.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 !NETSTANDARD2_0 + using System; using System.Collections.Generic; using System.Diagnostics; @@ -468,3 +470,5 @@ public static byte[] TakeBytesAndAdvance(byte[] input, ref int offset, int count } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index cfbe531e82..c60dd01c72 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.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 !NETSTANDARD2_0 + using System; using System.Runtime.Caching; using System.Security.Cryptography; @@ -419,3 +421,5 @@ private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, EnclaveDiffieH #endregion } } + +#endif From 3f3380ccde46102987e527be18b26aee3e9b2026 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Thu, 25 Apr 2024 12:25:42 -0700 Subject: [PATCH 32/53] Test | Address XUnit failure on Windows Principal functionality is not supported on this platform (#2469) --- .../SqlColumnEncryptionCertificateStoreProviderShould.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs index 31c3504d84..79956e78d5 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/SqlColumnEncryptionCertificateStoreProviderShould.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Security.Principal; using System.Text; @@ -495,22 +496,24 @@ public override IEnumerable GetData(MethodInfo testMethod) { yield return new object[2] { StoreLocation.CurrentUser, CurrentUserMyPathPrefix }; // use localmachine cert path only when current user is Admin. - if (CertificateFixture.IsAdmin) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && CertificateFixture.IsAdmin) { yield return new object[2] { StoreLocation.LocalMachine, LocalMachineMyPathPrefix }; } } } + public class ValidCertificatePathsParameters : DataAttribute { + public override IEnumerable GetData(MethodInfo testMethod) { yield return new object[2] { CurrentUserMyPathPrefix, StoreLocation.CurrentUser }; yield return new object[2] { MyPathPrefix, null }; yield return new object[2] { @"", null }; // use localmachine cert path only when current user is Admin. - if (CertificateFixture.IsAdmin) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && CertificateFixture.IsAdmin) { yield return new object[2] { LocalMachineMyPathPrefix, StoreLocation.LocalMachine }; } @@ -653,7 +656,7 @@ public CertificateFixture() AddCertificateToStore(certificate1, StoreLocation.CurrentUser); AddCertificateToStore(certificate2, StoreLocation.CurrentUser); AddCertificateToStore(certificate3, StoreLocation.CurrentUser); - if (IsAdmin) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && IsAdmin) { AddCertificateToStore(certificate3, StoreLocation.LocalMachine); } From c33bde24d4b68116938423c728903ebb3fa74b34 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Fri, 26 Apr 2024 11:12:08 -0700 Subject: [PATCH 33/53] Change | Updating Azure.Identity version to 1.11.2 (#2462) --- tools/props/Versions.props | 8 ++++---- tools/specs/Microsoft.Data.SqlClient.nuspec | 20 +++++++++---------- ...waysEncrypted.AzureKeyVaultProvider.nuspec | 8 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/props/Versions.props b/tools/props/Versions.props index 222ad1c1e6..f0695ec8fc 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -27,8 +27,8 @@ - 1.10.3 - 4.56.0 + 1.11.2 + 4.60.3 7.5.0 7.5.0 4.5.1 @@ -55,8 +55,8 @@ - [1.35.0,2.0.0) - [4.4.0,5.0.0) + [1.38.0,2.0.0) + [4.5.0,5.0.0) 6.0.1 diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index c2c4353999..ca4d10abf7 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -29,8 +29,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -40,8 +40,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -50,8 +50,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -60,8 +60,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + @@ -78,8 +78,8 @@ When using NuGet 3.x this package requires at least version 3.4. - - + + diff --git a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec index b651ad91b8..33be2b3409 100644 --- a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec +++ b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec @@ -26,25 +26,25 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti - + - + - + - + From f05be20efe40d356f6313f810123a2e5870714dc Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Fri, 26 Apr 2024 20:34:02 +0000 Subject: [PATCH 34/53] Merged PR 4529: eng | fix a few issues and improvements - Fixed a typo, publish symbols, and commit number - Updated the cron for daily run in case of any code changes, besides the weekly run - Added parameters instead of pipeline's variables - TSA, SBOM, and CodeQL tools moved out of the `syncSdl` for compatibility with OneBranch's NonOfficial template Related work items: #29920 --- .../jobs/build-signed-akv-package-job.yml | 14 +++++ .../jobs/build-signed-package-job.yml | 7 +++ .../steps/generate-nuget-package-step.yml | 6 +- .../templates/steps/publish-symbols-step.yml | 7 ++- .../dotnet-sqlclient-signing-pipeline.yml | 56 ++++++++++++++----- 5 files changed, 69 insertions(+), 21 deletions(-) diff --git a/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml index ecd07a41c9..617f61811f 100644 --- a/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml +++ b/eng/pipelines/common/templates/jobs/build-signed-akv-package-job.yml @@ -3,6 +3,18 @@ # The .NET Foundation licenses this file to you under the MIT license. # # See the LICENSE file in the project root for more information. # ################################################################################# +parameters: + - name: symbolsFolder + type: string + default: symbols + + - name: softwareFolder + type: string + default: software + + - name: publishSymbols + type: boolean + jobs: - job: build_signed_akv_package pool: @@ -54,6 +66,7 @@ jobs: referenceType: package symbolsVersion: ${{variables.AKVNuGetPackageVersion }} product: AKV + publishSymbols: ${{ parameters['PublishSymbols'] }} # Publish symbols to public server - template: ../steps/publish-symbols-step.yml@self @@ -62,3 +75,4 @@ jobs: referenceType: package symbolsVersion: ${{variables.AKVNuGetPackageVersion }} product: AKV + publishSymbols: ${{ parameters['PublishSymbols'] }} diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml index 26ab9fa236..6a11dbadba 100644 --- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml @@ -7,10 +7,14 @@ parameters: - name: symbolsFolder type: string default: symbols + - name: softwareFolder type: string default: software + - name: publishSymbols + type: boolean + jobs: - job: build_signed_package pool: @@ -49,7 +53,10 @@ jobs: - template: ../steps/publish-symbols-step.yml@self parameters: SymAccount: $(PrivateSymAccount) + publishSymbols: ${{ parameters['PublishSymbols'] }} + # Publish symbols to public server - template: ../steps/publish-symbols-step.yml@self parameters: SymAccount: $(PublicSymAccount) + publishSymbols: ${{ parameters['PublishSymbols'] }} diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml index 3736c0e828..d97229089a 100644 --- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml +++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml @@ -4,10 +4,6 @@ # See the LICENSE file in the project root for more information. # ################################################################################# parameters: - - name: CommitHead - type: string - default: '' # the value will grab from the repo's head - - name: nuspecPath type: string default: '$(nuspecPath)' @@ -43,4 +39,4 @@ steps: displayName: 'NuGet pack with snupkg' inputs: command: custom - arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=${{parameters.CommitHead}};Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"' + arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"' diff --git a/eng/pipelines/common/templates/steps/publish-symbols-step.yml b/eng/pipelines/common/templates/steps/publish-symbols-step.yml index ea48c87ab8..5898fddd4a 100644 --- a/eng/pipelines/common/templates/steps/publish-symbols-step.yml +++ b/eng/pipelines/common/templates/steps/publish-symbols-step.yml @@ -7,7 +7,7 @@ parameters: - name: SymAccount type: string - - name: PublishSymbols + - name: publishSymbols type: string default: '$(PublishSymbols)' @@ -31,6 +31,7 @@ parameters: steps: - powershell: 'Write-Host "##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{parameters.SymAccount}}"' displayName: 'Update Symbol.AccountName ${{parameters.SymAccount}}' + condition: and(succeeded(), ${{ eq(parameters.publishSymbols, 'true') }}) - ${{ if eq(parameters.product, 'MDS') }}: - task: PublishSymbols@2 @@ -45,7 +46,7 @@ steps: SymbolsMaximumWaitTime: 60 SymbolsProduct: Microsoft.Data.SqlClient SymbolsVersion: '{{parameters.symbolsVersion }}' - condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) + condition: and(succeeded(), ${{ eq(parameters.publishSymbols, 'true') }}) - ${{ if eq(parameters.product, 'AKV') }}: - task: PublishSymbols@2 @@ -60,4 +61,4 @@ steps: SymbolsMaximumWaitTime: 60 SymbolsProduct: Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider SymbolsVersion: '{{parameters.symbolsVersion }}' - condition: and(succeeded(), eq('${{ parameters.PublishSymbols }}', 'true')) + condition: and(succeeded(), ${{ eq(parameters.publishSymbols, 'true') }}) diff --git a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml index 4d64fc502d..1ec608f2a6 100644 --- a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml +++ b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml @@ -10,7 +10,7 @@ trigger: include: - internal/main paths: - exclude: + include: - src - eng - tools @@ -21,8 +21,15 @@ trigger: - '*.sh' schedules: -- cron: '30 21 * * 0' - displayName: Weekly Sunday 9:30 pm Build +- cron: '30 4 * * Mon' + displayName: Weekly Sunday 9:30 PM (UTC - 7) Build + branches: + include: + - internal/main + always: true + +- cron: '30 3 * * Mon-Fri' + displayName: Mon-Fri 8:30 PM (UTC - 7) Build branches: include: - internal/main @@ -33,10 +40,31 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: boolean default: true +- name: publishSymbols + displayName: 'Publish symbols' + type: boolean + default: false +- name: MDS_PackageRef_Version + displayName: 'MDS package version of AKV Provider (build AKV)' + type: string + default: 5.1.5 +- name: CurrentNetFxVersion + displayName: 'Lowest supported .NET Framework version (MDS validation)' + type: string + default: 'net462' + variables: - template: /eng/pipelines/libraries/variables.yml@self - name: packageFolderName value: drop_buildMDS_build_signed_package + - name: PublishSymbols + value: ${{ parameters['publishSymbols'] }} + - name: MDS_PackageRef_Version + value: ${{ parameters['MDS_PackageRef_Version'] }} + - name: CurrentNetFxVersion + value: ${{ parameters['CurrentNetFxVersion'] }} + - name: ProductVersion #MDS product version (MDS validation) + value: $(NUGETPACKAGEVERSION) resources: repositories: @@ -57,10 +85,17 @@ extends: symbolsFolder: $(symbolsFolder) softwarename: Microsoft.Data.SqlClient versionNumber: $(AssemblyFileVersion) + tsa: + enabled: true # onebranch publish all sdl results to TSA. If TSA is disabled all SDL tools will forced into 'break' build mode. + codeql: + compiled: + enabled: true + sbom: + enabled: true + packageName: Microsoft.Data.SqlClient + packageVersion: $(NugetPackageVersion) asyncSdl: - enabled: false - tsa: - enabled: true # onebranch publish all sdl results to TSA. If TSA is disabled all SDL tools will forced into 'break' build mode. + enabled: false credscan: enabled: true suppressionsFile: $(REPOROOT)/.config/CredScanSuppressions.json @@ -80,13 +115,6 @@ extends: break: true publishLogs: enabled: true - sbom: - enabled: true - packageName: Microsoft.Data.SqlClient - pacakgeVersion: $(NugetPackageVersion) - codeql: - compiled: - enabled: true tsaOptionsPath: $(REPOROOT)\.config\tsaoptions.json disableLegacyManifest: true stages: @@ -96,6 +124,7 @@ extends: parameters: symbolsFolder: $(symbolsFolder) softwareFolder: $(softwareFolder) + publishSymbols: ${{ parameters['publishSymbols'] }} - stage: buildMDS jobs: @@ -103,6 +132,7 @@ extends: parameters: symbolsFolder: $(symbolsFolder) softwareFolder: $(softwareFolder) + publishSymbols: ${{ parameters['publishSymbols'] }} - stage: package_validation dependsOn: buildMDS From aefd723026e75e68cea6bc98173404a5c765ab60 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Tue, 30 Apr 2024 11:00:01 -0700 Subject: [PATCH 35/53] Test | Updating tests to acquire token from user-assigned managed identity (#2473) --- BUILDGUIDE.md | 2 -- .../ManualTests/AlwaysEncrypted/AKVUnitTests.cs | 13 ++++--------- .../TestFixtures/Setup/CertificateUtility.cs | 3 +-- .../ManualTests/DataCommon/DataTestUtility.cs | 15 ++++++++++----- .../DataCommon/SqlClientCustomTokenCredential.cs | 4 +--- .../Config.cs | 2 -- .../config.default.json | 2 -- 7 files changed, 16 insertions(+), 25 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 4434af3f1a..2061e136ea 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -176,8 +176,6 @@ Manual Tests require the below setup to run: |AADSecurePrincipalSecret | (Optional) A Secret defined for a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Secret} | |AzureKeyVaultURL | (Optional) Azure Key Vault Identifier URL | `https://{keyvaultname}.vault.azure.net/` | |AzureKeyVaultTenantId | (Optional) The Azure Active Directory tenant (directory) Id of the service principal. | _{Tenant ID of Active Directory}_ | - |AzureKeyVaultClientId | (Optional) "Application (client) ID" of an Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL`. Requires the key permissions Get, List, Import, Decrypt, Encrypt, Unwrap, Wrap, Verify, and Sign. | _{Client Application ID}_ | - |AzureKeyVaultClientSecret | (Optional) "Client Secret" of the Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL` | _{Client Application Secret}_ | |SupportsIntegratedSecurity | (Optional) Whether or not the USER running tests has integrated security access to the target SQL Server.| `true` OR `false`| |LocalDbAppName | (Optional) If Local Db Testing is supported, this property configures the name of Local DB App instance available in client environment. Empty string value disables Local Db testing. | Name of Local Db App to connect to.| |LocalDbSharedInstanceName | (Optional) If LocalDB testing is supported and the instance is shared, this property configures the name of the shared instance of LocalDB to connect to. | Name of shared instance of LocalDB. | diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs index 85192076fc..9374b3783c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs @@ -3,12 +3,10 @@ // See the LICENSE file in the project root for more information. using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider; -using Azure.Identity; using Xunit; using Azure.Security.KeyVault.Keys; using System.Reflection; using System; -using System.Linq; using System.Collections.Generic; using System.Threading; using System.Diagnostics.Tracing; @@ -86,8 +84,7 @@ public static void TokenCredentialTest() Guid activityId = Trace.CorrelationManager.ActivityId = Guid.NewGuid(); using DataTestUtility.AKVEventListener AKVListener = new(); - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); byte[] encryptedCek = akvProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, s_columnEncryptionKey); byte[] decryptedCek = akvProvider.DecryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, encryptedCek); @@ -104,8 +101,7 @@ public static void TokenCredentialRotationTest() // SqlClientCustomTokenCredential implements a legacy authentication callback to request the access token from the client-side. SqlColumnEncryptionAzureKeyVaultProvider oldAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(new SqlClientCustomTokenCredential()); - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - SqlColumnEncryptionAzureKeyVaultProvider newAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider newAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); byte[] encryptedCekWithNewProvider = newAkvProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, s_columnEncryptionKey); byte[] decryptedCekWithOldProvider = oldAkvProvider.DecryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, encryptedCekWithNewProvider); @@ -129,15 +125,14 @@ public static void ReturnSpecifiedVersionOfKeyWhenItIsNotTheMostRecentVersion() { string keyName = keyPathUri.Segments[2]; string keyVersion = keyPathUri.Segments[3]; - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - KeyClient keyClient = new KeyClient(vaultUri, clientSecretCredential); + KeyClient keyClient = new KeyClient(vaultUri, DataTestUtility.GetTokenCredential()); KeyVaultKey currentVersionKey = keyClient.GetKey(keyName); KeyVaultKey specifiedVersionKey = keyClient.GetKey(keyName, keyVersion); //If specified versioned key is the most recent version of the key then we cannot test. if (!KeyIsLatestVersion(specifiedVersionKey, currentVersionKey)) { - SqlColumnEncryptionAzureKeyVaultProvider azureKeyProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider azureKeyProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); // Perform an operation to initialize the internal caches azureKeyProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVOriginalUrl, EncryptionAlgorithm, s_columnEncryptionKey); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs index 1c054f3769..3d3c717b31 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs @@ -141,8 +141,7 @@ internal static X509Certificate2 CreateCertificate() private static async Task SetupAKVKeysAsync() { - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - KeyClient keyClient = new KeyClient(DataTestUtility.AKVBaseUri, clientSecretCredential); + KeyClient keyClient = new KeyClient(DataTestUtility.AKVBaseUri, DataTestUtility.GetTokenCredential()); AsyncPageable keys = keyClient.GetPropertiesOfKeysAsync(); IAsyncEnumerator enumerator = keys.GetAsyncEnumerator(); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index d588761bdb..06209e1ad2 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -22,6 +22,8 @@ using System.Text; using System.Security.Principal; using System.Runtime.InteropServices; +using Azure.Identity; +using Azure.Core; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -41,8 +43,6 @@ public static class DataTestUtility public static readonly string AKVUrl = null; public static readonly string AKVOriginalUrl = null; public static readonly string AKVTenantId = null; - public static readonly string AKVClientId = null; - public static readonly string AKVClientSecret = null; public static readonly string LocalDbAppName = null; public static readonly string LocalDbSharedInstanceName = null; public static List AEConnStrings = new List(); @@ -194,8 +194,6 @@ static DataTestUtility() } AKVTenantId = c.AzureKeyVaultTenantId; - AKVClientId = c.AzureKeyVaultClientId; - AKVClientSecret = c.AzureKeyVaultClientSecret; if (EnclaveEnabled) { @@ -458,7 +456,14 @@ public static bool IsNotAzureServer() // Ref: https://feedback.azure.com/forums/307516-azure-synapse-analytics/suggestions/17858869-support-always-encrypted-in-sql-data-warehouse public static bool IsAKVSetupAvailable() { - return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(AKVClientId) && !string.IsNullOrEmpty(AKVClientSecret) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse(); + return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(UserManagedIdentityClientId) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse(); + } + + private static readonly DefaultAzureCredential s_defaultCredential = new(new DefaultAzureCredentialOptions { ManagedIdentityClientId = UserManagedIdentityClientId }); + + public static TokenCredential GetTokenCredential() + { + return s_defaultCredential; } public static bool IsTargetReadyForAeWithKeyStore() diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index 8b1ef93e61..eb276493a7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -106,9 +106,7 @@ public static async Task AzureActiveDirectoryAuthenticationCallback string authorityHost = authority.Remove(separatorIndex + 1); string audience = authority.Substring(separatorIndex + 1); TokenCredentialOptions tokenCredentialOptions = new TokenCredentialOptions() { AuthorityHost = new Uri(authorityHost) }; - ClientSecretCredential clientSecretCredential = s_clientSecretCredentials.GetOrAdd(authority + "|--|" + resource, - new ClientSecretCredential(audience, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret, tokenCredentialOptions)); - AccessToken accessToken = await clientSecretCredential.GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + AccessToken accessToken = await DataTestUtility.GetTokenCredential().GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); return accessToken; } } diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs index 49c368c790..14dcd5e086 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs @@ -22,8 +22,6 @@ public class Config public string AADServicePrincipalSecret = null; public string AzureKeyVaultURL = null; public string AzureKeyVaultTenantId = null; - public string AzureKeyVaultClientId = null; - public string AzureKeyVaultClientSecret = null; public string LocalDbAppName = null; public string LocalDbSharedInstanceName = null; public bool EnclaveEnabled = false; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index 411f4ad88f..f656c3ae15 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -13,8 +13,6 @@ "AADServicePrincipalSecret": "", "AzureKeyVaultURL": "", "AzureKeyVaultTenantId": "", - "AzureKeyVaultClientId": "", - "AzureKeyVaultClientSecret": "", "SupportsIntegratedSecurity": true, "LocalDbAppName": "", "LocalDbSharedInstanceName": "", From 226bdb8e4cedd3933ca415a91d69b8c814b5b9df Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Thu, 2 May 2024 09:50:38 -0700 Subject: [PATCH 36/53] Fix | Fix DateTimeOffset size in TdsValueSetter.cs class file. (#2453) --- .../Data/SqlClient/TdsValueSetter.cs | 30 +++- ....Data.SqlClient.ManualTesting.Tests.csproj | 1 + .../SQL/UdtTest/UdtDateTimeOffsetTest.cs | 143 ++++++++++++++++++ 3 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtDateTimeOffsetTest.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs index f2c33824a2..dc797ced8e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs @@ -697,10 +697,34 @@ internal void SetDateTimeOffset(DateTimeOffset value) short offset = (short)value.Offset.TotalMinutes; #if NETCOREAPP - Span result = stackalloc byte[9]; + // In TDS protocol: + // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/786f5b8a-f87d-4980-9070-b9b7274c681d + // + // date is represented as one 3 - byte unsigned integer that represents the number of days since January 1, year 1. + // + // time(n) is represented as one unsigned integer that represents the number of 10^-n, + // (10 to the power of negative n), second increments since 12 AM within a day. + // The length, in bytes, of that integer depends on the scale n as follows: + // 3 bytes if 0 <= n < = 2. + // 4 bytes if 3 <= n < = 4. + // 5 bytes if 5 <= n < = 7. + // For example: + // DateTimeOffset dateTimeOffset = new DateTimeOffset(2024, 1, 1, 23, 59, 59, TimeSpan.Zero); // using scale of 0 + // time = 23:59:59, scale is 1, is represented as 863990 in 3 bytes or { 246, 46, 13, 0, 0, 0, 0, 0 } in bytes array + + Span result = stackalloc byte[8]; + + // https://learn.microsoft.com/en-us/dotnet/api/system.buffers.binary.binaryprimitives.writeint64bigendian?view=net-8.0 + // WriteInt64LittleEndian requires 8 bytes to write the value. BinaryPrimitives.WriteInt64LittleEndian(result, time); - BinaryPrimitives.WriteInt32LittleEndian(result.Slice(5), days); - _stateObj.WriteByteSpan(result.Slice(0, 8)); + // The DateTimeOffset length is variable depending on the scale, 1 to 7, used. + // If length = 8, 8 - 5 = 3 bytes is used for time. + // If length = 10, 10 - 5 = 5 bytes is used for time. + _stateObj.WriteByteSpan(result.Slice(0, length - 5)); // this writes the time value to the state object using dynamic length based on the scale. + + // Date is represented as 3 bytes. So, 3 bytes are written to the state object. + BinaryPrimitives.WriteInt32LittleEndian(result, days); + _stateObj.WriteByteSpan(result.Slice(0, 3)); #else _stateObj.WriteByteArray(BitConverter.GetBytes(time), length - 5, 0); // time _stateObj.WriteByteArray(BitConverter.GetBytes(days), 3, 0); // date diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 1ed87d83cb..19c257001d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -204,6 +204,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtDateTimeOffsetTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtDateTimeOffsetTest.cs new file mode 100644 index 0000000000..a09d00895c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtDateTimeOffsetTest.cs @@ -0,0 +1,143 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Data; +using Microsoft.Data.SqlClient.Server; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class DateTimeOffsetList : SqlDataRecord + { + public DateTimeOffsetList(DateTimeOffset dateTimeOffset) + : base(new SqlMetaData("dateTimeOffset", SqlDbType.DateTimeOffset, 0, 1)) // this is using scale 1 + { + this.SetValues(dateTimeOffset); + } + } + + public class DateTimeOffsetVariableScale : SqlDataRecord + { + public DateTimeOffsetVariableScale(DateTimeOffset dateTimeOffset, int scale) + : base(new SqlMetaData("dateTimeOffset", SqlDbType.DateTimeOffset, 0, (byte)scale)) // this is using variable scale + { + this.SetValues(dateTimeOffset); + } + } + + public class UdtDateTimeOffsetTest + { + private readonly string _connectionString = null; + private readonly string _udtTableType = DataTestUtility.GetUniqueNameForSqlServer("DataTimeOffsetTableType"); + + public UdtDateTimeOffsetTest() + { + _connectionString = DataTestUtility.TCPConnectionString; + } + + // This unit test is for the reported issue #2423 using a specific scale of 1 + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + public void SelectFromSqlParameterShouldSucceed() + { + using SqlConnection connection = new(_connectionString); + connection.Open(); + SetupUserDefinedTableType(connection, _udtTableType); + + try + { + DateTimeOffset dateTimeOffset = new DateTimeOffset(2024, 1, 1, 23, 59, 59, 500, TimeSpan.Zero); + var param = new SqlParameter + { + ParameterName = "@params", + SqlDbType = SqlDbType.Structured, + TypeName = $"dbo.{_udtTableType}", + Value = new DateTimeOffsetList[] { new DateTimeOffsetList(dateTimeOffset) } + }; + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "SELECT * FROM @params"; + cmd.Parameters.Add(param); + var result = cmd.ExecuteScalar(); + Assert.Equal(dateTimeOffset, result); + } + } + finally + { + DataTestUtility.DropUserDefinedType(connection, _udtTableType); + } + } + + // This unit test is to ensure that time in DateTimeOffset with all scales are working as expected + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + public void DateTimeOffsetAllScalesTestShouldSucceed() + { + string tvpTypeName = DataTestUtility.GetUniqueNameForSqlServer("tvpType"); + + using SqlConnection connection = new(_connectionString); + connection.Open(); + + try + { + // Use different scale for each test: 0 to 7 + int fromScale = 0; + int toScale = 7; + + for (int scale = fromScale; scale <= toScale; scale++) + { + DateTimeOffset dateTimeOffset = new DateTimeOffset(2024, 1, 1, 23, 59, 59, TimeSpan.Zero); + + // Add sub-second offset corresponding to the scale being tested + TimeSpan subSeconds = TimeSpan.FromTicks((long)(TimeSpan.TicksPerSecond / Math.Pow(10, scale))); + dateTimeOffset = dateTimeOffset.Add(subSeconds); + + DataTestUtility.DropUserDefinedType(connection, tvpTypeName); + SetupDateTimeOffsetTableType(connection, tvpTypeName, scale); + + var param = new SqlParameter + { + ParameterName = "@params", + SqlDbType = SqlDbType.Structured, + Scale = (byte)scale, + TypeName = $"dbo.{tvpTypeName}", + Value = new DateTimeOffsetVariableScale[] { new DateTimeOffsetVariableScale(dateTimeOffset, scale) } + }; + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "SELECT * FROM @params"; + cmd.Parameters.Add(param); + var result = cmd.ExecuteScalar(); + Assert.Equal(dateTimeOffset, result); + } + } + } + finally + { + DataTestUtility.DropUserDefinedType(connection, tvpTypeName); + } + } + + private static void SetupUserDefinedTableType(SqlConnection connection, string tableTypeName) + { + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandType = CommandType.Text; + cmd.CommandText = $"CREATE TYPE {tableTypeName} AS TABLE ([Value] DATETIMEOFFSET(1) NOT NULL) "; + cmd.ExecuteNonQuery(); + } + } + + private static void SetupDateTimeOffsetTableType(SqlConnection connection, string tableTypeName, int scale) + { + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandType = CommandType.Text; + cmd.CommandText = $"CREATE TYPE {tableTypeName} AS TABLE ([Value] DATETIMEOFFSET({scale}) NOT NULL) "; + cmd.ExecuteNonQuery(); + } + } + } +} From 792479efaa7155143f3276965fac42c84de35e2e Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Fri, 3 May 2024 09:22:31 -0700 Subject: [PATCH 37/53] Test | Remove field with ClientSecretCredential (#2479) --- .../ManualTests/DataCommon/SqlClientCustomTokenCredential.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index eb276493a7..fa57a93697 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -16,7 +16,6 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests public class SqlClientCustomTokenCredential : TokenCredential { private const string DEFAULT_PREFIX = "/.default"; - private static readonly ConcurrentDictionary s_clientSecretCredentials = new(); string _authority = ""; string _resource = ""; From cd4805b144e170c946602d5c54d65ef649bce9a5 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Fri, 3 May 2024 21:42:21 +0200 Subject: [PATCH 38/53] Remove support for .NET Standard 2.0 and 2.1 (#2386) --- BUILDGUIDE.md | 10 +- RunPackageReferenceTests.cmd | 72 +----- build.proj | 14 -- src/Directory.Build.props | 4 +- src/Microsoft.Data.SqlClient.sln | 19 -- .../add-ons/Directory.Build.props | 6 +- .../Microsoft.Data.SqlClient.NetStandard.cs | 16 -- .../netcore/ref/Microsoft.Data.SqlClient.cs | 4 +- .../ref/Microsoft.Data.SqlClient.csproj | 13 +- .../src/Microsoft.Data.SqlClient.csproj | 28 +-- ...waysEncryptedKeyConverter.CrossPlatform.cs | 4 - .../Microsoft/Data/SqlClient/SNI/SNICommon.cs | 10 +- .../Microsoft/Data/SqlClient/SNI/SNIHandle.cs | 6 - .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 2 - .../Data/SqlClient/SNI/SNIStreams.Task.cs | 97 -------- .../SqlClient/SNI/SNIStreams.ValueTask.cs | 4 - .../SNI/SslOverTdsStream.NetCoreApp.cs | 4 - .../SNI/SslOverTdsStream.NetStandard.cs | 227 ------------------ ...uthenticationProviderManager.NetCoreApp.cs | 4 - ...thenticationProviderManager.NetStandard.cs | 19 -- .../SqlClientEventSource.NetCoreApp.cs | 4 - ...umnEncryptionEnclaveProvider.NetCoreApp.cs | 4 - .../SqlDelegatedTransaction.NetCoreApp.cs | 4 - .../SqlDelegatedTransaction.NetStandard.cs | 26 -- .../Data/SqlClient/TdsParser.NetCoreApp.cs | 4 - .../Data/SqlClient/TdsParser.NetStandard.cs | 45 ---- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +- .../Data/SqlTypes/SqlFileStream.Windows.cs | 4 - ...yzerExceptionList.analyzerdata.netstandard | 44 ---- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +- .../ActiveDirectoryAuthenticationProvider.cs | 37 --- .../AlwaysEncryptedEnclaveProviderUtils.cs | 4 - .../AzureAttestationBasedEnclaveProvider.cs | 4 - .../Data/SqlClient/EnclaveDelegate.Crypto.cs | 4 - .../SqlClient/EnclaveDelegate.NotSupported.cs | 59 ----- .../Data/SqlClient/EnclaveProviderBase.cs | 4 - .../Data/SqlClient/EnclaveSessionCache.cs | 4 - .../NoneAttestationEnclaveProvider.cs | 4 - .../Data/SqlClient/SqlConnectionString.cs | 2 +- .../Data/SqlClient/SqlDependencyUtils.cs | 2 +- .../SqlEnclaveAttestationParameters.Crypto.cs | 4 - ...claveAttestationParameters.NotSupported.cs | 23 -- .../Data/SqlClient/SqlInternalConnection.cs | 2 +- .../VirtualSecureModeEnclaveProvider.cs | 4 - .../VirtualSecureModeEnclaveProviderBase.cs | 4 - .../src/Resources/Strings.Designer.cs | 9 - .../src/Resources/Strings.de.resx | 8 +- .../src/Resources/Strings.es.resx | 5 +- .../src/Resources/Strings.fr.resx | 5 +- .../src/Resources/Strings.it.resx | 5 +- .../src/Resources/Strings.ja.resx | 5 +- .../src/Resources/Strings.ko.resx | 5 +- .../src/Resources/Strings.pt-BR.resx | 5 +- .../src/Resources/Strings.resx | 5 +- .../src/Resources/Strings.ru.resx | 5 +- .../src/Resources/Strings.zh-Hans.resx | 5 +- .../src/Resources/Strings.zh-Hant.resx | 5 +- .../src/System/Diagnostics/CodeAnalysis.cs | 54 ----- .../CustomRetryLogicProvider.csproj | 1 - .../tests/Directory.Build.props | 2 +- .../Microsoft.Data.SqlClient.Tests.csproj | 5 +- .../tests/FunctionalTests/SqlBufferTests.cs | 6 +- .../tests/FunctionalTests/SqlCommandTest.cs | 12 +- ....Data.SqlClient.ManualTesting.Tests.csproj | 7 +- .../SQL/UdtTest/UDTs/Address/Address.csproj | 1 - .../SQL/UdtTest/UDTs/Circle/Circle.csproj | 1 - .../SQL/UdtTest/UDTs/Shapes/Shapes.csproj | 1 - .../UdtTest/UDTs/Utf8String/Utf8String.csproj | 1 - .../Microsoft.Data.SqlClient.NSLibrary.csproj | 13 - tools/props/Versions.props | 7 +- tools/specs/Microsoft.Data.SqlClient.nuspec | 100 +------- ...waysEncrypted.AzureKeyVaultProvider.nuspec | 19 +- 72 files changed, 53 insertions(+), 1111 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetStandard.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/PinvokeAnalyzerExceptionList.analyzerdata.netstandard delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/NSLibrary/Microsoft.Data.SqlClient.NSLibrary.csproj diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 2061e136ea..5f57d70106 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -231,17 +231,15 @@ Tests can be built and run with custom "Reference Type" property that enables di - "Project" => Build and run tests with Microsoft.Data.SqlClient as Project Reference - "Package" => Build and run tests with Microsoft.Data.SqlClient as Package Reference with configured "TestMicrosoftDataSqlClientVersion" in "Versions.props" file. -- "NetStandard" => Build and run tests with Microsoft.Data.SqlClient as Project Reference via .NET Standard Library -- "NetStandardPackage" => Build and run tests with Microsoft.Data.SqlClient as Package Reference via .NET Standard Library -> ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES *************** +> ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" REFERENCE TYPE *************** > CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION > > ```bash > msbuild -p:configuration=Release > ``` -A non-AnyCPU platform reference can only be used with package and NetStandardPackage reference types. Otherwise, the specified platform will be replaced with AnyCPU in the build process. +A non-AnyCPU platform reference can only be used with package reference type. Otherwise, the specified platform will be replaced with AnyCPU in the build process. ### Building Tests with Reference Type @@ -252,10 +250,6 @@ msbuild -t:BuildTestsNetCore -p:ReferenceType=Project # Default setting uses Project Reference. msbuild -t:BuildTestsNetCore -p:ReferenceType=Package - -msbuild -t:BuildTestsNetCore -p:ReferenceType=NetStandard - -msbuild -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage ``` For .NET Framework, below reference types are supported: diff --git a/RunPackageReferenceTests.cmd b/RunPackageReferenceTests.cmd index 037d5aa84c..fa503f905e 100644 --- a/RunPackageReferenceTests.cmd +++ b/RunPackageReferenceTests.cmd @@ -1,10 +1,10 @@ @echo off -:: .NET CORE + .NET STANDARD LIBRARY TEST CASES +:: .NET CORE TEST CASES echo Building .NET Core Tests call :pauseOnError msbuild -t:Clean -:: ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES *************** +:: ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" REFERENCE TYPE *************** :: THESE ARE NOT STAND ALONE TEST COMMANDS AND NEED A DEVELOPER'S SPECIAL ATTENTION TO WORK. ATTEMPTING TO RUN THE ENTIRE SET OF COMMANDS AS-IS IS LIKELY TO FAIL! :: CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION @@ -70,74 +70,6 @@ call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:Targ call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-Win32.xml call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-Win32.xml -:: REFERENCE TYPE "NETSTANDARDPACKAGE" - -:: .NET - REFERENCE TYPE "NETSTANDARDPACKAGE" - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:TargetNetCoreVersion=net6.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-anycpu.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:TargetNetCoreVersion=net8.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-manual-anycpu.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetCoreVersion=net6.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-x64.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-x64.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetCoreVersion=net8.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-functional-x64.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-manual-x64.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetCoreVersion=net6.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-win32.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-win32.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetCoreVersion=net8.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-functional-win32.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net8.0-manual-win32.xml - -:: .NET Framework - REFERENCE TYPE "NETSTANDARDPACKAGE" - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:TargetNetFxVersion=net462 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-anycpu.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:TargetNetFxVersion=net48 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-anycpu.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetFxVersion=net462 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-x64.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-x64.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetFxVersion=net48 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-x64.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-x64.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetFxVersion=net462 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-win32.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-win32.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetFxVersion=net48 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-win32.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-win32.xml - -:: REFERENCE TYPE "NETSTANDARD" (We only build and test AnyCPU with Project Reference) -:: NUGET PACKAGE GENERATION IS NOT SUPPORTED FOR REFERNCE TYPE 'NETSTANDARD' -call :pauseOnError msbuild -p:Configuration="Release" -p:ReferenceType=NetStandard -p:GenerateNuget=false -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetCoreVersion=net6.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net6.0-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net6.0-manual-anycpu.xml - -call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetCoreVersion=net8.0 -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net8.0-functional-anycpu.xml -call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net8.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net8.0-manual-anycpu.xml - -:: TESTING 'NETSTANDARD' REFERENCE TYPE WITH .NET FRAMEWORK 4.6.2+ AS TARGET FRAMEWORK IS INVALID CASE AS PROJECT REFERENCE DOES NOT LOAD SNI.DLL IN .NET FRAMEWORK RUNTIME. -:: CASE IS VERIFIED WITH RUNTIME.NATIVE.SYSTEM.DATA.SQLCLIENT.SNI AS WELL. TO TEST .NET FRAMEWORK TARGETS, USE 'NETSTANDARDPACKAGE' REFERENCE TYPE ONLY. - goto :eof :pauseOnError diff --git a/build.proj b/build.proj index d500f48886..89b46fb761 100644 --- a/build.proj +++ b/build.proj @@ -53,7 +53,6 @@ - @@ -62,7 +61,6 @@ - @@ -219,12 +217,6 @@ - - - - - - @@ -232,10 +224,4 @@ - - - - - - diff --git a/src/Directory.Build.props b/src/Directory.Build.props index cc502f3798..1fa393eccb 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,10 +15,8 @@ "Project" => Build and run tests with Microsoft.Data.SqlClient as Project Reference "Package" => Build and run tests with Microsoft.Data.SqlClient as Package Reference with configured "TestMicrosoftDataSqlClientVersion" in "Versions.props" file. - "NetStandard" => Build and run tests with Microsoft.Data.SqlClient as Project Reference via .NET Standard Library - "NetStandardPackage" => Build and run tests with Microsoft.Data.SqlClient as Package Reference via .NET Standard Library - ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES *************** + ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" REFERENCE TYPE *************** CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION > msbuild -p:configuration=Release --> diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index d47f0a450e..04668c8f81 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -179,12 +179,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlTypes", " EndProject Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.NSLibrary", "Microsoft.Data.SqlClient\tests\NSLibrary\Microsoft.Data.SqlClient.NSLibrary.csproj", "{E7336BFB-8521-423A-A140-3123F9065C5D}" - ProjectSection(ProjectDependencies) = postProject - {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714} - {407890AC-9876-4FEF-A6F1-F36A876BAADE} = {407890AC-9876-4FEF-A6F1-F36A876BAADE} - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.TestUtilities", "Microsoft.Data.SqlClient\tests\tools\Microsoft.Data.SqlClient.TestUtilities\Microsoft.Data.SqlClient.TestUtilities.csproj", "{89D6D382-9B36-43C9-A912-03802FDA8E36}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.ExtUtilities", "Microsoft.Data.SqlClient\tests\tools\Microsoft.Data.SqlClient.ExtUtilities\Microsoft.Data.SqlClient.ExtUtilities.csproj", "{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}" @@ -410,18 +404,6 @@ Global {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x64.Build.0 = Release|Any CPU {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x86.ActiveCfg = Release|Any CPU {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x86.Build.0 = Release|Any CPU - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x64.ActiveCfg = Debug|x64 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x64.Build.0 = Debug|x64 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x86.ActiveCfg = Debug|x86 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x86.Build.0 = Debug|x86 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|Any CPU.Build.0 = Release|Any CPU - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|x64.ActiveCfg = Release|x64 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|x64.Build.0 = Release|x64 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|x86.ActiveCfg = Release|x86 - {E7336BFB-8521-423A-A140-3123F9065C5D}.Release|x86.Build.0 = Release|x86 {89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|Any CPU.Build.0 = Debug|Any CPU {89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -518,7 +500,6 @@ Global {5D1F0032-7B0D-4FB6-A969-FCFB25C9EA1D} = {71F356DC-DFA3-4163-8BFE-D268722CE189} {650EB7FA-EB0D-4F8E-AB2C-161C3AD8E363} = {71F356DC-DFA3-4163-8BFE-D268722CE189} {5A7600BD-AED8-44AB-8F2A-7CB33A8D9C02} = {71F356DC-DFA3-4163-8BFE-D268722CE189} - {E7336BFB-8521-423A-A140-3123F9065C5D} = {0CC4817A-12F3-4357-912C-09315FAAD008} {89D6D382-9B36-43C9-A912-03802FDA8E36} = {0CC4817A-12F3-4357-912C-09315FAAD008} {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B} = {0CC4817A-12F3-4357-912C-09315FAAD008} {B499E477-C9B1-4087-A5CF-5C762D90E433} = {0CC4817A-12F3-4357-912C-09315FAAD008} diff --git a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props index 3ec7e5a49c..4ec39ed694 100644 --- a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props +++ b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props @@ -17,7 +17,6 @@ net462 - netstandard2.0 net6.0 @@ -28,14 +27,13 @@ - $(TargetNetFxVersion);$(TargetNetCoreVersion);$(TargetNetStandardVersion) - $(TargetNetCoreVersion);$(TargetNetStandardVersion) + $(TargetNetCoreVersion);$(TargetNetFxVersion) + $(TargetNetCoreVersion) - netstandard2.0;netstandard2.1 net6.0;net8.0 net462 diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetStandard.cs deleted file mode 100644 index bdb2042b84..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetStandard.cs +++ /dev/null @@ -1,16 +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. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the http://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace Microsoft.Data.SqlClient -{ - /// - public sealed partial class ActiveDirectoryAuthenticationProvider : SqlAuthenticationProvider - { - /// - public void SetParentActivityOrWindowFunc(System.Func parentActivityOrWindowFunc) { } - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index ba7a1cd534..a0acf34a33 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -478,7 +478,7 @@ public static partial class SqlClientMetaDataCollectionNames /// public static readonly string StructuredTypeMembers; } -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NETCOREAPP /// public enum SqlConnectionAttestationProtocol { @@ -1017,7 +1017,7 @@ public SqlConnectionStringBuilder(string connectionString) { } [System.ComponentModel.DisplayNameAttribute("Data Source")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public string DataSource { get { throw null; } set { } } -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NETCOREAPP /// [System.ComponentModel.DisplayNameAttribute("Attestation Protocol")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj index 9ab6b8d80f..498849102a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj @@ -1,32 +1,23 @@  false - net8.0;net6.0;netstandard2.0;netstandard2.1 - netstandard2.1 + net6.0;net8.0 $(ObjFolder)$(Configuration)\$(AssemblyName)\ref\ $(BinFolder)$(Configuration)\$(AssemblyName)\ref\ $(OutputPath)\$(TargetFramework)\Microsoft.Data.SqlClient.xml Core $(BaseProduct) Debug;Release; netcoreapp - netstandard AnyCPU;x64;x86 - - - - - - - - + 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 122fcaa089..0a0f573333 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -1,8 +1,7 @@  Microsoft.Data.SqlClient - net8.0;net6.0;netstandard2.0;netstandard2.1 - netstandard2.1 + net8.0;net6.0 Microsoft.Data.SqlClient is not supported on this platform. $(OS) true @@ -10,7 +9,6 @@ false netcoreapp - netstandard Debug;Release; AnyCPU;x64;x86 $(ObjFolder)$(Configuration).$(Platform)\$(AssemblyName)\netcore\ @@ -178,9 +176,6 @@ Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs - - Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs - Microsoft\Data\SqlClient\EnclavePackage.cs @@ -457,9 +452,6 @@ Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs - - Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs - Microsoft\Data\SqlClient\SqlEnclaveSession.cs @@ -642,18 +634,15 @@ - - - @@ -670,14 +659,12 @@ - - @@ -964,19 +951,6 @@ - - - - - - - - - - - - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs index 81b90debeb..8b3def875c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Diagnostics; using System.Security.Cryptography; @@ -135,5 +133,3 @@ internal static RSA GetRSAFromCertificate(X509Certificate2 certificate) } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index 964d332ae4..9ccc98a779 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -342,11 +342,11 @@ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer ti args0: serverName, args1: remainingTimeout); using CancellationTokenSource cts = new CancellationTokenSource(remainingTimeout); - // using this overload to support netstandard - Task task = Dns.GetHostAddressesAsync(serverName); - task.ConfigureAwait(false); - task.Wait(cts.Token); - return task.Result; + + return Dns.GetHostAddressesAsync(serverName, cts.Token) + .ConfigureAwait(false) + .GetAwaiter() + .GetResult(); } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs index 354ce3eff5..515686f6a3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs @@ -19,7 +19,6 @@ internal abstract class SNIHandle { protected static readonly SslProtocols s_supportedProtocols = SslProtocols.None; -#if !NETSTANDARD2_0 protected static readonly List s_tdsProtocols = new List(1) { new(TdsEnums.TDS8_Protocol) }; protected static async Task AuthenticateAsClientAsync(SslStream sslStream, string serverNameIndication, X509CertificateCollection certificate, CancellationToken token) @@ -32,15 +31,10 @@ protected static async Task AuthenticateAsClientAsync(SslStream sslStream, strin }; await sslStream.AuthenticateAsClientAsync(sslClientOptions, token); } -#endif protected static void AuthenticateAsClient(SslStream sslStream, string serverNameIndication, X509CertificateCollection certificate) { -#if !NETSTANDARD2_0 AuthenticateAsClientAsync(sslStream, serverNameIndication, certificate, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); -#else - throw new NotSupportedException(Strings.SQL_TDS8_NotSupported_Netstandard2_0); -#endif } /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 3df369a2f6..ce3b9dd26b 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -524,10 +524,8 @@ private void PopulateProtocol() internal static string GetLocalDBInstance(string dataSource, out bool error) { string instanceName = null; - // ReadOnlySpan is not supported in netstandard 2.0, but installing System.Memory solves the issue ReadOnlySpan input = dataSource.AsSpan().TrimStart(); error = false; - // NetStandard 2.0 does not support passing a string to ReadOnlySpan int index = input.IndexOf(LocalDbHost.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase); if (input.StartsWith(LocalDbHost_NP.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase)) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs deleted file mode 100644 index 399c43cb9b..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs +++ /dev/null @@ -1,97 +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 NETSTANDARD2_0 - -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.Data.SqlClient.SNI -{ - // NetCore2.1: - // DO NOT OVERRIDE ValueTask versions of ReadAsync and WriteAsync because the underlying SslStream implements them - // by calling the Task versions which are already overridden meaning that if a caller uses Task WriteAsync this would - // call ValueTask WriteAsync which then called TaskWriteAsync introducing a lock cycle and never return - - internal sealed partial class SNISslStream - { - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await _readAsyncSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try - { - return await base.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - } - catch (System.Exception e) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message); - throw; - } - finally - { - _readAsyncSemaphore.Release(); - } - } - - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await _writeAsyncSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try - { - await base.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - } - catch (System.Exception e) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message); - throw; - } - finally - { - _writeAsyncSemaphore.Release(); - } - } - } - - internal sealed partial class SNINetworkStream - { - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await _readAsyncSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try - { - return await base.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - } - catch (System.Exception e) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message); - throw; - } - finally - { - _readAsyncSemaphore.Release(); - } - } - - // Prevent the WriteAsync collisions by running the task in a Semaphore Slim - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await _writeAsyncSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try - { - await base.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - } - catch (System.Exception e) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message); - throw; - } - finally - { - _writeAsyncSemaphore.Release(); - } - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs index 03b071eac2..f5f38f0efe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System.Threading; using System.Threading.Tasks; using System; @@ -109,5 +107,3 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs index 655fc91d7c..be8d1a0160 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Buffers; using System.Threading; @@ -295,5 +293,3 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs deleted file mode 100644 index e411c2955e..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SslOverTdsStream.NetStandard.cs +++ /dev/null @@ -1,227 +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 NETSTANDARD2_0 - -using System; -using System.Buffers; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.Data.SqlClient.SNI -{ - internal sealed partial class SslOverTdsStream : Stream - { - public override int Read(byte[] buffer, int offset, int count) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - return _stream.Read(buffer, offset, count); - } - - 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(count, _packetBytes); - int readCount = _stream.Read(buffer, offset, wantedCount); - 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); - Array.Clear(headerBytes, 0, headerBytes.Length); - - // fetch the packet header to determine how long the packet is - int headerBytesRead = 0; - do - { - int headerBytesReadIteration = _stream.Read(headerBytes, headerBytesRead, (TdsEnums.HEADER_LEN - headerBytesRead)); - 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 = _stream.Read(buffer, offset, Math.Min(count, _packetBytes)); - _packetBytes -= packetBytesRead; - return packetBytesRead; - } - } - } - - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - return await _stream.ReadAsync(buffer, offset, count, cancellationToken); - } - - 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(count, _packetBytes); - int readCount = await _stream.ReadAsync(buffer, offset, wantedCount, cancellationToken); - 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); - Array.Clear(headerBytes, 0, headerBytes.Length); - - // fetch the packet header to determine how long the packet is - int headerBytesRead = 0; - do - { - int headerBytesReadIteration = await _stream.ReadAsync(headerBytes, headerBytesRead, (TdsEnums.HEADER_LEN - headerBytesRead), cancellationToken); - 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 = await _stream.ReadAsync(buffer, offset, Math.Min(count, _packetBytes), cancellationToken); - _packetBytes -= packetBytesRead; - return packetBytesRead; - } - } - } - - public override void Write(byte[] buffer, int offset, int count) - { - 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, offset, count); - _stream.Flush(); - return; - } - - int remainingBytes = count; - int dataOffset = offset; - byte[] packetBuffer = null; - while (remainingBytes > 0) - { - int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remainingBytes); - int packetLength = TdsEnums.HEADER_LEN + dataLength; - remainingBytes -= 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, remainingBytes); - - Array.Copy(buffer, dataOffset, packetBuffer, TdsEnums.HEADER_LEN, dataLength); - - _stream.Write(packetBuffer, 0, packetLength); - _stream.Flush(); - - dataOffset += dataLength; - } - if (packetBuffer != null) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - } - } - } - - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - await _stream.WriteAsync(buffer, offset, count).ConfigureAwait(false); - Task flushTask = _stream.FlushAsync(); - if (flushTask.Status == TaskStatus.RanToCompletion) - { - await flushTask.ConfigureAwait(false); - } - return; - } - - int remainingBytes = count; - int dataOffset = offset; - byte[] packetBuffer = null; - while (remainingBytes > 0) - { - int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remainingBytes); - int packetLength = TdsEnums.HEADER_LEN + dataLength; - remainingBytes -= 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, remainingBytes); - - Array.Copy(buffer, dataOffset, packetBuffer, TdsEnums.HEADER_LEN, dataLength); - - await _stream.WriteAsync(packetBuffer, 0, packetLength, cancellationToken).ConfigureAwait(false); - await _stream.FlushAsync().ConfigureAwait(false); - - dataOffset += dataLength; - } - if (packetBuffer != null) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - } - } - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs index 9170614927..dd57c60da8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -197,5 +195,3 @@ internal class SqlClientAuthenticationProviderConfigurationSection : SqlAuthenti } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs deleted file mode 100644 index 0fa64d0cef..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.NetStandard.cs +++ /dev/null @@ -1,19 +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 NETSTANDARD2_0 - -namespace Microsoft.Data.SqlClient -{ - internal partial class SqlAuthenticationProviderManager - { - static SqlAuthenticationProviderManager() - { - Instance = new SqlAuthenticationProviderManager(); - SetDefaultAuthProviders(Instance); - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs index 6dc531f766..c0312ca219 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientEventSource.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Diagnostics.Tracing; using System.Threading; @@ -396,5 +394,3 @@ internal override void ReclaimedConnectionRequest() } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs index da5a516004..fd81db557d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System.Security.Cryptography; namespace Microsoft.Data.SqlClient @@ -25,5 +23,3 @@ internal abstract void CreateEnclaveSession(byte[] enclaveAttestationInfo, ECDif out SqlEnclaveSession sqlEnclaveSession, out long counter); } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs index ea27ceabe0..561f9bd6fb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Transactions; @@ -16,5 +14,3 @@ internal sealed partial class SqlDelegatedTransaction : IPromotableSinglePhaseNo private Guid GetGlobalTxnIdentifierFromToken() => new Guid(new ReadOnlySpan(_connection.PromotedDTCToken, _globalTransactionsTokenVersionSizeInBytes, 16)); } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs deleted file mode 100644 index ba50ca5d14..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.NetStandard.cs +++ /dev/null @@ -1,26 +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 NETSTANDARD2_0 - -using System; -using System.Transactions; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class SqlDelegatedTransaction : IPromotableSinglePhaseNotification - { - // Get the server-side Global Transaction Id from the PromotedDTCToken - // Skip first 4 bytes since they contain the version - private Guid GetGlobalTxnIdentifierFromToken() - { - byte[] txnGuid = new byte[16]; - Array.Copy(_connection.PromotedDTCToken, _globalTransactionsTokenVersionSizeInBytes, // Skip the version - txnGuid, 0, txnGuid.Length); - return new Guid(txnGuid); - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs index 2c7554a0cb..95dd0d9731 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Diagnostics; using System.Buffers.Binary; @@ -25,5 +23,3 @@ internal static Guid ConstructGuid(ReadOnlySpan bytes) } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs deleted file mode 100644 index 2327f92b72..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetStandard.cs +++ /dev/null @@ -1,45 +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 NETSTANDARD2_0 - -using System; -using System.Buffers; -using System.Diagnostics; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class TdsParser - { - internal static void FillGuidBytes(Guid guid, Span buffer) - { - byte[] bytes = guid.ToByteArray(); - bytes.AsSpan().CopyTo(buffer); - } - - internal static void FillDoubleBytes(double value, Span buffer) - { - byte[] bytes = BitConverter.GetBytes(value); - bytes.AsSpan().CopyTo(buffer); - } - - internal static void FillFloatBytes(float value, Span buffer) - { - byte[] bytes = BitConverter.GetBytes(value); - bytes.AsSpan().CopyTo(buffer); - } - - internal static Guid ConstructGuid(ReadOnlySpan bytes) - { - Debug.Assert(bytes.Length >= 16, "not enough bytes to set guid"); - byte[] temp = ArrayPool.Shared.Rent(16); - bytes.CopyTo(temp.AsSpan()); - Guid retval = new Guid(temp); - ArrayPool.Shared.Return(temp); - return retval; - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 4d731102fe..e89e5ef92e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -7568,7 +7568,7 @@ private Task WriteEncodingChar(string s, Encoding encoding, TdsParserStateObject private byte[] SerializeEncodingChar(string s, int numChars, int offset, Encoding encoding) { -#if NETFRAMEWORK || NETSTANDARD2_0 +#if NETFRAMEWORK char[] charData; byte[] byteData = null; @@ -7605,7 +7605,7 @@ private Task WriteEncodingChar(string s, int numChars, int offset, Encoding enco } else { -#if NETFRAMEWORK || NETSTANDARD2_0 +#if NETFRAMEWORK char[] charData = s.ToCharArray(offset, numChars); byte[] byteData = encoding.GetBytes(charData, 0, numChars); Debug.Assert(byteData != null, "no data from encoding"); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs index cfbd2139eb..78682e917f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs @@ -693,11 +693,7 @@ static private string InitializeNtPath(string path) // Ensure we have validated and normalized the path before AssertPathFormat(path); string uniqueId = Guid.NewGuid().ToString("N"); -#if NETSTANDARD - return System.IO.PathInternal.IsDeviceUNC(path.AsSpan()) -#else return System.IO.PathInternal.IsDeviceUNC(path) -#endif ? string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", path.Replace(@"\\.", @"\??"), uniqueId) : string.Format(CultureInfo.InvariantCulture, @"\??\UNC\{0}\{1}", path.Trim('\\'), uniqueId); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/PinvokeAnalyzerExceptionList.analyzerdata.netstandard b/src/Microsoft.Data.SqlClient/netcore/src/PinvokeAnalyzerExceptionList.analyzerdata.netstandard deleted file mode 100644 index 5c0648966d..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/PinvokeAnalyzerExceptionList.analyzerdata.netstandard +++ /dev/null @@ -1,44 +0,0 @@ - -kernel32.dll!LoadLibraryExW -sni.dll!GetSniMaxComposedSpnLength -sni.dll!SNIAddProviderWrapper -sni.dll!SNICheckConnectionWrapper -sni.dll!SNICloseWrapper -sni.dll!SNIGetInfoWrapper -sni.dll!SNIGetLastError -sni.dll!SNIInitialize -sni.dll!SNIOpenSyncExWrapper -sni.dll!SNIOpenWrapper -sni.dll!SNIPacketAllocateWrapper -sni.dll!SNIPacketGetDataWrapper -sni.dll!SNIPacketRelease -sni.dll!SNIPacketResetWrapper -sni.dll!SNIPacketSetData -sni.dll!SNIQueryInfo -sni.dll!SNIReadAsyncWrapper -sni.dll!SNIReadSyncOverAsync -sni.dll!SNIRemoveProviderWrapper -sni.dll!SNISecGenClientContextWrapper -sni.dll!SNISecInitPackage -sni.dll!SNISetInfoWrapper -sni.dll!SNITerminate -sni.dll!SNIWaitForSSLHandshakeToCompleteWrapper -sni.dll!SNIWriteAsyncWrapper -sni.dll!SNIWriteSyncOverAsync -sni.dll!UnmanagedIsTokenRestricted -sspicli.dll!AcceptSecurityContext -sspicli.dll!AcquireCredentialsHandleW -sspicli.dll!ApplyControlToken -sspicli.dll!CompleteAuthToken -sspicli.dll!DecryptMessage -sspicli.dll!DeleteSecurityContext -sspicli.dll!EncryptMessage -sspicli.dll!EnumerateSecurityPackagesW -sspicli.dll!FreeContextBuffer -sspicli.dll!FreeCredentialsHandle -sspicli.dll!InitializeSecurityContextW -sspicli.dll!QueryContextAttributesW -sspicli.dll!QuerySecurityContextToken -sspicli.dll!SetContextAttributesW -sspicli.dll!SspiEncodeStringsAsAuthIdentity -sspicli.dll!SspiFreeAuthIdentity \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 6d49a79051..3012a87bec 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -8340,7 +8340,7 @@ private Task WriteEncodingChar(string s, Encoding encoding, TdsParserStateObject private byte[] SerializeEncodingChar(string s, int numChars, int offset, Encoding encoding) { -#if NETFRAMEWORK || NETSTANDARD2_0 +#if NETFRAMEWORK char[] charData; byte[] byteData = null; @@ -8377,7 +8377,7 @@ private Task WriteEncodingChar(string s, int numChars, int offset, Encoding enco } else { -#if NETFRAMEWORK || NETSTANDARD2_0 +#if NETFRAMEWORK var charData = s.ToCharArray(offset, numChars); var byteData = encoding.GetBytes(charData, 0, numChars); Debug.Assert(byteData != null, "no data from encoding"); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index 01f265cf50..75b55847f7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -100,13 +100,6 @@ public override void BeforeUnload(SqlAuthenticationMethod authentication) _logger.LogInfo(_type, "BeforeUnload", $"being unloaded from SqlAuthProviders for {authentication}."); } -#if NETSTANDARD - private Func _parentActivityOrWindowFunc = null; - - /// - public void SetParentActivityOrWindowFunc(Func parentActivityOrWindowFunc) => this._parentActivityOrWindowFunc = parentActivityOrWindowFunc; -#endif - #if NETFRAMEWORK private Func _iWin32WindowFunc = null; @@ -223,9 +216,6 @@ public override async Task AcquireTokenAsync(SqlAuthenti PublicClientAppKey pcaKey = new PublicClientAppKey(parameters.Authority, redirectUri, _applicationClientId #if NETFRAMEWORK , _iWin32WindowFunc -#endif -#if NETSTANDARD - , _parentActivityOrWindowFunc #endif ); @@ -491,18 +481,6 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ { IPublicClientApplication publicClientApplication; -#if NETSTANDARD - if (_parentActivityOrWindowFunc != null) - { - publicClientApplication = PublicClientApplicationBuilder.Create(publicClientAppKey._applicationClientId) - .WithAuthority(publicClientAppKey._authority) - .WithClientName(Common.DbConnectionStringDefaults.ApplicationName) - .WithClientVersion(Common.ADP.GetAssemblyVersion().ToString()) - .WithRedirectUri(publicClientAppKey._redirectUri) - .WithParentActivityOrWindow(_parentActivityOrWindowFunc) - .Build(); - } -#endif #if NETFRAMEWORK if (_iWin32WindowFunc != null) { @@ -538,16 +516,10 @@ internal class PublicClientAppKey #if NETFRAMEWORK public readonly Func _iWin32WindowFunc; #endif -#if NETSTANDARD - public readonly Func _parentActivityOrWindowFunc; -#endif public PublicClientAppKey(string authority, string redirectUri, string applicationClientId #if NETFRAMEWORK , Func iWin32WindowFunc -#endif -#if NETSTANDARD - , Func parentActivityOrWindowFunc #endif ) { @@ -556,9 +528,6 @@ public PublicClientAppKey(string authority, string redirectUri, string applicati _applicationClientId = applicationClientId; #if NETFRAMEWORK _iWin32WindowFunc = iWin32WindowFunc; -#endif -#if NETSTANDARD - _parentActivityOrWindowFunc = parentActivityOrWindowFunc; #endif } @@ -571,9 +540,6 @@ public override bool Equals(object obj) && string.CompareOrdinal(_applicationClientId, pcaKey._applicationClientId) == 0 #if NETFRAMEWORK && pcaKey._iWin32WindowFunc == _iWin32WindowFunc -#endif -#if NETSTANDARD - && pcaKey._parentActivityOrWindowFunc == _parentActivityOrWindowFunc #endif ); } @@ -583,9 +549,6 @@ public override bool Equals(object obj) public override int GetHashCode() => Tuple.Create(_authority, _redirectUri, _applicationClientId #if NETFRAMEWORK , _iWin32WindowFunc -#endif -#if NETSTANDARD - , _parentActivityOrWindowFunc #endif ).GetHashCode(); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs index 890af0206f..ff84ab3310 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedEnclaveProviderUtils.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; namespace Microsoft.Data.SqlClient @@ -51,5 +49,3 @@ internal enum EnclaveType Sgx = 2 } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs index 70f6bc5f91..7b1b2bf2e4 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Collections.Generic; using System.Diagnostics; @@ -542,5 +540,3 @@ private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, byte[] nonce, #endregion } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs index fc87127b04..db1bdea90f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -213,5 +211,3 @@ internal byte[] GetSerializedAttestationParameters(SqlEnclaveAttestationParamete } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs deleted file mode 100644 index 3c3afac335..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.NotSupported.cs +++ /dev/null @@ -1,59 +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 NETSTANDARD2_0 - -using System; -using System.Collections.Concurrent; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class EnclaveDelegate - { - internal byte[] GetSerializedAttestationParameters( - SqlEnclaveAttestationParameters sqlEnclaveAttestationParameters, string enclaveType) - { - throw new PlatformNotSupportedException(); - } - - /// - /// Create a new enclave session - /// - /// attestation protocol - /// enclave type - /// The set of parameters required for enclave session. - /// attestation info from SQL Server - /// attestation parameters - /// A set of extra data needed for attesting the enclave. - /// The length of the extra data needed for attesting the enclave. - /// Indicates if this is a retry from a failed call. - internal void CreateEnclaveSession(SqlConnectionAttestationProtocol attestationProtocol, string enclaveType, EnclaveSessionParameters enclaveSessionParameters, - byte[] attestationInfo, SqlEnclaveAttestationParameters attestationParameters, byte[] customData, int customDataLength, bool isRetry) - { - throw new PlatformNotSupportedException(); - } - - internal void GetEnclaveSession(SqlConnectionAttestationProtocol attestationProtocol, string enclaveType, EnclaveSessionParameters enclaveSessionParameters, bool generateCustomData, bool isRetry, out SqlEnclaveSession sqlEnclaveSession, out byte[] customData, out int customDataLength) - { - throw new PlatformNotSupportedException(); - } - - internal EnclavePackage GenerateEnclavePackage(SqlConnectionAttestationProtocol attestationProtocol, ConcurrentDictionary keysTobeSentToEnclave, string queryText, string enclaveType, EnclaveSessionParameters enclaveSessionParameters, SqlConnection connection, SqlCommand command) - { - throw new PlatformNotSupportedException(); - } - - internal void InvalidateEnclaveSession(SqlConnectionAttestationProtocol attestationProtocol, string enclaveType, EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSession) - { - throw new PlatformNotSupportedException(); - } - - internal SqlEnclaveAttestationParameters GetAttestationParameters(SqlConnectionAttestationProtocol attestationProtocol, string enclaveType, string attestationUrl, byte[] customData, int customDataLength) - { - throw new PlatformNotSupportedException(); - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs index 1a2bcaeb03..b8a52b9e4b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Runtime.Caching; using System.Security.Cryptography; @@ -215,5 +213,3 @@ protected SqlEnclaveSession AddEnclaveSessionToCache(EnclaveSessionParameters en } #endregion } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs index d60c3ad5ba..2cc34eeeb5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Runtime.Caching; using System.Threading; @@ -74,5 +72,3 @@ private string GenerateCacheKey(EnclaveSessionParameters enclaveSessionParameter } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs index 9ef8a77d19..fabd69c976 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Diagnostics; using System.Security.Cryptography; @@ -106,5 +104,3 @@ internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclave } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index 690a4e810a..73de1ad4f7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -1024,7 +1024,7 @@ internal ApplicationIntent ConvertValueToApplicationIntent() // ArgumentException and other types are raised as is (no wrapping) } -#if NETCOREAPP || NETSTANDARD +#if NETCOREAPP internal void ThrowUnsupportedIfKeywordSet(string keyword) { if (ContainsKey(keyword)) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs index 506b45faac..3aa1697d03 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs @@ -107,7 +107,7 @@ private SqlDependencyPerAppDomainDispatcher() } } -#if NETCOREAPP || NETSTANDARD +#if NETCOREAPP partial void SubscribeToAppDomainUnload(); partial void SubscribeToAssemblyLoadContextUnload(); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs index 2abb408d41..c2e9739237 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.Crypto.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Security.Cryptography; @@ -52,5 +50,3 @@ internal byte[] GetInput() } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs deleted file mode 100644 index 64d5d19655..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NotSupported.cs +++ /dev/null @@ -1,23 +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 NETSTANDARD2_0 - -namespace Microsoft.Data.SqlClient -{ - /// - internal partial class SqlEnclaveAttestationParameters - { - /// - internal int Protocol { get; } - - /// - internal byte[] GetInput() - { - return null; - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs index e6faafc405..25e1808e56 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs @@ -27,7 +27,7 @@ internal abstract class SqlInternalConnection : DbConnectionInternal private bool _isGlobalTransactionEnabledForServer; // Whether Global Transactions are enabled for this Azure SQL DB Server private static readonly Guid s_globalTransactionTMID = new("1c742caf-6680-40ea-9c26-6b6846079764"); // ID of the Non-MSDTC, Azure SQL DB Transaction Manager -#if NETCOREAPP || NETSTANDARD +#if NETCOREAPP internal SqlCommand.ExecuteReaderAsyncCallContext CachedCommandExecuteReaderAsyncContext; internal SqlCommand.ExecuteNonQueryAsyncCallContext CachedCommandExecuteNonQueryAsyncContext; internal SqlCommand.ExecuteXmlReaderAsyncCallContext CachedCommandExecuteXmlReaderAsyncContext; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs index 7ebad456f5..fd180d12d6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProvider.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Collections.Generic; using System.Diagnostics; @@ -470,5 +468,3 @@ public static byte[] TakeBytesAndAdvance(byte[] input, ref int offset, int count } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index c60dd01c72..cfbe531e82 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !NETSTANDARD2_0 - using System; using System.Runtime.Caching; using System.Security.Cryptography; @@ -421,5 +419,3 @@ private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, EnclaveDiffieH #endregion } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs index a99e5d0303..533ffa86ad 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs @@ -10503,15 +10503,6 @@ internal static string SQL_StreamWriteNotSupported { } } - /// - /// Looks up a localized string similar to Not supported in .Net Standard 2.0.. - /// - internal static string SQL_TDS8_NotSupported_Netstandard2_0 { - get { - return ResourceManager.GetString("SQL_TDS8_NotSupported_Netstandard2_0", resourceCulture); - } - } - /// /// Looks up a localized string similar to Processing of results from SQL Server failed because of an invalid multipart name. /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx index ac803efe71..7862b1769c 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx @@ -4680,12 +4680,6 @@ Socket hat den erwarteten "{0}" nicht ausgelöst. Fehlercode: "{1}". - - Wird in .NET Standard 2.0 nicht unterstützt. - - - Der Server versucht, ein Feature zu verwenden, das auf dieser Plattform nicht unterstützt wird. - Das Schlüsselwort "{0}" wird auf dieser Plattform nicht unterstützt. @@ -4740,4 +4734,4 @@ Das Zertifikat ist während der Überprüfung des Zertifikats nicht verfügbar. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx index 821f8f1aa5..028ceeba85 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx @@ -4680,9 +4680,6 @@ El socket no produjo el esperado '{0}' con el código de error '{1}'. - - No se admite en .NET Standard 2.0. - El servidor está intentando usar una característica que no se admite en esta plataforma. @@ -4740,4 +4737,4 @@ El certificado no está disponible al validar el certificado. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx index d7e42c70c7..60c04699b7 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx @@ -4680,9 +4680,6 @@ Le socket n’a pas levé le '{0}' attendu avec le code d’erreur '{1}'. - - Non pris en charge dans .Net Standard 2.0. - Le serveur tente d’utiliser une fonctionnalité qui n’est pas prise en charge sur cette plateforme. @@ -4740,4 +4737,4 @@ Certificat non disponible lors de sa validation. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx index add941c9ce..01e3a62844 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx @@ -4680,9 +4680,6 @@ Il socket non ha generato '{0}' previsto con codice errore '{1}'. - - Non supportato in .NET Standard 2.0. - Il server sta tentando di usare una funzionalità non supportata in questa piattaforma. @@ -4740,4 +4737,4 @@ Certificato non disponibile durante la convalida del certificato. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx index 8b5b367a9f..bd05c52169 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx @@ -4680,9 +4680,6 @@ ソケットは予期された '{0}' をスローしませんでした。エラー コード '{1}'。 - - .Net Standard 2.0 ではサポートされていません。 - サーバーは、このプラットフォームでサポートされていない機能を使用しようとしています。 @@ -4740,4 +4737,4 @@ 証明書の検証中は証明書を使用できません。 - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx index d3d62df164..e2886df8ff 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx @@ -4680,9 +4680,6 @@ 소켓이 오류 코드 '{1}'과(와) 예상되는 '{0}'을(를) throw하지 않았습니다. - - .Net Standard 2.0에서는 지원되지 않습니다. - 서버가 이 플랫폼에서 지원되지 않는 기능을 사용하려고 합니다. @@ -4740,4 +4737,4 @@ 인증서의 유효성을 검사하는 동안에는 인증서를 사용할 수 없습니다. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx index 3cb1ae77ec..3a7fcbb0f4 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx @@ -4680,9 +4680,6 @@ O soquete não lançou o esperado '{0}' com código de erro '{1}'. - - Sem suporte no .Net Standard 2.0. - O servidor está tentando usar um recurso que não é suportado nesta plataforma. @@ -4740,4 +4737,4 @@ Certificado não disponível durante a validação do certificado. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx index 3712ece88f..3fb2e0a74a 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx @@ -4680,9 +4680,6 @@ Socket did not throw expected '{0}' with error code '{1}'. - - Not supported in .Net Standard 2.0. - The server is attempting to use a feature that is not supported on this platform. @@ -4740,4 +4737,4 @@ Certificate not available while validating the certificate. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx index 24fb60a6e4..3051d03352 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx @@ -4680,9 +4680,6 @@ Сокет не вызвал ожидаемый "{0}" с кодом ошибки "{1}". - - Не поддерживается в .NET Standard 2.0. - Сервер пытается использовать функцию, которая не поддерживается этой платформой. @@ -4740,4 +4737,4 @@ Сертификат недоступен при проверке сертификата. - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx index e2d34132a8..e24601fb33 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx @@ -4680,9 +4680,6 @@ 套接字未引发预期的“{0}”,错误代码为“{1}”。 - - .Net Standard 2.0 不支持。 - 服务器正在尝试使用此平台不支持的功能。 @@ -4740,4 +4737,4 @@ 验证证书时证书不可用。 - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx index d345373858..3492f58356 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx @@ -4680,9 +4680,6 @@ 通訊端未擲出預期的 '{0}',錯誤碼為 '{1}'。 - - .NET Standard 2.0 中不支援。 - 伺服器正嘗試使用此平台上不支援的功能。 @@ -4740,4 +4737,4 @@ 驗證在進行憑證驗證時無法使用。 - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs index e62544d06d..1c021b459a 100644 --- a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs +++ b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs @@ -4,60 +4,6 @@ namespace System.Diagnostics.CodeAnalysis { -#if NETSTANDARD2_0 - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] - internal sealed class AllowNullAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] - internal sealed class DisallowNullAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class DoesNotReturnAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class DoesNotReturnIfAttribute : Attribute - { - public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; - public bool ParameterValue { get; } - } - - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] - internal sealed class MaybeNullAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class MaybeNullWhenAttribute : Attribute - { - public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - public bool ReturnValue { get; } - } - - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] - internal sealed class NotNullAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] - internal sealed class NotNullIfNotNullAttribute : Attribute - { - public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; - public string ParameterName { get; } - } - - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class NotNullWhenAttribute : Attribute - { - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - public bool ReturnValue { get; } - } -#endif #if !NET6_0_OR_GREATER [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] diff --git a/src/Microsoft.Data.SqlClient/tests/CustomConfigurableRetryLogic/CustomRetryLogicProvider.csproj b/src/Microsoft.Data.SqlClient/tests/CustomConfigurableRetryLogic/CustomRetryLogicProvider.csproj index 4c4d66ca94..8a076d1e52 100644 --- a/src/Microsoft.Data.SqlClient/tests/CustomConfigurableRetryLogic/CustomRetryLogicProvider.csproj +++ b/src/Microsoft.Data.SqlClient/tests/CustomConfigurableRetryLogic/CustomRetryLogicProvider.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/Directory.Build.props b/src/Microsoft.Data.SqlClient/tests/Directory.Build.props index 7e412a3375..12c7957a23 100644 --- a/src/Microsoft.Data.SqlClient/tests/Directory.Build.props +++ b/src/Microsoft.Data.SqlClient/tests/Directory.Build.props @@ -24,7 +24,7 @@ - $(TargetNetFxVersion);$(TargetNetCoreVersion); + $(TargetNetCoreVersion);$(TargetNetFxVersion) $(TargetNetCoreVersion); diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index aedae160a7..b5ac559337 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -8,7 +8,6 @@ win-$(Platform) $(DefineConstants);NETFRAMEWORK $(DefineConstants);NETCOREAPP - NETSTANDARDREFERNCE $(ObjFolder)$(Configuration).$(Platform).$(AssemblyName) $(BinFolder)$(Configuration).$(Platform).$(AssemblyName) true @@ -93,7 +92,6 @@ - @@ -118,10 +116,9 @@ TDS - + - diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs index 6aef4b60b2..21169fba96 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs @@ -209,7 +209,7 @@ public object SqlValue public void SetToNullOfType(StorageType storageType) { -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER _setToNullOfTypeMethod .Invoke(_instance, BindingFlags.DoNotWrapExceptions, null, new object[] { (int)storageType }, null); #else @@ -219,7 +219,7 @@ public void SetToNullOfType(StorageType storageType) private T GetPropertyValue(PropertyInfo property) { -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER return (T)property.GetValue(_instance, BindingFlags.DoNotWrapExceptions, null, null, null); #else try @@ -235,7 +235,7 @@ private T GetPropertyValue(PropertyInfo property) private void SetPropertyValue(PropertyInfo property, object value) { -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER property.SetValue(_instance, value, BindingFlags.DoNotWrapExceptions, null, null, null); #else try diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandTest.cs index 0a1a8e9ef5..c5e3b000dc 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandTest.cs @@ -125,7 +125,7 @@ public void Constructor3() Assert.Null(cmd.Container); Assert.True(cmd.DesignTimeVisible); Assert.Null(cmd.Notification); -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif @@ -166,7 +166,7 @@ public void Constructor4() Assert.Null(cmd.Container); Assert.True(cmd.DesignTimeVisible); Assert.Null(cmd.Notification); -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif @@ -184,7 +184,7 @@ public void Constructor4() Assert.Null(cmd.Container); Assert.True(cmd.DesignTimeVisible); Assert.Null(cmd.Notification); -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif @@ -202,7 +202,7 @@ public void Constructor4() Assert.Null(cmd.Container); Assert.True(cmd.DesignTimeVisible); Assert.Null(cmd.Notification); -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif @@ -224,7 +224,7 @@ public void Clone() cmd.CommandType = CommandType.StoredProcedure; cmd.DesignTimeVisible = false; cmd.Notification = notificationReq; -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif @@ -240,7 +240,7 @@ public void Clone() Assert.Null(cmd.Connection); Assert.False(cmd.DesignTimeVisible); Assert.Same(notificationReq, cmd.Notification); -#if NETFRAMEWORK && !NETSTANDARDREFERNCE +#if NETFRAMEWORK // see https://github.com/dotnet/SqlClient/issues/17 Assert.True(cmd.NotificationAutoEnlist); #endif diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 19c257001d..f75aef8edb 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -14,7 +14,7 @@ $(BinFolder)$(Configuration).$(Platform).$(AssemblyName) true - + @@ -30,7 +30,7 @@ TCECryptoNativeBaselineRsa.txt - + @@ -257,7 +257,7 @@ - + @@ -310,7 +310,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Address/Address.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Address/Address.csproj index e525bdeda3..941b08588c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Address/Address.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Address/Address.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Circle/Circle.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Circle/Circle.csproj index 750ae10973..93137d1883 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Circle/Circle.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Circle/Circle.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Shapes/Shapes.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Shapes/Shapes.csproj index d2b894a83d..596f7ffe74 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Shapes/Shapes.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Shapes/Shapes.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Utf8String/Utf8String.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Utf8String/Utf8String.csproj index 4b520c0286..ec1229e0e7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Utf8String/Utf8String.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UDTs/Utf8String/Utf8String.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/NSLibrary/Microsoft.Data.SqlClient.NSLibrary.csproj b/src/Microsoft.Data.SqlClient/tests/NSLibrary/Microsoft.Data.SqlClient.NSLibrary.csproj deleted file mode 100644 index c7658cb0a5..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/NSLibrary/Microsoft.Data.SqlClient.NSLibrary.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - netstandard2.0;netstandard2.1 - netstandard2.1 - $(ObjFolder)$(Configuration).$(Platform)\$(AssemblyName) - $(BinFolder)$(Configuration).$(Platform)\$(AssemblyName) - - - - - - diff --git a/tools/props/Versions.props b/tools/props/Versions.props index f0695ec8fc..022c9a4c7a 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -37,7 +37,6 @@ - 5.0.0 5.2.0 6.0.1 1.0.0 @@ -48,11 +47,6 @@ 5.0.0 6.0.0 - - - 4.3.0 - 6.0.1 - [1.38.0,2.0.0) @@ -78,6 +72,7 @@ 0.13.2 6.0.0 6.0.1 + 5.0.0 $(NugetPackageVersion) diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index ca4d10abf7..b1666d4459 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -58,41 +58,6 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -111,14 +76,6 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - - @@ -135,13 +92,6 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - @@ -164,7 +114,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -175,7 +125,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -194,41 +144,6 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -244,16 +159,5 @@ When using NuGet 3.x this package requires at least version 3.4. - - - - - - - - - - - diff --git a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec index 33be2b3409..5c89d24276 100644 --- a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec +++ b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec @@ -42,12 +42,6 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti - - - - - - @@ -84,16 +78,5 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti - - - - - - - - - - - - + From 910bdb4754bfd11c2043c8f8b89b91df49e46888 Mon Sep 17 00:00:00 2001 From: Wraith Date: Fri, 3 May 2024 21:10:35 +0100 Subject: [PATCH 39/53] make EnableOptimizedParameterBinding only apply to text mode commands and update documentation to match. (#2417) --- doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml | 3 ++- .../netcore/src/Microsoft/Data/SqlClient/TdsParser.cs | 2 +- .../netfx/src/Microsoft/Data/SqlClient/TdsParser.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml index a19cff3c8a..7b0b19f031 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml @@ -1385,7 +1385,8 @@ The method is a st - Gets or sets a value indicating whether the command object should optimize parameter performance by disabling Output and InputOutput directions when submitting the command to the SQL Server. + Gets or sets a value indicating whether the command object should optimize parameter performance by disabling Output and InputOutput directions when submitting the command to the SQL Server.
+ This option is only used when the is Text otherwise it is ignored.
A value indicating whether the command object should optimize parameter performance by disabling Output and InputOuput parameter directions when submitting the command to the SQL Server. diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index e89e5ef92e..0d3c0a01b5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -8988,7 +8988,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout int parametersLength = rpcext.userParamCount + rpcext.systemParamCount; bool isAdvancedTraceOn = SqlClientEventSource.Log.IsAdvancedTraceOn(); - bool enableOptimizedParameterBinding = cmd.EnableOptimizedParameterBinding; + bool enableOptimizedParameterBinding = cmd.EnableOptimizedParameterBinding && cmd.CommandType == CommandType.Text; for (int i = (ii == startRpc) ? startParam : 0; i < parametersLength; i++) { diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 3012a87bec..7c8fc724c6 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -9817,7 +9817,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout int parametersLength = rpcext.userParamCount + rpcext.systemParamCount; bool isAdvancedTraceOn = SqlClientEventSource.Log.IsAdvancedTraceOn(); - bool enableOptimizedParameterBinding = cmd.EnableOptimizedParameterBinding; + bool enableOptimizedParameterBinding = cmd.EnableOptimizedParameterBinding && cmd.CommandType == CommandType.Text; for (int i = (ii == startRpc) ? startParam : 0; i < parametersLength; i++) { From 7def235d764c1b1fa12db242afecf146a18a60f6 Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Fri, 3 May 2024 21:51:35 +0000 Subject: [PATCH 40/53] Merged PR 4490: eng | Remove netstandard from production pipeline - Complementary code change of PR [#2386](https://github.com/dotnet/SqlClient/pull/2386). - This should be merged after merging the related PR to remove support of .NET Standard in the production pipeline. - The first commit has the related PR's changes(review them on GH). - After having merged the related GH PR and updating the CI pipeline, I'll sync with this PR to unify the changes and get passed the pipeline. - Only the YAML changes under the `eng` folder should be reviewed (ignore the other changes as they are identical to the GH). - Introduced `oneBranchType` parameter to switch between **Official** and **NonOfficial** templates - [new sample run](https://dev.azure.com/SqlClientDrivers/ADO.Net/_build/results?buildId=86908&view=results) Related work items: #30122 --- .../common/templates/jobs/validate-signed-package-job.yml | 6 +++--- .../steps/build-all-configurations-signed-dlls-step.yml | 7 ------- .../common/templates/steps/copy-dlls-for-test-step.yml | 2 -- eng/pipelines/dotnet-sqlclient-signing-pipeline.yml | 8 +++++++- eng/pipelines/libraries/mds-validation-variables.yml | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml index 9f12f42e92..379f6673f1 100644 --- a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml @@ -115,7 +115,7 @@ jobs: displayName: 'Check expected folder names' - powershell: | - # Checks the version of DotNetFramework, NetStandard and NetCore + # Checks the version of DotNetFramework and DotNet $countErr = 0 $countPass = 0 $excludNamesFromRuntimeFolder = 'lib','win','unix' @@ -260,11 +260,11 @@ jobs: if($pVersion.FileVersion -eq '${{parameters.assembly_file_version_core}}') { - Write-Host 'Correct File version Detected for netcore and netstandard,' $pVersion.FileVersion -ForegroundColor Green + Write-Host 'Correct File version Detected for netcore,' $pVersion.FileVersion -ForegroundColor Green } else { - Write-Host 'Wrong File version Detected for netcore and netstandard and ref folder of netfx,' $pVersion.FileVersion -ForegroundColor Red + Write-Host 'Wrong File version Detected for netcore and ref folder,' $pVersion.FileVersion -ForegroundColor Red Exit -1 } } diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml index f61dd48767..5be79793fd 100644 --- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml +++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml @@ -39,13 +39,6 @@ steps: msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' - ${{ if eq(parameters.product, 'AKV') }}: - - task: MSBuild@1 - displayName: 'BuildAKVNetStAllOS using build.proj' - inputs: - solution: '**/build.proj' - configuration: '$(Configuration)' - msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAKVNetStAllOS -p:NugetPackageVersion=${{parameters.nugetPackageRefVersion }} -p:ReferenceType=Package -p:SignAssembly=true -p:AssemblyOriginatorKeyFile=$(Agent.TempDirectory)\netfxKeypair.snk' - - task: MSBuild@1 displayName: 'BuildAKVNetFx using build.proj' inputs: diff --git a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml index 6b0c1fa3ab..faf54fc24d 100644 --- a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml +++ b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml @@ -28,8 +28,6 @@ parameters: - net462 - net6.0 - net8.0 - - netstandard2.0 - - netstandard2.1 - name: product default: MDS diff --git a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml index 1ec608f2a6..aa8d90d3e5 100644 --- a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml +++ b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml @@ -52,6 +52,12 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: 'Lowest supported .NET Framework version (MDS validation)' type: string default: 'net462' +- name: oneBranchType + displayName: 'Select OneBranch template' + default: Official + values: + - NonOfficial + - Official variables: - template: /eng/pipelines/libraries/variables.yml@self @@ -74,7 +80,7 @@ resources: ref: refs/heads/main extends: - template: v2/OneBranch.Official.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates + template: v2/OneBranch.${{parameters.oneBranchType }}.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates parameters: featureFlags: WindowsHostVersion: 1ESWindows2022 diff --git a/eng/pipelines/libraries/mds-validation-variables.yml b/eng/pipelines/libraries/mds-validation-variables.yml index 3c711364a3..7aed06dd61 100644 --- a/eng/pipelines/libraries/mds-validation-variables.yml +++ b/eng/pipelines/libraries/mds-validation-variables.yml @@ -15,7 +15,7 @@ variables: - name: expectedFolderNames value: lib,ref,runtimes - name: expectedDotnetVersions - value: net462,net6.0,net8.0,netstandard2.0,netstandard2.1 + value: net462,net6.0,net8.0 - name: Database value: Northwind - name: platform From 48ab625f82bc2f147276e02862b47b24f06d576c Mon Sep 17 00:00:00 2001 From: SqlClient DevOps Date: Sat, 4 May 2024 02:08:39 +0000 Subject: [PATCH 41/53] [Scheduled Run] Localized resource files from OneLocBuild --- src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx | 5 ++++- src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx | 2 +- .../src/Resources/Strings.pt-BR.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx | 2 +- .../src/Resources/Strings.zh-Hans.resx | 2 +- .../src/Resources/Strings.zh-Hant.resx | 2 +- 10 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx index 7862b1769c..4a6d349fd8 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx @@ -4680,6 +4680,9 @@ Socket hat den erwarteten "{0}" nicht ausgelöst. Fehlercode: "{1}". + + Der Server versucht, ein Feature zu verwenden, das auf dieser Plattform nicht unterstützt wird. + Das Schlüsselwort "{0}" wird auf dieser Plattform nicht unterstützt. @@ -4734,4 +4737,4 @@ Das Zertifikat ist während der Überprüfung des Zertifikats nicht verfügbar. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx index 028ceeba85..ff71f45c02 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx @@ -4737,4 +4737,4 @@ El certificado no está disponible al validar el certificado. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx index 60c04699b7..8b426074c2 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx @@ -4737,4 +4737,4 @@ Certificat non disponible lors de sa validation. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx index 01e3a62844..b5cbd33bdd 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx @@ -4737,4 +4737,4 @@ Certificato non disponibile durante la convalida del certificato. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx index bd05c52169..de5a1c1830 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx @@ -4737,4 +4737,4 @@ 証明書の検証中は証明書を使用できません。 - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx index e2886df8ff..20db99df33 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx @@ -4737,4 +4737,4 @@ 인증서의 유효성을 검사하는 동안에는 인증서를 사용할 수 없습니다. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx index 3a7fcbb0f4..911334848e 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx @@ -4737,4 +4737,4 @@ Certificado não disponível durante a validação do certificado. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx index 3051d03352..cae6234541 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx @@ -4737,4 +4737,4 @@ Сертификат недоступен при проверке сертификата. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx index e24601fb33..2b866bd6ed 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx @@ -4737,4 +4737,4 @@ 验证证书时证书不可用。 - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx index 3492f58356..404f048cf6 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx @@ -4737,4 +4737,4 @@ 驗證在進行憑證驗證時無法使用。 - + \ No newline at end of file From 55d30c71b9c17b804710b4d7ba83d92f2b2676be Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Mon, 6 May 2024 10:58:22 -0700 Subject: [PATCH 42/53] Test | Remove AAS - VBS tests from test pipelines (#2474) --- BUILDGUIDE.md | 1 - .../tests/ManualTests/DataCommon/DataTestUtility.cs | 7 ------- .../Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs | 8 -------- .../Microsoft.Data.SqlClient.TestUtilities/Config.cs | 1 - .../config.default.json | 1 - 5 files changed, 18 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 5f57d70106..d7408fa15e 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -165,7 +165,6 @@ Manual Tests require the below setup to run: |TCPConnectionString | Connection String for a TCP enabled SQL Server instance. | `Server={servername};Database={Database_Name};Trusted_Connection=True;`
OR `Data Source={servername};Initial Catalog={Database_Name};Integrated Security=True;`| |NPConnectionString | Connection String for a Named Pipes enabled SQL Server instance.| `Server=\\{servername}\pipe\sql\query;Database={Database_Name};Trusted_Connection=True;`
OR
`Data Source=np:{servername};Initial Catalog={Database_Name};Integrated Security=True;`| |TCPConnectionStringHGSVBS | (Optional) Connection String for a TCP enabled SQL Server with Host Guardian Service (HGS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = HGS; Enclave Attestation Url = {AttestationURL};`| - |TCPConnectionStringAASVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`| |TCPConnectionStringNoneVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using None Attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = NONE;`| |TCPConnectionStringAASSGX | (Optional) Connection String for a TCP enabled SQL Server with a SGX Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`| |EnclaveEnabled | Enables tests requiring an enclave-configured server.| diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 06209e1ad2..62d4f641ea 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -32,7 +32,6 @@ public static class DataTestUtility public static readonly string NPConnectionString = null; public static readonly string TCPConnectionString = null; public static readonly string TCPConnectionStringHGSVBS = null; - public static readonly string TCPConnectionStringAASVBS = null; public static readonly string TCPConnectionStringNoneVBS = null; public static readonly string TCPConnectionStringAASSGX = null; public static readonly string AADAuthorityURL = null; @@ -144,7 +143,6 @@ static DataTestUtility() NPConnectionString = c.NPConnectionString; TCPConnectionString = c.TCPConnectionString; TCPConnectionStringHGSVBS = c.TCPConnectionStringHGSVBS; - TCPConnectionStringAASVBS = c.TCPConnectionStringAASVBS; TCPConnectionStringNoneVBS = c.TCPConnectionStringNoneVBS; TCPConnectionStringAASSGX = c.TCPConnectionStringAASSGX; AADAuthorityURL = c.AADAuthorityURL; @@ -203,11 +201,6 @@ static DataTestUtility() AEConnStringsSetup.Add(TCPConnectionStringHGSVBS); } - if (!string.IsNullOrEmpty(TCPConnectionStringAASVBS)) - { - AEConnStrings.Add(TCPConnectionStringAASVBS); - } - if (!string.IsNullOrEmpty(TCPConnectionStringNoneVBS)) { AEConnStrings.Add(TCPConnectionStringNoneVBS); diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs index 6a936ac5a1..52bf5c30f4 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs @@ -24,7 +24,6 @@ public static class SqlDbManager private const string TCPConnectionString = "TCPConnectionString"; private const string NPConnectionString = "NPConnectionString"; private const string TCPConnectionStringAASSGX = "TCPConnectionStringAASSGX"; - private const string TCPConnectionStringAASVBS = "TCPConnectionStringAASVBS"; private const string TCPConnectionStringHGSVBS = "TCPConnectionStringHGSVBS"; /// @@ -124,10 +123,6 @@ private static void LoadActiveConnectionStrings() { s_activeConnectionStrings.Add(TCPConnectionStringAASSGX, s_configJson.TCPConnectionStringAASSGX); } - if (!string.IsNullOrEmpty(s_configJson.TCPConnectionStringAASVBS)) - { - s_activeConnectionStrings.Add(TCPConnectionStringAASVBS, s_configJson.TCPConnectionStringAASVBS); - } if (!string.IsNullOrEmpty(s_configJson.TCPConnectionStringHGSVBS)) { s_activeConnectionStrings.Add(TCPConnectionStringHGSVBS, s_configJson.TCPConnectionStringHGSVBS); @@ -148,9 +143,6 @@ private static void UpdateConfig(string key, SqlConnectionStringBuilder builder) case TCPConnectionStringAASSGX: s_configJson.TCPConnectionStringAASSGX = builder.ConnectionString; break; - case TCPConnectionStringAASVBS: - s_configJson.TCPConnectionStringAASVBS = builder.ConnectionString; - break; case TCPConnectionStringHGSVBS: s_configJson.TCPConnectionStringHGSVBS = builder.ConnectionString; break; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs index 14dcd5e086..3fbe8313ee 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs @@ -13,7 +13,6 @@ public class Config public string TCPConnectionString = null; public string NPConnectionString = null; public string TCPConnectionStringHGSVBS = null; - public string TCPConnectionStringAASVBS = null; public string TCPConnectionStringNoneVBS = null; public string TCPConnectionStringAASSGX = null; public string AADAuthorityURL = null; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index f656c3ae15..d159b7628d 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -2,7 +2,6 @@ "TCPConnectionString": "Data Source=tcp:localhost;Database=Northwind;Integrated Security=true;Encrypt=false;", "NPConnectionString": "Data Source=np:localhost;Database=Northwind;Integrated Security=true;Encrypt=false;", "TCPConnectionStringHGSVBS": "", - "TCPConnectionStringAASVBS": "", "TCPConnectionStringNoneVBS": "", "TCPConnectionStringAASSGX": "", "EnclaveEnabled": false, From b4f38f50d4fb03e49956b8007496c50c22fbbea2 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Mon, 6 May 2024 16:27:12 -0700 Subject: [PATCH 43/53] Use ReadOnlyMemory in (#2447) --- .../Interop/SNINativeMethodWrapper.Windows.cs | 9 ++++--- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 19 +++++++++++-- .../Interop/SNINativeManagedWrapperARM64.cs | 2 +- .../Interop/SNINativeManagedWrapperX64.cs | 2 +- .../Interop/SNINativeManagedWrapperX86.cs | 2 +- .../Data/Interop/SNINativeMethodWrapper.cs | 27 ++++++++++--------- .../SSPI/ManagedSSPIContextProvider.cs | 5 ++-- .../SSPI/NativeSSPIContextProvider.cs | 4 +-- .../SSPI/NegotiateSSPIContextProvider.cs | 4 +-- .../SqlClient/SSPI/SSPIContextProvider.cs | 10 +++---- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +-- 11 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs index c8591a8c11..6f75be4e70 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs @@ -315,7 +315,7 @@ private static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, @@ -471,15 +471,16 @@ internal static unsafe void SNIPacketSetData(SNIPacket packet, byte[] data, int } } - internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) + internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) { fixed (byte* pin_serverUserName = &serverUserName[0]) + fixed (byte* pInBuff = inBuff) { bool local_fDone; return SNISecGenClientContextWrapper( pConnectionObject, - inBuff, - receivedLength, + pInBuff, + (uint)inBuff.Length, OutBuff, ref sendLength, out local_fDone, diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index ce3b9dd26b..3276023ef6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Buffers; using System.Diagnostics; using System.IO; using System.Net; @@ -34,7 +35,21 @@ internal class SNIProxy /// Send buffer /// Service Principal Name buffer /// SNI error code - internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) + internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, ReadOnlyMemory receivedBuff, ref byte[] sendBuff, byte[][] serverName) + { + // TODO: this should use ReadOnlyMemory all the way through + byte[] array = null; + + if (!receivedBuff.IsEmpty) + { + array = new byte[receivedBuff.Length]; + receivedBuff.CopyTo(array); + } + + GenSspiClientContext(sspiClientContextStatus, array, ref sendBuff, serverName); + } + + private static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; @@ -189,7 +204,7 @@ internal static SNIHandle CreateConnectionHandle( case DataSource.Protocol.TCP: sniHandle = CreateTcpHandle(details, timeout, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo, tlsFirst, hostNameInCertificate, serverCertificateFilename); - break; + break; case DataSource.Protocol.NP: sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); break; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs index 50552a3fb3..6e9bda11cd 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs index f4970e1cda..acb10c8c79 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs index 6e1a0abf5f..c8bb7c0e93 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs index b9af5849c4..898fcc6866 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs @@ -889,8 +889,7 @@ private static unsafe void SNIPacketSetData(SNIPacket pPacket, [In] byte* pbBuf, private static unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, - uint cbIn, + [In, Out] ReadOnlySpan pIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, [MarshalAsAttribute(UnmanagedType.Bool)] out bool pfDone, @@ -899,16 +898,19 @@ private static unsafe uint SNISecGenClientContextWrapper( [MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszUserName, [MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszPassword) { - switch (s_architecture) + fixed (byte* pInPtr = pIn) { - case System.Runtime.InteropServices.Architecture.Arm64: - return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - case System.Runtime.InteropServices.Architecture.X64: - return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - case System.Runtime.InteropServices.Architecture.X86: - return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - default: - throw ADP.SNIPlatformNotSupported(s_architecture.ToString()); + switch (s_architecture) + { + case System.Runtime.InteropServices.Architecture.Arm64: + return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + case System.Runtime.InteropServices.Architecture.X64: + return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + case System.Runtime.InteropServices.Architecture.X86: + return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + default: + throw ADP.SNIPlatformNotSupported(s_architecture.ToString()); + } } } @@ -1378,7 +1380,7 @@ Int32[] passwordOffsets // Offset into data buffer where the password to be w } } - internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) + internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) { fixed (byte* pin_serverUserName = &serverUserName[0]) { @@ -1386,7 +1388,6 @@ internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, return SNISecGenClientContextWrapper( pConnectionObject, inBuff, - receivedLength, OutBuff, ref sendLength, out local_fDone, diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs index 25fb2cadae..8395371de7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -1,5 +1,6 @@ #if !NETFRAMEWORK && !NET7_0_OR_GREATER +using System; using Microsoft.Data.SqlClient.SNI; #nullable enable @@ -10,11 +11,11 @@ internal sealed class ManagedSSPIContextProvider : SSPIContextProvider { private SspiClientContextStatus? _sspiClientContextStatus; - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { _sspiClientContextStatus ??= new SspiClientContextStatus(); - SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); + SNIProxy.GenSspiClientContext(_sspiClientContextStatus, received, ref sendBuff, _sniSpnBuffer); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _physicalStateObj.SessionId); sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs index 718608d136..067682a617 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs @@ -50,7 +50,7 @@ private void LoadSSPILibrary() } } - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { #if NETFRAMEWORK SNIHandle handle = _physicalStateObj.Handle; @@ -58,7 +58,7 @@ internal override void GenerateSspiClientContext(byte[] receivedBuff, uint recei Debug.Assert(_physicalStateObj.SessionHandle.Type == SessionHandle.NativeHandleType); SNIHandle handle = _physicalStateObj.SessionHandle.NativeHandle; #endif - if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer[0])) + if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff.Span, sendBuff, ref sendLength, _sniSpnBuffer[0])) { throw new InvalidOperationException(SQLMessage.SSPIGenerateError()); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index bc11cf29c9..2d73d28390 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -12,10 +12,10 @@ internal sealed class NegotiateSSPIContextProvider : SSPIContextProvider { private NegotiateAuthentication? _negotiateAuth = null; - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) }); - sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!; + sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out NegotiateAuthenticationStatusCode statusCode)!; SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _physicalStateObj.SessionId, statusCode); if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs index fa8c27e3ab..256818660e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs @@ -27,16 +27,16 @@ private protected virtual void Initialize() { } - internal abstract void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); + internal abstract void GenerateSspiClientContext(ReadOnlyMemory input, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); - internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer) - => SSPIData(receivedBuff, receivedLength, ref sendBuff, ref sendLength, new[] { sniSpnBuffer }); + internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer) + => SSPIData(receivedBuff, ref sendBuff, ref sendLength, new[] { sniSpnBuffer }); - internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) + internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) { try { - GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, sniSpnBuffer); + GenerateSspiClientContext(receivedBuff, ref sendBuff, ref sendLength, sniSpnBuffer); } catch (Exception e) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs index 4366b4665a..8e0569b44b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -31,7 +31,7 @@ internal void ProcessSSPI(int receivedLength) uint sendLength = _authenticationProvider.MaxSSPILength; // make call for SSPI data - _authenticationProvider.SSPIData(receivedBuff, (uint)receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer); + _authenticationProvider.SSPIData(receivedBuff.AsMemory(0, receivedLength), ref sendBuff, ref sendLength, _sniSpnBuffer); // DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA! _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0); @@ -194,7 +194,7 @@ internal void TdsLogin( // byte[] buffer and 0 for the int length. Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'"); _physicalStateObj.SniContext = SniContext.Snix_LoginSspi; - _authenticationProvider.SSPIData(Array.Empty(), 0, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer); + _authenticationProvider.SSPIData(ReadOnlyMemory.Empty, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer); if (outSSPILength > int.MaxValue) { From 4c0f013bac63d8bd928c985440acb1e2bc13d3c6 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 7 May 2024 18:02:12 +0200 Subject: [PATCH 44/53] Remove UWP (uap) references and special cased code (#2483) --- .../src/Microsoft.Data.SqlClient.csproj | 41 ++----- .../Data/SqlClient/LocalDBAPI.uap.cs | 14 --- .../Data/SqlClient/SNI/LocalDB.uap.cs | 14 --- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 45 ------- .../ManualTests/DataCommon/DataTestUtility.cs | 111 +----------------- .../ExceptionTest/ConnectionExceptionTest.cs | 19 --- 7 files changed, 19 insertions(+), 229 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 0a0f573333..57497fd2b0 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -726,6 +726,9 @@ Common\Interop\Windows\Kernel32\Interop.IoControlTransferType.cs + + Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs + Common\Interop\Windows\NtDll\Interop.FILE_FULL_EA_INFORMATION.cs @@ -826,16 +829,25 @@ Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs + + Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs + + + + + + @@ -894,31 +906,6 @@ - - - - - - - - - - - - - - Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs - - - Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs - - - - - - - - @@ -947,10 +934,6 @@ - - - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs deleted file mode 100644 index 9ed10f0fcc..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace System.Data -{ - internal static partial class LocalDBAPI - { - private static IntPtr LoadProcAddress() => - throw new PlatformNotSupportedException(Strings.LocalDBNotSupported); // No Registry support on UAP - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs deleted file mode 100644 index e764375802..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.SqlClient.SNI -{ - internal class LocalDB - { - internal static string GetLocalDBConnectionString(string localDbInstance) - { - throw new PlatformNotSupportedException(Strings.LocalDBNotSupported); // No Registry support on UAP - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 0d3c0a01b5..84b3978bdf 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1509,9 +1509,7 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj) SqlClientEventSource.Log.TryAdvancedTraceEvent(" Empty error message received from SNI. Error Message = {0}", details.errorMessage); } - string sniContextEnumName = TdsEnums.GetSniContextEnumName(stateObj.SniContext); - - string sqlContextInfo = StringsHelper.GetResourceString(sniContextEnumName); + string sqlContextInfo = StringsHelper.GetResourceString(stateObj.SniContext.ToString()); string providerRid = string.Format("SNI_PN{0}", details.provider); string providerName = StringsHelper.GetResourceString(providerRid); Debug.Assert(!string.IsNullOrEmpty(providerName), $"invalid providerResourceId '{providerRid}'"); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index c483d8a0f8..8c7119a695 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -3,11 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Data; -using System.Diagnostics; -using Microsoft.Data.Common; namespace Microsoft.Data.SqlClient { @@ -998,47 +994,6 @@ internal enum FedAuthInfoId : byte internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; internal const byte DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED = 0x02; - // Needed for UapAot, since we cannot use Enum.GetName() on SniContext. - // Enum.GetName() uses reflection, which is blocked on UapAot for internal types - // like SniContext. - internal static string GetSniContextEnumName(SniContext sniContext) - { - switch (sniContext) - { - case SniContext.Undefined: - return "Undefined"; - case SniContext.Snix_Connect: - return "Snix_Connect"; - case SniContext.Snix_PreLoginBeforeSuccessfulWrite: - return "Snix_PreLoginBeforeSuccessfulWrite"; - case SniContext.Snix_PreLogin: - return "Snix_PreLogin"; - case SniContext.Snix_LoginSspi: - return "Snix_LoginSspi"; - case SniContext.Snix_ProcessSspi: - return "Snix_ProcessSspi"; - case SniContext.Snix_Login: - return "Snix_Login"; - case SniContext.Snix_EnableMars: - return "Snix_EnableMars"; - case SniContext.Snix_AutoEnlist: - return "Snix_AutoEnlist"; - case SniContext.Snix_GetMarsSession: - return "Snix_GetMarsSession"; - case SniContext.Snix_Execute: - return "Snix_Execute"; - case SniContext.Snix_Read: - return "Snix_Read"; - case SniContext.Snix_Close: - return "Snix_Close"; - case SniContext.Snix_SendRows: - return "Snix_SendRows"; - default: - Debug.Fail($"Received unknown SniContext enum. Value: {sniContext}"); - return null; - } - } - // TCE Related constants internal const byte MAX_SUPPORTED_TCE_VERSION = 0x03; // max version internal const byte MIN_TCE_VERSION_WITH_ENCLAVE_SUPPORT = 0x02; // min version with enclave support diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 62d4f641ea..e88a72104c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -11,19 +11,19 @@ using System.IO; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; +using System.Runtime.InteropServices; using System.Security; +using System.Security.Principal; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Azure.Core; +using Azure.Identity; using Microsoft.Data.SqlClient.TestUtilities; using Microsoft.Identity.Client; using Xunit; -using System.Net.NetworkInformation; -using System.Text; -using System.Security.Principal; -using System.Runtime.InteropServices; -using Azure.Identity; -using Azure.Core; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -77,10 +77,6 @@ public static class DataTestUtility public const string AKVEventSourceName = "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.EventSource"; private const string ManagedNetworkingAppContextSwitch = "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"; - // uap constant - const long APPMODEL_ERROR_NO_PACKAGE = 15700L; - public static readonly bool IsRunningAsUWPApp = RunningAsUWPApp(); - private static Dictionary AvailableDatabases; private static BaseEventListener TraceListener; @@ -676,10 +672,6 @@ public static string GetUserIdentityAccessToken() public static bool IsAccessTokenSetup() => !string.IsNullOrEmpty(GetAccessToken()); - public static bool IsSystemIdentityTokenSetup() => !string.IsNullOrEmpty(GetSystemIdentityAccessToken()); - - public static bool IsUserIdentityTokenSetup() => !string.IsNullOrEmpty(GetUserIdentityAccessToken()); - public static bool IsFileStreamSetup() => !string.IsNullOrEmpty(FileStreamDirectory) && IsNotAzureServer() && IsNotAzureSynapse(); private static bool CheckException(Exception ex, string exceptionMessage, bool innerExceptionMustBeNull) where TException : Exception @@ -780,58 +772,6 @@ public static TException ExpectFailure(Action actionThatFails, strin } } - public static TException ExpectFailure(Action actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, bool innerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception - { - try - { - actionThatFails(); - Assert.Fail("ERROR: Did not get expected exception"); - return null; - } - catch (Exception ex) - { - if ((CheckException(ex, exceptionMessage, false)) && (CheckException(ex.InnerException, innerExceptionMessage, innerInnerExceptionMustBeNull))) - { - return (ex as TException); - } - else - { - throw; - } - } - } - - public static TException ExpectFailure(Action actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, string innerInnerExceptionMessage = null, bool innerInnerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception where TInnerInnerException : Exception - { - try - { - actionThatFails(); - Assert.Fail("ERROR: Did not get expected exception"); - return null; - } - catch (Exception ex) - { - if ((CheckException(ex, exceptionMessage, false)) && (CheckException(ex.InnerException, innerExceptionMessage, false)) && (CheckException(ex.InnerException.InnerException, innerInnerExceptionMessage, innerInnerInnerExceptionMustBeNull))) - { - return (ex as TException); - } - else - { - throw; - } - } - } - - public static void ExpectAsyncFailure(Func actionThatFails, string exceptionMessage = null, bool innerExceptionMustBeNull = false) where TException : Exception - { - ExpectFailure(() => actionThatFails().Wait(), null, exceptionMessage, innerExceptionMustBeNull); - } - - public static void ExpectAsyncFailure(Func actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, bool innerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception - { - ExpectFailure(() => actionThatFails().Wait(), null, exceptionMessage, innerExceptionMessage, innerInnerExceptionMustBeNull); - } - public static string GenerateObjectName() { return string.Format("TEST_{0}{1}{2}", Environment.GetEnvironmentVariable("ComputerName"), Environment.TickCount, Guid.NewGuid()).Replace('-', '_'); @@ -1093,44 +1033,5 @@ public static string GetMachineFQDN(string hostname) } return fqdn.ToString(); } - - public static bool IsNotLocalhost() - { - // get the tcp connection string - SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); - - string hostname = ""; - - // parse the datasource - ParseDataSource(builder.DataSource, out hostname, out _, out _); - - // hostname must not be localhost, ., 127.0.0.1 nor ::1 - return !(new string[] { "localhost", ".", "127.0.0.1", "::1" }).Contains(hostname.ToLowerInvariant()); - - } - - private static bool RunningAsUWPApp() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return false; - } - else - { - [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName); - - { - int length = 0; - StringBuilder sb = new(0); - _ = GetCurrentPackageFullName(ref length, sb); - - sb = new StringBuilder(length); - int result = GetCurrentPackageFullName(ref length, sb); - - return result != APPMODEL_ERROR_NO_PACKAGE; - } - } - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs index 9b8e7476e4..b1ba557562 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs @@ -176,25 +176,6 @@ public void NamedPipeInvalidConnStringTest() OpenBadConnection(builder.ConnectionString, invalidConnStringError); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsRunningAsUWPApp))] - public static void LocalDBNotSupportedOnUapTest() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(@$"server=(localdb)\{DataTestUtility.LocalDbAppName}") - { - IntegratedSecurity = true, - ConnectTimeout = 2 - }; - - Assert.Throws(() => - { - using (SqlConnection conn = new SqlConnection(builder.ConnectionString)) - { - conn.Open(); - } - }); - } - - private void GenerateConnectionException(string connectionString) { using (SqlConnection sqlConnection = new SqlConnection(connectionString)) From 9a71c94c172fd5b231e9673525e95c7079528fa9 Mon Sep 17 00:00:00 2001 From: Saurabh Singh <1623701+saurabh500@users.noreply.github.com> Date: Mon, 13 May 2024 15:37:01 -0700 Subject: [PATCH 45/53] Update build guide for Linux (#2499) Adding the detail about installing powershell on linux to build the driver --- BUILDGUIDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index d7408fa15e..09143c84cf 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -8,6 +8,8 @@ This project should be built with Visual Studio 2019+ for the best compatibility - **Visual Studio 2019** with imported components: [VS19Components](/tools/vsconfig/VS19Components.vsconfig) +- **Powershell**: To build SqlClient on Linux, powershell is needed as well. Follow the distro specific instructions at [Install Powershell on Linux](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux?view=powershell-7.4) + Once the environment is setup properly, execute the desired set of commands below from the _root_ folder to perform the respective operations: ## Building the driver From cc6ea2181af5473648d5c7f79b71be30132d0ac0 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 14 May 2024 20:30:08 +0200 Subject: [PATCH 46/53] Streamline conditional compilation symbols (#2486) --- .../netcore/ref/Microsoft.Data.SqlClient.cs | 6 +++--- .../Common/src/Interop/Windows/Interop.Libraries.cs | 2 +- .../src/System/Net/Logging/NetEventSource.Common.cs | 4 ++-- .../Data/ProviderBase/DbConnectionPool.NetCoreApp.cs | 2 +- .../Microsoft/Data/ProviderBase/DbConnectionPool.cs | 2 +- .../src/Microsoft/Data/SqlClient/SNI/SNICommon.cs | 4 ++-- .../src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 2 +- .../src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlCommand.cs | 4 ++-- .../SqlConnectionFactory.AssemblyLoadContext.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlDataReader.cs | 2 +- .../Data/SqlClient/SqlDelegatedTransaction.cs | 8 ++++---- .../Data/SqlClient/SqlInternalConnectionTds.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 10 +++++----- .../Data/SqlClient/TdsParserStateObjectManaged.cs | 2 +- .../Data/SqlClient/TdsParserStateObjectNative.cs | 2 +- .../Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs | 4 ++-- .../src/Microsoft/Data/Common/AdapterUtil.Windows.cs | 4 ++-- .../src/Microsoft/Data/Common/AdapterUtil.cs | 2 +- .../DbConnectionPoolAuthenticationContext.cs | 2 +- .../Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs | 6 +++--- .../ActiveDirectoryAuthenticationProvider.cs | 6 ++---- .../Data/SqlClient/LocalAppContextSwitches.cs | 2 +- .../Reliability/SqlConfigurableRetryLogicLoader.cs | 2 +- .../SqlClient/SSPI/ManagedSSPIContextProvider.cs | 2 +- .../SqlClient/SSPI/NegotiateSSPIContextProvider.cs | 2 +- .../Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs | 6 +++--- .../src/Microsoft/Data/SqlClient/SqlBuffer.cs | 2 +- .../Microsoft/Data/SqlClient/SqlCommandBuilder.cs | 2 -- .../Microsoft/Data/SqlClient/SqlConnectionString.cs | 4 ++-- .../Data/SqlClient/SqlConnectionStringBuilder.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlDependency.cs | 4 ++-- .../SqlDependencyUtils.AssemblyLoadContext.cs | 2 +- .../Microsoft/Data/SqlClient/SqlDependencyUtils.cs | 2 +- .../Data/SqlClient/SqlInternalConnection.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlParameter.cs | 2 +- .../Data/SqlClient/TdsParserSafeHandles.Windows.cs | 2 +- .../Microsoft/Data/SqlClient/TdsParserStateObject.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsValueSetter.cs | 12 ++++++------ .../src/Resources/StringsHelper.cs | 2 +- .../src/System/Diagnostics/CodeAnalysis.cs | 2 +- .../tests/FunctionalTests/SqlErrorTest.cs | 2 +- .../tests/FunctionalTests/SqlExceptionTest.cs | 2 +- .../tests/ManualTests/DataCommon/DataTestUtility.cs | 6 +++--- .../SQL/DataReaderTest/DataReaderStreamsTest.cs | 2 +- .../SQL/InstanceNameTest/InstanceNameTest.cs | 2 +- .../SQL/RetryLogic/RetryLogicConfigHelper.cs | 2 +- .../TransactionTest/DistributedTransactionTest.cs | 2 +- 48 files changed, 75 insertions(+), 79 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index a0acf34a33..b228b0a137 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -478,7 +478,7 @@ public static partial class SqlClientMetaDataCollectionNames /// public static readonly string StructuredTypeMembers; } -#if NETCOREAPP +#if NET6_0_OR_GREATER /// public enum SqlConnectionAttestationProtocol { @@ -1017,7 +1017,7 @@ public SqlConnectionStringBuilder(string connectionString) { } [System.ComponentModel.DisplayNameAttribute("Data Source")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public string DataSource { get { throw null; } set { } } -#if NETCOREAPP +#if NET6_0_OR_GREATER /// [System.ComponentModel.DisplayNameAttribute("Attestation Protocol")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] @@ -1444,7 +1444,7 @@ internal SqlException() { } public byte State { get { throw null; } } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)] #endif #if NET8_0_OR_GREATER diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs index 40308195e7..f3c5526e0f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs @@ -9,7 +9,7 @@ internal static partial class Libraries internal const string Crypt32 = "crypt32.dll"; internal const string Kernel32 = "kernel32.dll"; internal const string NtDll = "ntdll.dll"; -#if !NET7_0_OR_GREATER +#if !NET8_0_OR_GREATER internal const string SspiCli = "sspicli.dll"; #endif } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs index 5b908a3b8e..1e56818132 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs @@ -13,7 +13,7 @@ using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if net462 +#if NETFRAMEWORK using System.Security; #endif @@ -45,7 +45,7 @@ namespace System.Net // method that takes an object and optionally provides a string representation of it, in case a particular library wants to customize further. /// Provides logging facilities for System.Net libraries. -#if net462 +#if NETFRAMEWORK [SecuritySafeCritical] #endif internal sealed partial class NetEventSource : EventSource diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs index 9f330c3dcc..4a59e0b858 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System.Diagnostics; using Microsoft.Data.Common; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs index 7858adc93c..3bf8a9d561 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs @@ -776,7 +776,7 @@ private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectio throw; } -#if NETCOREAPP +#if NET6_0_OR_GREATER if (!IsBlockingPeriodEnabled()) { throw; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index 9ccc98a779..2e5d3fd815 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -190,7 +190,7 @@ internal static bool ValidateSslServerCertificate(string targetServerName, X509C if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER X509Certificate2 cert2 = cert as X509Certificate2; if (!cert2.MatchesHostname(targetServerName)) { @@ -297,7 +297,7 @@ internal static bool ValidateSslServerCertificate(X509Certificate clientCert, X5 if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER X509Certificate2 s_cert = serverCert as X509Certificate2; X509Certificate2 c_cert = clientCert as X509Certificate2; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 3276023ef6..77b44a1cf5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -26,7 +26,7 @@ internal class SNIProxy private static readonly SNIProxy s_singleton = new SNIProxy(); internal static SNIProxy Instance => s_singleton; -#if !NET7_0_OR_GREATER +#if !NET8_0_OR_GREATER /// /// Generate SSPI context /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs index d12e91ad62..9d415bcfc8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs @@ -1008,7 +1008,7 @@ public override void KillConnection() internal static void SetKeepAliveValues(ref Socket socket) { -#if NETCOREAPP +#if NET6_0_OR_GREATER socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, 1); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, 30); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index d01c686d04..94325d3c88 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -3994,7 +3994,7 @@ private SqlDataReader GetParameterEncryptionDataReader(out Task returnTask, Task SqlCommand command = (SqlCommand)state; bool processFinallyBlockAsync = true; bool decrementAsyncCountInFinallyBlockAsync = true; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -4068,7 +4068,7 @@ private SqlDataReader GetParameterEncryptionDataReaderAsync(out Task returnTask, bool processFinallyBlockAsync = true; bool decrementAsyncCountInFinallyBlockAsync = true; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs index 38411594af..230b7ae5fc 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System; using System.Reflection; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs index 5eb7d7cdeb..c538483fc8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -1353,7 +1353,7 @@ override public string GetName(int i) } /// -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] #endif override public Type GetProviderSpecificFieldType(int i) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs index 3ed756eef0..2f9e1e8e06 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs @@ -81,7 +81,7 @@ public void Initialize() SqlInternalConnection connection = _connection; SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Initialize | RES | CPOOL | Object Id {0}, Client Connection Id {1}, delegating transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -146,7 +146,7 @@ public byte[] Promote() { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Promote | RES | CPOOL | Object Id {0}, Client Connection Id {1}, promoting transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -256,7 +256,7 @@ public void Rollback(SinglePhaseEnlistment enlistment) { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Rollback | RES | CPOOL | Object Id {0}, Client Connection Id {1}, rolling back transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -343,7 +343,7 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.SinglePhaseCommit | RES | CPOOL | Object Id {0}, Client Connection Id {1}, committing transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index dd7043d629..5ef3d781ea 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2300,7 +2300,7 @@ internal bool TryGetFedAuthTokenLocked(SqlFedAuthInfo fedAuthInfo, DbConnectionP bool authenticationContextLocked = false; // Prepare CER to ensure the lock on authentication context is released. -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 84b3978bdf..abb16eaebe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1774,7 +1774,7 @@ internal void WriteInt(int v, TdsParserStateObject stateObj) internal static void WriteInt(Span buffer, int value) { -#if NETCOREAPP +#if NET6_0_OR_GREATER BinaryPrimitives.TryWriteInt32LittleEndian(buffer, value); #else buffer[0] = (byte)(value & 0xff); @@ -6144,7 +6144,7 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T } else { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER value.SqlBinary = SqlBinary.WrapBytes(b); #else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array @@ -6441,7 +6441,7 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, { return false; } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER value.SqlBinary = SqlBinary.WrapBytes(b); #else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); @@ -7313,7 +7313,7 @@ internal byte[] SerializeSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) Span data = stackalloc uint[4]; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER d.WriteTdsValue(data); #else SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); @@ -7342,7 +7342,7 @@ internal void WriteSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) stateObj.WriteByte(0); Span data = stackalloc uint[4]; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER d.WriteTdsValue(data); #else SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs index 7d879ae4d5..b912ea9f09 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -408,7 +408,7 @@ private SNIHandle GetSessionSNIHandleHandleOrThrow() private void ThrowClosedConnection() => throw ADP.ClosedConnectionError(); internal override SSPIContextProvider CreateSSPIContextProvider() -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER => new NegotiateSSPIContextProvider(); #else => new ManagedSSPIContextProvider(); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index 6f26250072..611a003177 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -409,7 +409,7 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) { protocolVersion = (int)SslProtocols.Tls12; } -#if NETCOREAPP +#if NET6_0_OR_GREATER else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_SERVER)) { /* The SslProtocols.Tls13 is supported by netcoreapp3.1 and later */ diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs index 78682e917f..319e0d0169 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs @@ -297,7 +297,7 @@ public override void Flush() } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [HostProtection(ExternalThreading = true)] #endif public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) @@ -318,7 +318,7 @@ public override int EndRead(IAsyncResult asyncResult) } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [HostProtection(ExternalThreading = true)] #endif public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs index abeadf86b7..6fbdfcb343 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs @@ -26,7 +26,7 @@ internal static partial class ADP [ResourceConsumption(ResourceScope.Machine)] internal static object LocalMachineRegistryValue(string subkey, string queryvalue) { // MDAC 77697 -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK (new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\" + subkey)).Assert(); // MDAC 62028 #endif try @@ -43,7 +43,7 @@ internal static object LocalMachineRegistryValue(string subkey, string queryvalu ADP.TraceExceptionWithoutRethrow(e); return null; } -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK finally { RegistryPermission.RevertAssert(); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index 1ded2eef3a..dcbb89a248 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -668,7 +668,7 @@ private static long TimerToSeconds(long timerValue) /// Note: In Longhorn you'll be able to rename a machine without /// rebooting. Therefore, don't cache this machine name. /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [EnvironmentPermission(SecurityAction.Assert, Read = "COMPUTERNAME")] #endif internal static string MachineName() => Environment.MachineName; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs index 213f4b8b25..29ac7fee31 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs @@ -102,7 +102,7 @@ internal bool LockToUpdate() /// /// Release the lock which was obtained through LockToUpdate. /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] #endif internal void ReleaseLockToUpdate() diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs index 9118e341af..a236d5645e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs @@ -25,7 +25,7 @@ internal static class SqlDataSourceEnumeratorNativeHelper /// internal static DataTable GetDataSources() { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK (new NamedPermissionSet("FullTrust")).Demand(); // SQLBUDT 244304 #endif char[] buffer = null; @@ -37,13 +37,13 @@ internal static DataTable GetDataSources() bool more = true; bool failure = false; IntPtr handle = ADP.s_ptrZero; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try { long s_timeoutTime = TdsParserStaticMethods.GetTimeoutSeconds(ADP.DefaultCommandTimeout); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index 75b55847f7..d40f59c78b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -207,7 +207,7 @@ public override async Task AcquireTokenAsync(SqlAuthenti */ string redirectUri = s_nativeClientRedirectUri; -#if NETCOREAPP +#if NET6_0_OR_GREATER if (parameters.AuthenticationMethod != SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow) { redirectUri = "http://localhost"; @@ -361,7 +361,7 @@ private static async Task AcquireTokenInteractiveDeviceFlo if (authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive) { CancellationTokenSource ctsInteractive = new CancellationTokenSource(); -#if NETCOREAPP +#if NET6_0_OR_GREATER /* * On .NET Core, MSAL will start the system browser as a separate process. MSAL does not have control over this browser, * but once the user finishes authentication, the web page is redirected in such a way that MSAL can intercept the Uri. @@ -492,8 +492,6 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ .WithParentActivityOrWindow(_iWin32WindowFunc) .Build(); } -#endif -#if !NETCOREAPP else #endif { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index ed2c4aedf7..5d35159d60 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -26,7 +26,7 @@ private enum Tristate : byte private static Tristate s_makeReadAsyncBlocking; private static Tristate s_useMinimumLoginTimeout; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER static LocalAppContextSwitches() { IAppContextSwitchOverridesSection appContextSwitch = AppConfigManager.FetchConfigurationSection(AppContextSwitchOverridesSection.Name); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs index a4d197d5e2..ab69ed288f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs @@ -43,7 +43,7 @@ public SqlConfigurableRetryLogicLoader(ISqlConfigurableRetryConnectionSection co string cnnSectionName = SqlConfigurableRetryConnectionSection.Name, string cmdSectionName = SqlConfigurableRetryCommandSection.Name) { -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER // Just only one subscription to this event is required. // This class isn't supposed to be called more than one time; // SqlConfigurableRetryLogicManager manages a single instance of this class. diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs index 8395371de7..546ee11366 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -1,4 +1,4 @@ -#if !NETFRAMEWORK && !NET7_0_OR_GREATER +#if NET6_0 using System; using Microsoft.Data.SqlClient.SNI; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index 2d73d28390..2c68839e3f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER using System; using System.Text; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 4662bc6012..7dd4abd7c1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -15,7 +15,7 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlTypes; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER using SmiContext = System.Object; #endif @@ -3174,7 +3174,7 @@ private static SqlMoney GetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedG long temp = getters.GetInt64(sink, ordinal); sink.ProcessMessagesAndThrow(); -#if NETCOREAPP && NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return SqlMoney.FromTdsValue(temp); #else return SqlTypeWorkarounds.SqlMoneyCtor(temp, 1 /* ignored */ ); @@ -3658,7 +3658,7 @@ private static void SetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedSette sink.ProcessMessagesAndThrow(); } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER setters.SetInt64(sink, ordinal, value.GetTdsValue()); #else setters.SetInt64(sink, ordinal, SqlTypeWorkarounds.SqlMoneyToSqlInternalRepresentation(value)); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs index 31678a3107..f28bf6033b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -886,7 +886,7 @@ internal SqlMoney SqlMoney { return SqlMoney.Null; } -#if NETCOREAPP && NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return SqlMoney.FromTdsValue(_value._int64); #else return SqlTypeWorkarounds.SqlMoneyCtor(_value._int64, 1/*ignored*/); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs index 90546993a6..e256dde95c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs @@ -256,8 +256,6 @@ public static void DeriveParameters(SqlCommand command) } #if NETFRAMEWORK TdsParser bestEffortCleanupTarget = null; -#endif -#if !NET6_0_OR_GREATER RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index 73de1ad4f7..bbcf46d727 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -836,7 +836,7 @@ internal static Dictionary GetParseSynonyms() { int count = SqlConnectionStringBuilder.KeywordsCount + SynonymCount; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER count += SqlConnectionStringBuilder.DeprecatedKeywordsCount + DeprecatedSynonymCount; #endif synonyms = new Dictionary(count, StringComparer.OrdinalIgnoreCase) @@ -1024,7 +1024,7 @@ internal ApplicationIntent ConvertValueToApplicationIntent() // ArgumentException and other types are raised as is (no wrapping) } -#if NETCOREAPP +#if NET6_0_OR_GREATER internal void ThrowUnsupportedIfKeywordSet(string keyword) { if (ContainsKey(keyword)) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs index c9f9fd2912..3abb275a9f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -638,7 +638,7 @@ private void SetPoolBlockingPeriodValue(PoolBlockingPeriod value) private Exception UnsupportedKeyword(string keyword) { -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER for (int index = 0; index < s_notSupportedKeywords.Length; index++) { if (string.Equals(keyword, s_notSupportedKeywords[index], StringComparison.OrdinalIgnoreCase)) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs index 401cde2fa2..0b882bc02c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs @@ -629,7 +629,7 @@ internal static bool Start(string connectionString, string queue, bool useDefaul string database = null; string service = null; bool appDomainStart = false; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -775,7 +775,7 @@ internal static bool Stop(string connectionString, string queue, bool useDefault if (useDefaults) { bool appDomainStop = false; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs index c3f82f0047..34052c3a9d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System; using System.Reflection; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs index 3aa1697d03..c3a0bb1492 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs @@ -107,7 +107,7 @@ private SqlDependencyPerAppDomainDispatcher() } } -#if NETCOREAPP +#if NET6_0_OR_GREATER partial void SubscribeToAppDomainUnload(); partial void SubscribeToAssemblyLoadContextUnload(); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs index 25e1808e56..401815cf94 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs @@ -27,7 +27,7 @@ internal abstract class SqlInternalConnection : DbConnectionInternal private bool _isGlobalTransactionEnabledForServer; // Whether Global Transactions are enabled for this Azure SQL DB Server private static readonly Guid s_globalTransactionTMID = new("1c742caf-6680-40ea-9c26-6b6846079764"); // ID of the Non-MSDTC, Azure SQL DB Transaction Manager -#if NETCOREAPP +#if NET6_0_OR_GREATER internal SqlCommand.ExecuteReaderAsyncCallContext CachedCommandExecuteReaderAsyncContext; internal SqlCommand.ExecuteNonQueryAsyncCallContext CachedCommandExecuteNonQueryAsyncContext; internal SqlCommand.ExecuteXmlReaderAsyncCallContext CachedCommandExecuteXmlReaderAsyncContext; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs index ee3a09c17a..a7c7fa58e1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -844,7 +844,7 @@ public override string SourceColumn /// [ResCategory("DataCategory_Update")] -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER [ResDescription(StringsHelper.ResourceNames.SqlParameter_SourceColumnNullMapping)] #endif public override bool SourceColumnNullMapping diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs index 8d276cd285..dba1ec788c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs @@ -164,7 +164,7 @@ internal SNIHandle( string hostNameInCertificate) : base(IntPtr.Zero, true) { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 17729a4cc9..4aadbee4bd 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -976,7 +976,7 @@ internal bool TryProcessHeader() _inBuff[_inBytesUsed + TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - _inputHeaderLen; _spid = _inBuff[_inBytesUsed + TdsEnums.SPID_OFFSET] << 8 | _inBuff[_inBytesUsed + TdsEnums.SPID_OFFSET + 1]; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER SqlClientEventSource.Log.TryAdvancedTraceEvent("TdsParserStateObject.TryProcessHeader | ADV | State Object Id {0}, Client Connection Id {1}, Server process Id (SPID) {2}", _objectID, _parser?.Connection?.ClientConnectionId, _spid); #endif _inBytesUsed += _inputHeaderLen; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs index dc797ced8e..6b05698972 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs @@ -587,7 +587,7 @@ internal void SetDateTime(DateTime value) if (SqlDbType.DateTime2 == _metaData.SqlDbType) { long time = value.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[_metaData.Scale]; -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_time = stackalloc byte[8]; BinaryPrimitives.WriteInt64LittleEndian(result_time, time); _stateObj.WriteByteSpan(result_time.Slice(0, (int)_metaData.MaxLength - 3)); @@ -595,7 +595,7 @@ internal void SetDateTime(DateTime value) _stateObj.WriteByteArray(BitConverter.GetBytes(time), (int)_metaData.MaxLength - 3, 0); #endif } -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_date = stackalloc byte[4]; BinaryPrimitives.WriteInt32LittleEndian(result_date, days); _stateObj.WriteByteSpan(result_date.Slice(0, 3)); @@ -612,7 +612,7 @@ internal void SetGuid(Guid value) Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetGuid)); -#if NETCOREAPP +#if NET6_0_OR_GREATER Span bytes = stackalloc byte[16]; value.TryWriteBytes(bytes); @@ -631,7 +631,7 @@ internal void SetGuid(Guid value) _stateObj.WriteByte((byte)_metaData.MaxLength); } -#if NETCOREAPP +#if NET6_0_OR_GREATER _stateObj.WriteByteSpan(bytes); #else _stateObj.WriteByteArray(bytes, bytes.Length, 0); @@ -659,7 +659,7 @@ internal void SetTimeSpan(TimeSpan value) _stateObj.WriteByte(length); } long time = value.Ticks / TdsEnums.TICKS_FROM_SCALE[scale]; -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_time = stackalloc byte[8]; BinaryPrimitives.WriteInt64LittleEndian(result_time, time); _stateObj.WriteByteSpan(result_time.Slice(0, length)); @@ -696,7 +696,7 @@ internal void SetDateTimeOffset(DateTimeOffset value) int days = utcDateTime.Subtract(DateTime.MinValue).Days; short offset = (short)value.Offset.TotalMinutes; -#if NETCOREAPP +#if NET6_0_OR_GREATER // In TDS protocol: // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/786f5b8a-f87d-4980-9070-b9b7274c681d // diff --git a/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs b/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs index 3f003c081c..d1b736f595 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs @@ -63,7 +63,7 @@ public static string GetString(string res, params object[] args) } } -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER // This method is used to decide if we need to append the exception message parameters to the message when calling Strings.Format. // by default it returns false. // Native code generators can replace the value this returns based on user input at the time of native code generation. diff --git a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs index 1c021b459a..aaca20a34d 100644 --- a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs +++ b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics.CodeAnalysis { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] internal sealed class MemberNotNullAttribute : Attribute { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs index bce79cb6d1..ee05379870 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs @@ -16,7 +16,7 @@ public class SqlErrorTest "Connecting to a mirrored SQL Server instance using the MultiSubnetFailover connection option is not supported."; private const byte FATAL_ERROR_CLASS = 20; -#if !NET50_OR_LATER +#if NETFRAMEWORK [Fact] public static void SqlErrorSerializationTest() { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs index 204ab379c1..85d3a02fb1 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs @@ -33,7 +33,7 @@ public void SerializationTest() Assert.Equal(e.StackTrace, sqlEx.StackTrace); } -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [Fact] [ActiveIssue("12161", TestPlatforms.AnyUnix)] public static void SqlExcpetionSerializationTest() diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index e88a72104c..34fbacb218 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -467,7 +467,7 @@ public static bool IsTargetReadyForAeWithKeyStore() public static bool IsSupportingDistributedTransactions() { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return OperatingSystem.IsWindows() && System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture != System.Runtime.InteropServices.Architecture.X86 && IsNotAzureServer(); #elif NETFRAMEWORK return IsNotAzureServer(); @@ -481,8 +481,8 @@ public static bool IsSupportingDistributedTransactions() public static bool IsNotUsingManagedSNIOnWindows() => !UseManagedSNIOnWindows; public static bool IsUsingNativeSNI() => -#if !NETFRAMEWORK - DataTestUtility.IsNotUsingManagedSNIOnWindows(); +#if NET6_0_OR_GREATER + IsNotUsingManagedSNIOnWindows(); #else true; #endif diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs index 3f16a3a138..3902f812fc 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs @@ -472,7 +472,7 @@ public static void InvalidCastExceptionStream(CommandBehavior behavior, Accessor } } -#if NETCOREAPP +#if NET6_0_OR_GREATER [ConditionalFact(typeof(DataTestUtility),nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public static async void ReadAsyncContentsCompletes() { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index aa72bb6f5b..61474ece7f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -86,7 +86,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove } } -#if NETCOREAPP +#if NET6_0_OR_GREATER [ActiveIssue("27824")] // When specifying instance name and port number, this method call always returns false [ConditionalFact(nameof(IsSPNPortNumberTestForTCP))] public static void PortNumberInSPNTestForTCP() diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs index 7162c4dcaa..21370c08e7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs @@ -73,7 +73,7 @@ public static object CreateLoader(RetryLogicConfigs cnnConfig, RetryLogicConfigs public static void ApplyContextSwitchByManager(string name, bool value) { -#if NETCOREAPP +#if NET6_0_OR_GREATER var appCtxType = s_sqlClientAssembly.GetType(AppCtxCfgTypeName); var appCtxObj = Activator.CreateInstance(appCtxType); SetValue(appCtxObj, appCtxType, "Value", string.Concat(name, "=", value)); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs index dc04ea56ae..658104e193 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs @@ -8,7 +8,7 @@ using System.Transactions; using Xunit; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER namespace Microsoft.Data.SqlClient.ManualTesting.Tests { From 5cb73fdc9fa408fcd033510b2e2182085c1f14c9 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Tue, 14 May 2024 19:31:10 +0100 Subject: [PATCH 47/53] Merged SqlClientFactory between .NET Core and Framework (#2369) --- .../netcore/ref/Microsoft.Data.SqlClient.cs | 30 +++-- .../src/Microsoft.Data.SqlClient.csproj | 5 +- .../SqlClient/SqlClientFactory.NetCoreApp.cs | 24 ---- .../Data/SqlClient/SqlClientFactory.cs | 55 --------- .../netfx/src/Microsoft.Data.SqlClient.csproj | 6 +- .../Data/SqlClient/SqlClientFactory.cs | 98 ---------------- .../Data/SqlClient/SqlClientFactory.cs | 108 ++++++++++++++++++ .../FunctionalTests/SqlClientFactoryTest.cs | 36 +++--- 8 files changed, 149 insertions(+), 213 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs delete mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index b228b0a137..72203bb433 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -189,23 +189,23 @@ public class SqlAuthenticationParameters /// protected SqlAuthenticationParameters(Microsoft.Data.SqlClient.SqlAuthenticationMethod authenticationMethod, string serverName, string databaseName, string resource, string authority, string userId, string password, System.Guid connectionId, int connectionTimeout) { } /// - public Microsoft.Data.SqlClient.SqlAuthenticationMethod AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Data.SqlClient.SqlAuthenticationMethod AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public System.Guid ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Guid ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string DatabaseName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DatabaseName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string ServerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ServerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public int ConnectionTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int ConnectionTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } /// public abstract partial class SqlAuthenticationProvider @@ -231,9 +231,9 @@ public partial class SqlAuthenticationToken /// public SqlAuthenticationToken(string accessToken, System.DateTimeOffset expiresOn) { } /// - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public System.DateTimeOffset ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.DateTimeOffset ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } /// public sealed partial class SqlBulkCopy : System.IDisposable @@ -427,6 +427,14 @@ internal SqlClientFactory() { } public override System.Data.Common.DbDataAdapter CreateDataAdapter() { throw null; } /// public override System.Data.Common.DbParameter CreateParameter() { throw null; } + /// + public override System.Data.Common.DbDataSourceEnumerator CreateDataSourceEnumerator() { throw null; } + /// + public override bool CanCreateBatch { get { throw null; } } + /// + public override System.Data.Common.DbBatch CreateBatch() { throw null; } + /// + public override System.Data.Common.DbBatchCommand CreateBatchCommand() { throw null; } } /// public partial class SqlClientLogger diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 57497fd2b0..2cd3537ea7 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -383,6 +383,9 @@ Microsoft\Data\SqlClient\SqlClientEventSource.cs + + Microsoft\Data\SqlClient\SqlClientFactory.cs + Microsoft\Data\SqlClient\SqlClientLogger.cs @@ -646,8 +649,6 @@ - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs deleted file mode 100644 index a48179b621..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET6_0_OR_GREATER - -using System.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - public sealed partial class SqlClientFactory : DbProviderFactory - { - /// - public override bool CanCreateBatch => true; - - /// - public override DbBatch CreateBatch() => new SqlBatch(); - - /// - public override DbBatchCommand CreateBatchCommand() => new SqlBatchCommand(); - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs deleted file mode 100644 index 2dd3261fe6..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - /// - public sealed partial class SqlClientFactory : DbProviderFactory - { - /// - public static readonly SqlClientFactory Instance = new SqlClientFactory(); - - private SqlClientFactory() - { - } - - /// - public override DbCommand CreateCommand() - { - return new SqlCommand(); - } - - /// - public override DbCommandBuilder CreateCommandBuilder() - { - return new SqlCommandBuilder(); - } - - /// - public override DbConnection CreateConnection() - { - return new SqlConnection(); - } - - /// - public override DbConnectionStringBuilder CreateConnectionStringBuilder() - { - return new SqlConnectionStringBuilder(); - } - - /// - public override DbDataAdapter CreateDataAdapter() - { - return new SqlDataAdapter(); - } - - /// - public override DbParameter CreateParameter() - { - return new SqlParameter(); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 2dd8d69b08..e291206a4a 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -423,6 +423,9 @@ Microsoft\Data\SqlClient\SqlClientEventSource.cs + + Microsoft\Data\SqlClient\SqlClientFactory.cs + Microsoft\Data\SqlClient\SqlClientLogger.cs @@ -668,7 +671,6 @@ - @@ -766,4 +768,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs deleted file mode 100644 index 3d44d202c0..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Data.Common; -using System.Data.Sql; -using System.Security; -using System.Security.Permissions; -using Microsoft.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - /// - public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider - { - - /// - public static readonly SqlClientFactory Instance = new SqlClientFactory(); - - private SqlClientFactory() - { - } - - /// - public override bool CanCreateDataSourceEnumerator - { - get - { - return true; - } - } - - /// - public override DbCommand CreateCommand() - { - return new SqlCommand(); - } - - /// - public override DbCommandBuilder CreateCommandBuilder() - { - return new SqlCommandBuilder(); - } - - /// - public override DbConnection CreateConnection() - { - return new SqlConnection(); - } - - /// - public override DbConnectionStringBuilder CreateConnectionStringBuilder() - { - return new SqlConnectionStringBuilder(); - } - - /// - public override DbDataAdapter CreateDataAdapter() - { - return new SqlDataAdapter(); - } - - /// - public override DbParameter CreateParameter() - { - return new SqlParameter(); - } - - /// - public override CodeAccessPermission CreatePermission(PermissionState state) - { - return new SqlClientPermission(state); - } - - /// - public override DbDataSourceEnumerator CreateDataSourceEnumerator() - { - return SqlDataSourceEnumerator.Instance; - } - - /// - /// Extension mechanism for additional services; currently the only service - /// supported is the DbProviderServices - /// - /// requested service provider or null. - object IServiceProvider.GetService(Type serviceType) - { - object result = null; - if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type) - { - result = GreenMethods.MicrosoftDataSqlClientSqlProviderServices_Instance(); - } - return result; - } - } -} - diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs new file mode 100644 index 0000000000..eacf4d6e55 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs @@ -0,0 +1,108 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Data.Sql; +using System; +using System.Data.Common; +using System.Security.Permissions; +using System.Security; +using Microsoft.Data.Common; + +namespace Microsoft.Data.SqlClient +{ + /// + public sealed class SqlClientFactory : DbProviderFactory +#if NETFRAMEWORK + , IServiceProvider +#endif + { + + /// + public static readonly SqlClientFactory Instance = new SqlClientFactory(); + + private SqlClientFactory() + { + } + + /// + public override bool CanCreateDataSourceEnumerator => true; + + /// + public override DbCommand CreateCommand() + { + return new SqlCommand(); + } + + /// + public override DbCommandBuilder CreateCommandBuilder() + { + return new SqlCommandBuilder(); + } + + /// + public override DbConnection CreateConnection() + { + return new SqlConnection(); + } + + /// + public override DbConnectionStringBuilder CreateConnectionStringBuilder() + { + return new SqlConnectionStringBuilder(); + } + + /// + public override DbDataAdapter CreateDataAdapter() + { + return new SqlDataAdapter(); + } + + /// + public override DbParameter CreateParameter() + { + return new SqlParameter(); + } + +#if NETFRAMEWORK + /// + public override CodeAccessPermission CreatePermission(PermissionState state) + { + return new SqlClientPermission(state); + } + + /// + /// Extension mechanism for additional services; currently the only service + /// supported is the DbProviderServices + /// + /// requested service provider or null. + object IServiceProvider.GetService(Type serviceType) + { + object result = null; + if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type) + { + result = GreenMethods.MicrosoftDataSqlClientSqlProviderServices_Instance(); + } + return result; + } +#endif + + /// + public override DbDataSourceEnumerator CreateDataSourceEnumerator() + { + return SqlDataSourceEnumerator.Instance; + } + +#if NET6_0_OR_GREATER + /// + public override bool CanCreateBatch => true; + + /// + public override DbBatch CreateBatch() => new SqlBatch(); + + /// + public override DbBatchCommand CreateBatchCommand() => new SqlBatchCommand(); +#endif + + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs index f0e8d39173..b88ae0a260 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs @@ -21,40 +21,34 @@ public void InstanceTest() public static readonly object[][] FactoryMethodTestData = { - new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand) }, - new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder) }, - new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection) }, - new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder) }, - new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter) }, - new object[] { new Func(SqlClientFactory.Instance.CreateParameter), typeof(SqlParameter) }, + new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateParameter), typeof(SqlParameter), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateDataSourceEnumerator), typeof(Microsoft.Data.Sql.SqlDataSourceEnumerator), true }, }; [Theory] [MemberData(nameof(FactoryMethodTestData))] - public void FactoryMethodTest(Func factory, Type expectedType) + public void FactoryMethodTest(Func factory, Type expectedType, bool singleton) { object value1 = factory(); Assert.NotNull(value1); Assert.IsType(expectedType, value1); - object value2 = factory(); - Assert.NotNull(value2); - Assert.IsType(expectedType, value2); + if (!singleton) + { + object value2 = factory(); + Assert.NotNull(value2); + Assert.IsType(expectedType, value2); - Assert.NotSame(value1, value2); + Assert.NotSame(value1, value2); + } } #if NETFRAMEWORK - [Fact] - public void FactoryCreateDataSourceEnumerator() - { - // Unable to cover the in the FactoryMethodTest because the SqlDataSourceEnumerator is a singleton so, it's always the same. - object instance = SqlClientFactory.Instance.CreateDataSourceEnumerator(); - // SqlDataSourceEnumerator is not available for .NET core 3.1 and above, so the type check is only for .NET Framework. - Assert.IsType(instance); - Assert.NotNull(instance); - } - [Fact] public void FactoryGetService() { From cd7a3d10e88a15e6151afca1d0f2b972d6058fcb Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Thu, 23 May 2024 09:20:03 -0700 Subject: [PATCH 48/53] Updating Azure.Identity version to 1.11.3 (#2526) --- tools/props/Versions.props | 2 +- tools/specs/Microsoft.Data.SqlClient.nuspec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/props/Versions.props b/tools/props/Versions.props index 022c9a4c7a..29d1201137 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -27,7 +27,7 @@ - 1.11.2 + 1.11.3 4.60.3 7.5.0 7.5.0 diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index b1666d4459..6bbc961ac7 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -29,7 +29,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -40,7 +40,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -50,7 +50,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + From b178ba5d324cfc77a4ff68cf7c250895f766dbeb Mon Sep 17 00:00:00 2001 From: David Engel Date: Thu, 23 May 2024 12:10:21 -0700 Subject: [PATCH 49/53] Fix | Clone of SqlConnection should include AccessTokenCallback (#2525) --- .../src/Microsoft/Data/SqlClient/SqlConnection.cs | 1 + .../src/Microsoft/Data/SqlClient/SqlConnection.cs | 1 + .../tests/FunctionalTests/CloneTests.cs | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index 4b4e7ccc43..1d044633ec 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -227,6 +227,7 @@ private SqlConnection(SqlConnection connection) } _accessToken = connection._accessToken; + _accessTokenCallback = connection._accessTokenCallback; CacheConnectionStringProperties(); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs index b6104b9075..b9d2e32daa 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -429,6 +429,7 @@ private SqlConnection(SqlConnection connection) _credential = new SqlCredential(connection._credential.UserId, password); } _accessToken = connection._accessToken; + _accessTokenCallback = connection._accessTokenCallback; _serverCertificateValidationCallback = connection._serverCertificateValidationCallback; _clientCertificateRetrievalCallback = connection._clientCertificateRetrievalCallback; _originalNetworkAddressInfo = connection._originalNetworkAddressInfo; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs index f5deb6c62c..1c8efc4456 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs @@ -4,6 +4,7 @@ using System; using System.Data; +using System.Threading.Tasks; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -18,10 +19,19 @@ public void CloneSqlConnection() builder.ConnectTimeout = 1; builder.InitialCatalog = "northwinddb"; SqlConnection connection = new SqlConnection(builder.ConnectionString); + connection.AccessToken = Guid.NewGuid().ToString(); SqlConnection clonedConnection = (connection as ICloneable).Clone() as SqlConnection; Assert.Equal(connection.ConnectionString, clonedConnection.ConnectionString); Assert.Equal(connection.ConnectionTimeout, clonedConnection.ConnectionTimeout); + Assert.Equal(connection.AccessToken, clonedConnection.AccessToken); + Assert.NotEqual(connection, clonedConnection); + + connection = new SqlConnection(builder.ConnectionString); + connection.AccessTokenCallback = (ctx, token) => + Task.FromResult(new SqlAuthenticationToken(Guid.NewGuid().ToString(), DateTimeOffset.MaxValue)); + clonedConnection = (connection as ICloneable).Clone() as SqlConnection; + Assert.Equal(connection.AccessTokenCallback, clonedConnection.AccessTokenCallback); Assert.NotEqual(connection, clonedConnection); } From b7c4007d0deb2c2ffa8281f7f731a59f42a5fce1 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 24 May 2024 10:21:39 -0700 Subject: [PATCH 50/53] Enhancement | Add trace logs for packet size (#2522) --- .../netcore/src/Microsoft/Data/SqlClient/TdsParser.cs | 3 +++ .../netfx/src/Microsoft/Data/SqlClient/TdsParser.cs | 3 +++ .../src/Microsoft/Data/SqlClient/TdsParserStateObject.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index abb16eaebe..8a5ed05abe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -2740,6 +2740,9 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, // to MARS initialization! int packetSize = int.Parse(env._newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Server sent env packet size change of {2}, ClientConnectionID {3}", + nameof(TdsParser), nameof(TryProcessEnvChange), packetSize, _connHandler._clientConnectionId); + if (_physicalStateObj.SetPacketSize(packetSize)) { // If packet size changed, we need to release our SNIPackets since diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 7c8fc724c6..afa5220563 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -3182,6 +3182,9 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, // to MARS initialization! int packetSize = int.Parse(env._newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Server sent env packet size change of {2}, ClientConnectionID {3}", + nameof(TdsParser), nameof(TryProcessEnvChange), packetSize, _connHandler._clientConnectionId); + if (_physicalStateObj.SetPacketSize(packetSize)) { // If packet size changed, we need to release our SNIPackets since diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 4aadbee4bd..4347d0f2e0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -1097,6 +1097,9 @@ internal bool SetPacketSize(int size) (_outBytesUsed == _outputHeaderLen && _outputPacketNumber == 1), "SetPacketSize called with data in the buffer!"); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | State Object Id {2}, Setting packet size to {3}", + nameof(TdsParserStateObject), nameof(SetPacketSize), _objectID, size); + if (_inBuff == null || _inBuff.Length != size) { // We only check _inBuff, since two buffers should be consistent. // Allocate or re-allocate _inBuff. From 815e5ab19e9e096bc52f13a82170aa1c5e641826 Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Tue, 28 May 2024 09:37:31 -0700 Subject: [PATCH 51/53] Doc | Fix SNI dependencies of 5.1 and 5.2 release notes (#2537) --- release-notes/5.1/5.1.0.md | 4 ++-- release-notes/5.1/5.1.1.md | 4 ++-- release-notes/5.1/5.1.2.md | 4 ++-- release-notes/5.1/5.1.3.md | 4 ++-- release-notes/5.1/5.1.4.md | 4 ++-- release-notes/5.1/5.1.5.md | 4 ++-- release-notes/5.2/5.2.0-preview1.md | 4 ++-- release-notes/5.2/5.2.0-preview2.md | 4 ++-- release-notes/5.2/5.2.0-preview3.md | 4 ++-- release-notes/5.2/5.2.0.md | 8 ++++---- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/release-notes/5.1/5.1.0.md b/release-notes/5.1/5.1.0.md index e7c4eae495..adbf449e63 100644 --- a/release-notes/5.1/5.1.0.md +++ b/release-notes/5.1/5.1.0.md @@ -79,7 +79,7 @@ The default value of the `ServerCertificate` connection setting is an empty stri #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -95,7 +95,7 @@ The default value of the `ServerCertificate` connection setting is an empty stri #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.1.md b/release-notes/5.1/5.1.1.md index bf40701739..057466a565 100644 --- a/release-notes/5.1/5.1.1.md +++ b/release-notes/5.1/5.1.1.md @@ -37,7 +37,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -53,7 +53,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.2.md b/release-notes/5.1/5.1.2.md index 14c4b347ad..cb9ccc5992 100644 --- a/release-notes/5.1/5.1.2.md +++ b/release-notes/5.1/5.1.2.md @@ -45,7 +45,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -61,7 +61,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.3.md b/release-notes/5.1/5.1.3.md index 75a3140a6d..7889bf61bb 100644 --- a/release-notes/5.1/5.1.3.md +++ b/release-notes/5.1/5.1.3.md @@ -34,7 +34,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -50,7 +50,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.4.md b/release-notes/5.1/5.1.4.md index 3f4e784b75..c1638b1eee 100644 --- a/release-notes/5.1/5.1.4.md +++ b/release-notes/5.1/5.1.4.md @@ -37,7 +37,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -53,7 +53,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.5.md b/release-notes/5.1/5.1.5.md index c25672a8d1..e05c26861f 100644 --- a/release-notes/5.1/5.1.5.md +++ b/release-notes/5.1/5.1.5.md @@ -39,7 +39,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.JsonWebTokens 6.35.0 @@ -55,7 +55,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 diff --git a/release-notes/5.2/5.2.0-preview1.md b/release-notes/5.2/5.2.0-preview1.md index 84a4678452..152b3169b8 100644 --- a/release-notes/5.2/5.2.0-preview1.md +++ b/release-notes/5.2/5.2.0-preview1.md @@ -63,7 +63,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -82,7 +82,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0-preview2.md b/release-notes/5.2/5.2.0-preview2.md index 6cfd799f69..360894b93a 100644 --- a/release-notes/5.2/5.2.0-preview2.md +++ b/release-notes/5.2/5.2.0-preview2.md @@ -84,7 +84,7 @@ Example usage: #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -103,7 +103,7 @@ Example usage: #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0-preview3.md b/release-notes/5.2/5.2.0-preview3.md index 0aa43912d2..82173a5744 100644 --- a/release-notes/5.2/5.2.0-preview3.md +++ b/release-notes/5.2/5.2.0-preview3.md @@ -81,7 +81,7 @@ Example usage: #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -100,7 +100,7 @@ Example usage: #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0.md b/release-notes/5.2/5.2.0.md index e499e795da..aef0863b6c 100644 --- a/release-notes/5.2/5.2.0.md +++ b/release-notes/5.2/5.2.0.md @@ -216,7 +216,7 @@ Example usage: #### .NET 6 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -228,7 +228,7 @@ Example usage: #### .NET 8 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -240,7 +240,7 @@ Example usage: #### .NET Standard 2.0 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -259,7 +259,7 @@ Example usage: #### .NET Standard 2.1 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 From 808d4c3b5a935e6954c96ce02d99c53b624099dc Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Wed, 29 May 2024 18:45:55 -0500 Subject: [PATCH 52/53] Change | Separate tests for NetFx and NetCore - NetFx-Only Connection String Properties (#2466) * Adding TransparentNetworkIpResolution to list of unsupported on platform connection string error messages Splitting unit test for netfx-only connection string properties such that test does not fail on netcore * Remove DeprecatedSynonymCount since referencing the unsupported array is not possible --- .../Data/Common/DbConnectionStringCommon.cs | 5 ++- .../Data/SqlClient/SqlConnectionString.cs | 3 +- .../SqlClient/SqlConnectionStringBuilder.cs | 11 ++++--- .../SqlConnectionStringBuilderTest.cs | 33 ++++++++++++++----- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs index 35aaf412a5..95a54538f9 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs @@ -1037,7 +1037,6 @@ internal static class DbConnectionStringKeywords internal const string OmitOracleConnectionName = "Omit Oracle Connection Name"; // SqlClient - internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution"; internal const string Certificate = "Certificate"; #endif // SqlClient @@ -1073,6 +1072,7 @@ internal static class DbConnectionStringKeywords internal const string IPAddressPreference = "IP Address Preference"; internal const string ServerSPN = "Server SPN"; internal const string FailoverPartnerSPN = "Failover Partner SPN"; + internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution"; // common keywords (OleDb, OracleClient, SqlClient) internal const string DataSource = "Data Source"; @@ -1092,10 +1092,9 @@ internal static class DbConnectionStringKeywords internal static class DbConnectionStringSynonyms { -#if NETFRAMEWORK //internal const string TransparentNetworkIPResolution = TRANSPARENTNETWORKIPRESOLUTION; internal const string TRANSPARENTNETWORKIPRESOLUTION = "transparentnetworkipresolution"; -#endif + //internal const string ApplicationName = APP; internal const string APP = "app"; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index bbcf46d727..243efb3db1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -233,7 +233,6 @@ internal static class TRANSACTIONBINDING internal const int SynonymCount = 33; #else internal const int SynonymCount = 30; - internal const int DeprecatedSynonymCount = 2; #endif // NETFRAMEWORK private static Dictionary s_sqlClientSynonyms; @@ -837,7 +836,7 @@ internal static Dictionary GetParseSynonyms() int count = SqlConnectionStringBuilder.KeywordsCount + SynonymCount; #if NET6_0_OR_GREATER - count += SqlConnectionStringBuilder.DeprecatedKeywordsCount + DeprecatedSynonymCount; + count += SqlConnectionStringBuilder.DeprecatedKeywordsCount; #endif synonyms = new Dictionary(count, StringComparer.OrdinalIgnoreCase) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs index 3abb275a9f..de8319c526 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -139,7 +139,7 @@ private enum Keywords private string _certificate = DbConnectionStringDefaults.Certificate; #endif #else - internal const int DeprecatedKeywordsCount = 3; + internal const int DeprecatedKeywordsCount = 5; #endif #endregion //Fields @@ -363,7 +363,6 @@ private object GetAt(Keywords index) return MinPoolSize; case Keywords.MultiSubnetFailover: return MultiSubnetFailover; - // case Keywords.NamedConnection: return NamedConnection; case Keywords.PacketSize: return PacketSize; case Keywords.Password: @@ -912,17 +911,19 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex } } #else - private static readonly string[] s_notSupportedKeywords = new string[DeprecatedKeywordsCount] { + private static readonly string[] s_notSupportedKeywords = { DbConnectionStringKeywords.ConnectionReset, DbConnectionStringKeywords.ContextConnection, DbConnectionStringKeywords.TransactionBinding, + DbConnectionStringKeywords.TransparentNetworkIPResolution, + DbConnectionStringSynonyms.TRANSPARENTNETWORKIPRESOLUTION, }; - private static readonly string[] s_notSupportedNetworkLibraryKeywords = new string[] { + private static readonly string[] s_notSupportedNetworkLibraryKeywords = { DbConnectionStringKeywords.NetworkLibrary, DbConnectionStringSynonyms.NET, - DbConnectionStringSynonyms.NETWORK + DbConnectionStringSynonyms.NETWORK, }; #endif #endregion //Private Methods diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index d1c3fd2d34..05b3ca5b48 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -107,19 +107,34 @@ public void ConnectionStringTests(string connectionString) ExecuteConnectionStringTests(connectionString); } + public static readonly IEnumerable ConnectionStringTestsNetFx_TestCases = new[] + { + new object[] { "Connection Reset = false" }, + new object[] { "Context Connection = false" }, + new object[] { "Network Library = dbmssocn" }, + new object[] { "Network = dbnmpntw" }, + new object[] { "Net = dbmsrpcn" }, + new object[] { "TransparentNetworkIPResolution = false" }, + new object[] { "Transparent Network IP Resolution = true" }, + }; + [Theory] - [InlineData("Connection Reset = false")] - [InlineData("Context Connection = false")] - [InlineData("Network Library = dbmssocn")] - [InlineData("Network = dbnmpntw")] - [InlineData("Net = dbmsrpcn")] - [InlineData("TransparentNetworkIPResolution = false")] - [InlineData("Transparent Network IP Resolution = true")] - [SkipOnTargetFramework(~TargetFrameworkMonikers.NetFramework)] - public void ConnectionStringTestsNetFx(string connectionString) + [MemberData(nameof(ConnectionStringTestsNetFx_TestCases))] + #if NETFRAMEWORK + public void ConnectionStringTestsNetFx_OnNetFx_Success(string connectionString) { ExecuteConnectionStringTests(connectionString); } + #else + public void ConnectionStringTestsNetFx_OnNetCore_Throws(string connectionString) + { + // Act + Action action = () => _ = new SqlConnectionStringBuilder(connectionString); + + // Assert + Assert.Throws(action); + } + #endif [Fact] public void SetInvalidApplicationIntent_Throws() From 7af2438ee177738131c6b13dc37743a2dafe6910 Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Thu, 30 May 2024 12:11:53 -0700 Subject: [PATCH 53/53] Fix | Enhance certificate validation (#2487) --- .../Microsoft/Data/SqlClient/SNI/SNICommon.cs | 256 +++++++---------- .../Data/SqlClient/SNI/SNINpHandle.cs | 16 +- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 10 +- .../Data/SqlClient/SNI/SNITcpHandle.cs | 28 +- .../src/Resources/Strings.Designer.cs | 9 + .../src/Resources/Strings.resx | 3 + .../SqlConnectionBasicTests.cs | 1 + .../tests/FunctionalTests/TestTdsServer.cs | 1 - .../DataCommon/ConnectionTestParameters.cs | 40 +++ .../ConnectionTestParametersData.cs | 85 ++++++ ....Data.SqlClient.ManualTesting.Tests.csproj | 12 + .../CertificateTest.cs | 2 +- .../CertificateTestWithTdsServer.cs | 269 ++++++++++++++++++ .../ManualTests/TracingTests/TestTdsServer.cs | 52 +++- .../tests/ManualTests/makepfxcert.ps1 | 158 ++++++++++ .../tests/ManualTests/mismatchedcert.cer | Bin 0 -> 919 bytes .../tests/ManualTests/removecert.ps1 | 21 ++ .../tests/tools/TDS/TDS/TDSStream.cs | 4 + 18 files changed, 771 insertions(+), 196 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index 2e5d3fd815..f8f2facb59 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -138,196 +138,154 @@ internal class SNICommon internal const int LocalDBBadRuntime = 57; /// - /// We only validate Server name in Certificate to match with "targetServerName". + /// We either validate that the provided 'validationCert' matches the 'serverCert', or we validate that the server name in the 'serverCert' matches 'targetServerName'. /// Certificate validation and chain trust validations are done by SSLStream class [System.Net.Security.SecureChannel.VerifyRemoteCertificate method] /// This method is called as a result of callback for SSL Stream Certificate validation. /// + /// Connection ID/GUID for tracing /// Server that client is expecting to connect to - /// X.509 certificate + /// Optional hostname to use for server certificate validation + /// X.509 certificate from the server + /// Path to an X.509 certificate file from the application to compare with the serverCert /// Policy errors /// True if certificate is valid - internal static bool ValidateSslServerCertificate(string targetServerName, X509Certificate cert, SslPolicyErrors policyErrors) + internal static bool ValidateSslServerCertificate(Guid connectionId, string targetServerName, string hostNameInCertificate, X509Certificate serverCert, string validationCertFileName, SslPolicyErrors policyErrors) { using (TrySNIEventScope.Create("SNICommon.ValidateSslServerCertificate | SNI | SCOPE | INFO | Entering Scope {0} ")) { if (policyErrors == SslPolicyErrors.None) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "targetServerName {0}, SSL Server certificate not validated as PolicyErrors set to None.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, targetServerName {1}, SSL Server certificate not validated as PolicyErrors set to None.", args0: connectionId, args1: targetServerName); return true; } - // If we get to this point then there is a ssl policy flag. - StringBuilder messageBuilder = new(); - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) + string serverNameToValidate; + X509Certificate validationCertificate = null; + if (!string.IsNullOrEmpty(hostNameInCertificate)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors.", args0: targetServerName, args1: policyErrors); + serverNameToValidate = hostNameInCertificate; + } + else + { + serverNameToValidate = targetServerName; + } - // get the chain status from the certificate - X509Certificate2 cert2 = cert as X509Certificate2; - X509Chain chain = new(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; - StringBuilder chainStatusInformation = new(); - bool chainIsValid = chain.Build(cert2); - Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); - if (!chainIsValid) + if (!string.IsNullOrEmpty(validationCertFileName)) + { + try { - foreach (X509ChainStatus chainStatus in chain.ChainStatus) - { - chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); - chainStatusInformation.AppendLine(); - } + validationCertificate = new X509Certificate(validationCertFileName); + } + catch (Exception e) + { + // if this fails, then fall back to the HostNameInCertificate or TargetServer validation. + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, Exception occurred loading specified ServerCertificate: {1}, treating it as if ServerCertificate has not been specified.", args0: connectionId, args1: e.Message); } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors. ChainStatus {2}", args0: targetServerName, args1: policyErrors, args2: chainStatusInformation); - messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); - messageBuilder.AppendLine(); } - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) + if (validationCertificate != null) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SSL Policy invalidated certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); + if (serverCert.GetRawCertData().AsSpan().SequenceEqual(validationCertificate.GetRawCertData().AsSpan())) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, ServerCertificate matches the certificate provided by the server. Certificate validation passed.", args0: connectionId); + return true; + } + else + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, ServerCertificate doesn't match the certificate provided by the server. Certificate validation failed.", args0: connectionId); + throw ADP.SSLCertificateAuthenticationException(Strings.SQL_RemoteCertificateDoesNotMatchServerCertificate); + } } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) + else { -#if NET8_0_OR_GREATER - X509Certificate2 cert2 = cert as X509Certificate2; - if (!cert2.MatchesHostname(targetServerName)) + // If we get to this point then there is a ssl policy flag. + StringBuilder messageBuilder = new(); + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name or HNIC does not match the Subject/SAN in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {1}, SSL Server certificate not validated as PolicyErrors set to RemoteCertificateNotAvailable.", args0: connectionId, args1: targetServerName); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); } -#else - // To Do: include certificate SAN (Subject Alternative Name) check. - string certServerName = cert.Subject.Substring(cert.Subject.IndexOf('=') + 1); - // Verify that target server name matches subject in the certificate - if (targetServerName.Length > certServerName.Length) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name is of greater length than Subject in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); - } - else if (targetServerName.Length == certServerName.Length) + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) { - // Both strings have the same length, so targetServerName must be a FQDN - if (!targetServerName.Equals(certServerName, StringComparison.OrdinalIgnoreCase)) + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors.", args0: connectionId, args1: targetServerName, args2: policyErrors); + + // get the chain status from the certificate + X509Certificate2 cert2 = serverCert as X509Certificate2; + X509Chain chain = new(); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; + StringBuilder chainStatusInformation = new(); + bool chainIsValid = chain.Build(cert2); + Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); + if (!chainIsValid) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + { + chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); + chainStatusInformation.AppendLine(); + } } + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {1}, SslPolicyError {2}, SSL Policy certificate chain has errors. ChainStatus {3}", args0: connectionId, args1: targetServerName, args2: policyErrors, args3: chainStatusInformation); + messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); + messageBuilder.AppendLine(); } - else + + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { - if (string.Compare(targetServerName, 0, certServerName, 0, targetServerName.Length, StringComparison.OrdinalIgnoreCase) != 0) +#if NET8_0_OR_GREATER + X509Certificate2 cert2 = serverCert as X509Certificate2; + if (!cert2.MatchesHostname(serverNameToValidate)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name or HNIC does not match the Subject/SAN in Certificate.", args0: connectionId, args1: serverNameToValidate); messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); } +#else + // To Do: include certificate SAN (Subject Alternative Name) check. + string certServerName = serverCert.Subject.Substring(serverCert.Subject.IndexOf('=') + 1); - // Server name matches cert name for its whole length, so ensure that the - // character following the server name is a '.'. This will avoid - // having server name "ab" match "abc.corp.company.com" - // (Names have different lengths, so the target server can't be a FQDN.) - if (certServerName[targetServerName.Length] != '.') + // Verify that target server name matches subject in the certificate + if (serverNameToValidate.Length > certServerName.Length) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name is of greater length than Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); } - } -#endif - } - - if (messageBuilder.Length > 0) - { - throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); - } - - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, " Remote certificate with subject: {0}, validated successfully.", args0: cert.Subject); - return true; - } - } - - /// - /// We validate the provided certificate provided by the client with the one from the server to see if it matches. - /// Certificate validation and chain trust validations are done by SSLStream class [System.Net.Security.SecureChannel.VerifyRemoteCertificate method] - /// This method is called as a result of callback for SSL Stream Certificate validation. - /// - /// X.509 certificate provided by the client - /// X.509 certificate provided by the server - /// Policy errors - /// True if certificate is valid - internal static bool ValidateSslServerCertificate(X509Certificate clientCert, X509Certificate serverCert, SslPolicyErrors policyErrors) - { - using (TrySNIEventScope.Create("SNICommon.ValidateSslServerCertificate | SNI | SCOPE | INFO | Entering Scope {0} ")) - { - if (policyErrors == SslPolicyErrors.None) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "serverCert {0}, SSL Server certificate not validated as PolicyErrors set to None.", args0: clientCert.Subject); - return true; - } - - StringBuilder messageBuilder = new(); - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "serverCert {0}, SSL Server certificate not validated as PolicyErrors set to RemoteCertificateNotAvailable.", args0: clientCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); - } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) - { - // get the chain status from the server certificate - X509Certificate2 cert2 = serverCert as X509Certificate2; - X509Chain chain = new(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; - StringBuilder chainStatusInformation = new(); - bool chainIsValid = chain.Build(cert2); - Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); - if (!chainIsValid) - { - foreach (X509ChainStatus chainStatus in chain.ChainStatus) + else if (serverNameToValidate.Length == certServerName.Length) { - chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); - chainStatusInformation.AppendLine(); + // Both strings have the same length, so serverNameToValidate must be a FQDN + if (!serverNameToValidate.Equals(certServerName, StringComparison.OrdinalIgnoreCase)) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } } - } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate subject from server is {0}, and does not match with the certificate provided client.", args0: cert2.SubjectName.Name); - messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); - messageBuilder.AppendLine(); - } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) - { -#if NET8_0_OR_GREATER - X509Certificate2 s_cert = serverCert as X509Certificate2; - X509Certificate2 c_cert = clientCert as X509Certificate2; - - if (!s_cert.MatchesHostname(c_cert.SubjectName.Name)) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate from server does not match with the certificate provided client.", args0: s_cert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); - } -#else - // Verify that subject name matches - if (serverCert.Subject != clientCert.Subject) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate subject from server is {0}, and does not match with the certificate provided client.", args0: serverCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + else + { + if (string.Compare(serverNameToValidate, 0, certServerName, 0, serverNameToValidate.Length, StringComparison.OrdinalIgnoreCase) != 0) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } + + // Server name matches cert name for its whole length, so ensure that the + // character following the server name is a '.'. This will avoid + // having server name "ab" match "abc.corp.company.com" + // (Names have different lengths, so the target server can't be a FQDN.) + if (certServerName[serverNameToValidate.Length] != '.') + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } + } +#endif } - if (!serverCert.Equals(clientCert)) + if (messageBuilder.Length > 0) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate from server does not match with the certificate provided client.", args0: serverCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); } -#endif } - if (messageBuilder.Length > 0) - { - throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); - } - - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "certificate subject {0}, Client certificate validated successfully.", args0: clientCert.Subject); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, certificate with subject: {1}, validated successfully.", args0: connectionId, args1: serverCert.Subject); return true; } } @@ -342,11 +300,11 @@ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer ti args0: serverName, args1: remainingTimeout); using CancellationTokenSource cts = new CancellationTokenSource(remainingTimeout); - - return Dns.GetHostAddressesAsync(serverName, cts.Token) - .ConfigureAwait(false) - .GetAwaiter() - .GetResult(); + // using this overload to support netstandard + Task task = Dns.GetHostAddressesAsync(serverName); + task.ConfigureAwait(false); + task.Wait(cts.Token); + return task.Result; } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs index 2889ce6bb4..8f8af57f58 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs @@ -24,6 +24,8 @@ internal sealed class SNINpHandle : SNIPhysicalHandle private readonly string _targetServer; private readonly object _sendSync; + private readonly string _hostNameInCertificate; + private readonly string _serverCertificateFilename; private readonly bool _tlsFirst; private Stream _stream; private NamedPipeClientStream _pipeStream; @@ -38,7 +40,7 @@ internal sealed class SNINpHandle : SNIPhysicalHandle private int _bufferSize = TdsEnums.DEFAULT_LOGIN_PACKET_SIZE; private readonly Guid _connectionId = Guid.NewGuid(); - public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, bool tlsFirst) + public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, bool tlsFirst, string hostNameInCertificate, string serverCertificateFilename) { using (TrySNIEventScope.Create(nameof(SNINpHandle))) { @@ -47,6 +49,8 @@ public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, boo _sendSync = new object(); _targetServer = serverName; _tlsFirst = tlsFirst; + _hostNameInCertificate = hostNameInCertificate; + _serverCertificateFilename = serverCertificateFilename; try { _pipeStream = new NamedPipeClientStream( @@ -369,14 +373,14 @@ public override void DisableSsl() /// Validate server certificate /// /// Sender object - /// X.509 certificate + /// X.509 certificate /// X.509 chain /// Policy errors /// true if valid - private bool ValidateServerCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors) + private bool ValidateServerCertificate(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors policyErrors) { using (TrySNIEventScope.Create(nameof(SNINpHandle))) - { + { if (!_validateCert) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, Certificate validation not requested.", args0: ConnectionId); @@ -384,8 +388,8 @@ private bool ValidateServerCertificate(object sender, X509Certificate cert, X509 } SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, Proceeding to SSL certificate validation.", args0: ConnectionId); - return SNICommon.ValidateSslServerCertificate(_targetServer, cert, policyErrors); - } + return SNICommon.ValidateSslServerCertificate(_connectionId, _targetServer, _hostNameInCertificate, serverCertificate, _serverCertificateFilename, policyErrors); + } } /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 77b44a1cf5..0ee31e5f46 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -206,7 +206,7 @@ internal static SNIHandle CreateConnectionHandle( tlsFirst, hostNameInCertificate, serverCertificateFilename); break; case DataSource.Protocol.NP: - sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); + sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst, hostNameInCertificate, serverCertificateFilename); break; default: Debug.Fail($"Unexpected connection protocol: {details._connectionProtocol}"); @@ -362,8 +362,10 @@ private static SNITCPHandle CreateTcpHandle( /// Timer expiration /// Should MultiSubnetFailover be used. Only returns an error for named pipes. /// + /// Host name in certificate + /// Used for the path to the Server Certificate /// SNINpHandle - private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeout, bool parallel, bool tlsFirst) + private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeout, bool parallel, bool tlsFirst, string hostNameInCertificate, string serverCertificateFilename) { if (parallel) { @@ -371,7 +373,7 @@ private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeo SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, Strings.SNI_ERROR_49); return null; } - return new SNINpHandle(details.PipeHostName, details.PipeName, timeout, tlsFirst); + return new SNINpHandle(details.PipeHostName, details.PipeName, timeout, tlsFirst, hostNameInCertificate, serverCertificateFilename); } /// @@ -539,8 +541,10 @@ private void PopulateProtocol() internal static string GetLocalDBInstance(string dataSource, out bool error) { string instanceName = null; + // ReadOnlySpan is not supported in netstandard 2.0, but installing System.Memory solves the issue ReadOnlySpan input = dataSource.AsSpan().TrimStart(); error = false; + // NetStandard 2.0 does not support passing a string to ReadOnlySpan int index = input.IndexOf(LocalDbHost.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase); if (input.StartsWith(LocalDbHost_NP.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase)) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs index 9d415bcfc8..2791de17a4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs @@ -644,7 +644,6 @@ public override uint EnableSsl(uint options) } else { - // TODO: Resolve whether to send _serverNameIndication or _targetServer. _serverNameIndication currently results in error. Why? _sslStream.AuthenticateAsClient(_targetServer, null, s_supportedProtocols, false); } if (_sslOverTdsStream is not null) @@ -698,33 +697,8 @@ private bool ValidateServerCertificate(object sender, X509Certificate serverCert return true; } - string serverNameToValidate; - if (!string.IsNullOrEmpty(_hostNameInCertificate)) - { - serverNameToValidate = _hostNameInCertificate; - } - else - { - serverNameToValidate = _targetServer; - } - - if (!string.IsNullOrEmpty(_serverCertificateFilename)) - { - X509Certificate clientCertificate = null; - try - { - clientCertificate = new X509Certificate(_serverCertificateFilename); - return SNICommon.ValidateSslServerCertificate(clientCertificate, serverCertificate, policyErrors); - } - catch (Exception e) - { - // if this fails, then fall back to the HostNameInCertificate or TargetServer validation. - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, IOException occurred: {1}", args0: _connectionId, args1: e.Message); - } - } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, Certificate will be validated for Target Server name", args0: _connectionId); - return SNICommon.ValidateSslServerCertificate(serverNameToValidate, serverCertificate, policyErrors); + return SNICommon.ValidateSslServerCertificate(_connectionId, _targetServer, _hostNameInCertificate, serverCertificate, _serverCertificateFilename, policyErrors); } /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs index 533ffa86ad..a685787e9e 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs @@ -10215,6 +10215,15 @@ internal static string SQL_RemoteCertificateChainErrors { } } + /// + /// Looks up a localized string similar to The certificate provided by the server does not match the certificate provided by the ServerCertificate option.. + /// + internal static string SQL_RemoteCertificateDoesNotMatchServerCertificate { + get { + return ResourceManager.GetString("SQL_RemoteCertificateDoesNotMatchServerCertificate", resourceCulture); + } + } + /// /// Looks up a localized string similar to Certificate name mismatch. The provided 'DataSource' or 'HostNameInCertificate' does not match the name in the certificate.. /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx index 3fb2e0a74a..c2dd68b867 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx @@ -4737,4 +4737,7 @@ Certificate not available while validating the certificate. + + The certificate provided by the server does not match the certificate provided by the ServerCertificate option. + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 8f16c09aa3..a164149a60 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -12,6 +12,7 @@ using System.Security; using System.Threading; using System.Threading.Tasks; +using Microsoft.SqlServer.TDS.PreLogin; using Microsoft.SqlServer.TDS.Servers; using Xunit; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs index 1ead74f58d..ef45bdbc7a 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs @@ -65,6 +65,5 @@ public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool ena public void Dispose() => _endpoint?.Stop(); public string ConnectionString { get; private set; } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs new file mode 100644 index 0000000000..4b6e7b087b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.SqlServer.TDS.PreLogin; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon +{ + public class ConnectionTestParameters + { + private SqlConnectionEncryptOption _encryptionOption; + private TDSPreLoginTokenEncryptionType _encryptionType; + private string _hnic; + private string _cert; + private bool _result; + private bool _trustServerCert; + + public SqlConnectionEncryptOption Encrypt => _encryptionOption; + public bool TrustServerCertificate => _trustServerCert; + public string Certificate => _cert; + public string HostNameInCertificate => _hnic; + public bool TestResult => _result; + public TDSPreLoginTokenEncryptionType TdsEncryptionType => _encryptionType; + + public ConnectionTestParameters(TDSPreLoginTokenEncryptionType tdsEncryptionType, SqlConnectionEncryptOption encryptOption, bool trustServerCert, string cert, string hnic, bool result) + { + _encryptionOption = encryptOption; + _trustServerCert = trustServerCert; + _cert = cert; + _hnic = hnic; + _result = result; + _encryptionType = tdsEncryptionType; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs new file mode 100644 index 0000000000..5a2e01a77c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using Microsoft.SqlServer.TDS.PreLogin; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon +{ + public class ConnectionTestParametersData + { + private const int CASES = 30; + private string _empty = string.Empty; + // It was advised to store the client certificate in its own folder. + private static readonly string s_fullPathToCer = Path.Combine(Directory.GetCurrentDirectory(), "clientcert", "localhostcert.cer"); + private static readonly string s_mismatchedcert = Path.Combine(Directory.GetCurrentDirectory(), "clientcert", "mismatchedcert.cer"); + + private static readonly string s_hostName = System.Net.Dns.GetHostName(); + public static ConnectionTestParametersData Data { get; } = new ConnectionTestParametersData(); + public List ConnectionTestParametersList { get; set; } + + public static IEnumerable GetConnectionTestParameters() + { + for (int i = 0; i < CASES; i++) + { + yield return new object[] { Data.ConnectionTestParametersList[i] }; + } + } + + public ConnectionTestParametersData() + { + // Test cases possible field values for connection parameters: + // These combinations are based on the possible values of Encrypt, TrustServerCertificate, Certificate, HostNameInCertificate + /* + * TDSEncryption | Encrypt | TrustServerCertificate | Certificate | HNIC | TestResults + * ---------------------------------------------------------------------------------------------- + * Off | Optional | true | valid | valid name | true + * On | Mandatory | false | mismatched | empty | false + * Required | | x | ChainError? | wrong name? | + */ + ConnectionTestParametersList = new List + { + // TDSPreLoginTokenEncryptionType.Off + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Optional, false, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // TDSPreLoginTokenEncryptionType.On + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Optional, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // TDSPreLoginTokenEncryptionType.Required + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Optional, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // Mismatched certificate test + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + }; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index f75aef8edb..8962d5ab15 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -270,6 +270,8 @@ + + @@ -287,6 +289,7 @@ + @@ -354,6 +357,15 @@ + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + Always diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs index fc358acb05..d8a402236e 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs @@ -32,7 +32,7 @@ public class CertificateTest : IDisposable // InstanceName will get replaced with an instance name in the connection string private static string InstanceName = "MSSQLSERVER"; - // InstanceNamePrefix will get replaced with MSSQL$ is there is an instance name in connection string + // s_instanceNamePrefix will get replaced with MSSQL$ is there is an instance name in connection string private static string InstanceNamePrefix = ""; // SlashInstance is used to override IPV4 and IPV6 defined about so it includes an instance name diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs new file mode 100644 index 0000000000..9cfc1c71bb --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs @@ -0,0 +1,269 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Data; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.ServiceProcess; +using System.Text; +using Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon; +using Microsoft.Win32; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class CertificateTestWithTdsServer : IDisposable + { + private static readonly string s_fullPathToPowershellScript = Path.Combine(Directory.GetCurrentDirectory(), "makepfxcert.ps1"); + private static readonly string s_fullPathToCleanupPowershellScript = Path.Combine(Directory.GetCurrentDirectory(), "removecert.ps1"); + private static readonly string s_fullPathToPfx = Path.Combine(Directory.GetCurrentDirectory(), "localhostcert.pfx"); + private static readonly string s_fullPathTothumbprint = Path.Combine(Directory.GetCurrentDirectory(), "thumbprint.txt"); + private static readonly string s_fullPathToClientCert = Path.Combine(Directory.GetCurrentDirectory(), "clientcert"); + private static bool s_windowsAdmin = true; + private static string s_instanceName = "MSSQLSERVER"; + // s_instanceNamePrefix will get replaced with MSSQL$ is there is an instance name in the connection string + private static string s_instanceNamePrefix = ""; + private const string LocalHost = "localhost"; + + public CertificateTestWithTdsServer() + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + Assert.True(DataTestUtility.ParseDataSource(builder.DataSource, out string hostname, out _, out string instanceName)); + + if (!string.IsNullOrEmpty(instanceName)) + { + s_instanceName = instanceName; + s_instanceNamePrefix = "MSSQL$"; + } + + // Confirm that user has elevated access on Windows + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + using WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new(identity); + if (principal.IsInRole(WindowsBuiltInRole.Administrator)) + s_windowsAdmin = true; + else + s_windowsAdmin = false; + } + + if (!Directory.Exists(s_fullPathToClientCert)) + { + Directory.CreateDirectory(s_fullPathToClientCert); + } + + RunPowershellScript(s_fullPathToPowershellScript); + } + + private static bool IsLocalHost() + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + Assert.True(DataTestUtility.ParseDataSource(builder.DataSource, out string hostname, out _, out _)); + return LocalHost.Equals(hostname, StringComparison.OrdinalIgnoreCase); + } + + private static bool AreConnStringsSetup() => DataTestUtility.AreConnStringsSetup(); + private static bool IsNotAzureServer() => DataTestUtility.IsNotAzureServer(); + private static bool UseManagedSNIOnWindows() => DataTestUtility.UseManagedSNIOnWindows; + + private static string ForceEncryptionRegistryPath + { + get + { + if (DataTestUtility.IsSQL2022()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + if (DataTestUtility.IsSQL2019()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + if (DataTestUtility.IsSQL2016()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + return string.Empty; + } + } + + [ConditionalTheory(nameof(AreConnStringsSetup), nameof(IsNotAzureServer), nameof(IsLocalHost))] + [MemberData(nameof(ConnectionTestParametersData.GetConnectionTestParameters), MemberType = typeof(ConnectionTestParametersData))] + [PlatformSpecific(TestPlatforms.Windows)] + public void BeginWindowsConnectionTest(ConnectionTestParameters connectionTestParameters) + { + if (!s_windowsAdmin) + { + Assert.Fail("User needs to have elevated access for these set of tests"); + } + + ConnectionTest(connectionTestParameters); + } + + [ConditionalTheory(nameof(AreConnStringsSetup), nameof(IsNotAzureServer), nameof(IsLocalHost))] + [MemberData(nameof(ConnectionTestParametersData.GetConnectionTestParameters), MemberType = typeof(ConnectionTestParametersData))] + [PlatformSpecific(TestPlatforms.Linux)] + public void BeginLinuxConnectionTest(ConnectionTestParameters connectionTestParameters) + { + ConnectionTest(connectionTestParameters); + } + + private void ConnectionTest(ConnectionTestParameters connectionTestParameters) + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + + // The TestTdsServer does not validate the user name and password, so we can use any value if they are not defined. + string userId = string.IsNullOrWhiteSpace(builder.UserID) ? "user" : builder.UserID; + string password = string.IsNullOrWhiteSpace(builder.Password) ? "password" : builder.Password; + + using TestTdsServer server = TestTdsServer.StartTestServer(enableFedAuth: false, enableLog: false, connectionTimeout: 15, + methodName: "", new X509Certificate2(s_fullPathToPfx, "nopassword", X509KeyStorageFlags.UserKeySet), + encryptionType: connectionTestParameters.TdsEncryptionType); + + builder = new(server.ConnectionString) + { + UserID = userId, + Password = password, + TrustServerCertificate = connectionTestParameters.TrustServerCertificate, + Encrypt = connectionTestParameters.Encrypt, + }; + + if (!string.IsNullOrEmpty(connectionTestParameters.Certificate)) + { + builder.ServerCertificate = connectionTestParameters.Certificate; + } + + if (!string.IsNullOrEmpty(connectionTestParameters.HostNameInCertificate)) + { + builder.HostNameInCertificate = connectionTestParameters.HostNameInCertificate; + } + + using SqlConnection connection = new(builder.ConnectionString); + try + { + connection.Open(); + Assert.Equal(connectionTestParameters.TestResult, (connection.State == ConnectionState.Open)); + } + catch (Exception) + { + Assert.False(connectionTestParameters.TestResult); + } + } + + private static void RunPowershellScript(string script) + { + string currentDirectory = Directory.GetCurrentDirectory(); + string powerShellCommand = "powershell.exe"; + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + powerShellCommand = "pwsh"; + } + + if (File.Exists(script)) + { + StringBuilder output = new(); + Process proc = new() + { + StartInfo = + { + FileName = powerShellCommand, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false, + Arguments = $"{script} -OutDir {currentDirectory} > result.txt", + CreateNoWindow = false, + Verb = "runas" + } + }; + + proc.EnableRaisingEvents = true; + + proc.OutputDataReceived += new DataReceivedEventHandler((sender, e) => + { + if (e.Data != null) + { + output.AppendLine(e.Data); + } + }); + + proc.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => + { + if (e.Data != null) + { + output.AppendLine(e.Data); + } + }); + + proc.Start(); + + proc.BeginOutputReadLine(); + proc.BeginErrorReadLine(); + + if (!proc.WaitForExit(60000)) + { + proc.Kill(); + proc.WaitForExit(2000); + throw new Exception($"Could not generate certificate. Error output: {output}"); + } + } + else + { + throw new Exception($"Could not find makepfxcert.ps1"); + } + } + + private void RemoveCertificate() + { + string thumbprint = File.ReadAllText(s_fullPathTothumbprint); + using X509Store certStore = new(StoreName.Root, StoreLocation.LocalMachine); + certStore.Open(OpenFlags.ReadWrite); + X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); + if (certCollection.Count > 0) + { + certStore.Remove(certCollection[0]); + } + certStore.Close(); + + File.Delete(s_fullPathTothumbprint); + Directory.Delete(s_fullPathToClientCert, true); + } + + private static void RemoveForceEncryptionFromRegistryPath(string registryPath) + { + RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath, true); + key?.SetValue("ForceEncryption", 0, RegistryValueKind.DWord); + key?.SetValue("Certificate", "", RegistryValueKind.String); + ServiceController sc = new($"{s_instanceNamePrefix}{s_instanceName}"); + sc.Stop(); + sc.WaitForStatus(ServiceControllerStatus.Stopped); + sc.Start(); + sc.WaitForStatus(ServiceControllerStatus.Running); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (disposing && !string.IsNullOrEmpty(s_fullPathTothumbprint)) + { + RemoveCertificate(); + RemoveForceEncryptionFromRegistryPath(ForceEncryptionRegistryPath); + } + } + else + { + RunPowershellScript(s_fullPathToCleanupPowershellScript); + } + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs index 3552204886..a4557d72b6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs @@ -3,27 +3,35 @@ // See the LICENSE file in the project root for more information. using System; +using System.Linq; using System.Net; +using System.Net.Sockets; using System.Runtime.CompilerServices; +using System.Security.Cryptography.X509Certificates; using Microsoft.SqlServer.TDS.EndPoint; +using Microsoft.SqlServer.TDS.PreLogin; using Microsoft.SqlServer.TDS.Servers; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { internal class TestTdsServer : GenericTDSServer, IDisposable { + private const int DefaultConnectionTimeout = 5; + private TDSServerEndPoint _endpoint = null; - private SqlConnectionStringBuilder connectionStringBuilder; + private SqlConnectionStringBuilder _connectionStringBuilder; public TestTdsServer(TDSServerArguments args) : base(args) { } public TestTdsServer(QueryEngine engine, TDSServerArguments args) : base(args) { - this.Engine = engine; + Engine = engine; } - public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool enableFedAuth = false, bool enableLog = false, [CallerMemberName] string methodName = "") + public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool enableFedAuth = false, bool enableLog = false, + int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "", + X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported) { TDSServerArguments args = new TDSServerArguments() { @@ -32,10 +40,18 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool if (enableFedAuth) { - args.FedAuthRequiredPreLoginOption = Microsoft.SqlServer.TDS.PreLogin.TdsPreLoginFedAuthRequiredOption.FedAuthRequired; + args.FedAuthRequiredPreLoginOption = SqlServer.TDS.PreLogin.TdsPreLoginFedAuthRequiredOption.FedAuthRequired; + } + + if (encryptionCertificate != null) + { + args.EncryptionCertificate = encryptionCertificate; } + args.Encryption = encryptionType; + TestTdsServer server = engine == null ? new TestTdsServer(args) : new TestTdsServer(engine, args); + server._endpoint = new TDSServerEndPoint(server) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. @@ -43,19 +59,37 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool server._endpoint.Start(); int port = server._endpoint.ServerEndPoint.Port; - server.connectionStringBuilder = new SqlConnectionStringBuilder() { DataSource = "localhost," + port, ConnectTimeout = 5, Encrypt = SqlConnectionEncryptOption.Optional }; - server.ConnectionString = server.connectionStringBuilder.ConnectionString; + + server._connectionStringBuilder = new SqlConnectionStringBuilder() + { + DataSource = "localhost," + port, + ConnectTimeout = connectionTimeout, + }; + + if (encryptionType == TDSPreLoginTokenEncryptionType.Off || + encryptionType == TDSPreLoginTokenEncryptionType.None || + encryptionType == TDSPreLoginTokenEncryptionType.NotSupported) + { + server._connectionStringBuilder.Encrypt = SqlConnectionEncryptOption.Optional; + } + else + { + server._connectionStringBuilder.Encrypt = SqlConnectionEncryptOption.Mandatory; + } + + server.ConnectionString = server._connectionStringBuilder.ConnectionString; return server; } - public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool enableLog = false, [CallerMemberName] string methodName = "") + public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool enableLog = false, + int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "", + X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported) { - return StartServerWithQueryEngine(null, false, false, methodName); + return StartServerWithQueryEngine(null, enableFedAuth, enableLog, connectionTimeout, methodName, encryptionCertificate, encryptionType); } public void Dispose() => _endpoint?.Stop(); public string ConnectionString { get; private set; } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 b/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 new file mode 100644 index 0000000000..02d558d77b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 @@ -0,0 +1,158 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# Script: Invoke-SqlServerCertificateCommand# +# Author: SqlClient Team +# Date: March 20, 2024 +# Comments: This scripts creates SSL Self-Signed Certificate for TestTdsServer in pfx format. +# This script is not intended to be used in any production environments. + +param ($OutDir) + +function Invoke-SqlServerCertificateCommand { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string] $certificateName = "localhostcert.cer", + [string] $myCertStoreLocation = "Cert:\LocalMachine\My", + [string] $rootCertStoreLocation = "Cert:\LocalMachine\Root", + [string] $sqlAliasName = "SQLAliasName", + [string] $localhost = "localhost", + [string] $LoopBackIPV4 = "127.0.0.1", + [string] $LoopBackIPV6 = "::1" + ) + Write-Output "Certificate generation started..." + + # Change directory to where the tests are + Write-Output "Change directory to $OutDir ..." + cd $OutDir + pwd + + try { + # Get FQDN of the machine + Write-Output "Get FQDN of the machine..." + $fqdn = [System.Net.Dns]::GetHostByName(($env:computerName)).HostName + Write-Output "FQDN = $fqdn" + + $OS = [System.Environment]::OSVersion.Platform + Write-Output "Operating System is $OS" + + # Create a self-signed certificate + if ($OS -eq "Unix") { + chmod 777 $OutDir + # Install OpenSSL module + Install-Module -Name OpenSSL -Repository PSGallery -Force + # Show version of OpenSSL just to make sure it is installed + openssl version + + # Create self signed certificate using openssl + Write-Output "Creating certificate for linux..." + if ($fqdn.length -gt 64) { + $machineId = $fqdn.Substring(0,15) + openssl req -x509 -newkey rsa:4096 -sha256 -days 1095 -nodes -keyout $OutDir/localhostcert.key -out $OutDir/localhostcert.cer -subj "/CN=$machineId" -addext "subjectAltName=DNS:$fqdn,DNS:localhost,IP:127.0.0.1,IP:::1" + } + else { + openssl req -x509 -newkey rsa:4096 -sha256 -days 1095 -nodes -keyout $OutDir/localhostcert.key -out $OutDir/localhostcert.cer -subj "/CN=$fqdn" -addext "subjectAltName=DNS:$fqdn,DNS:localhost,IP:127.0.0.1,IP:::1" + } + chmod 777 $OutDir/localhostcert.key $OutDir/localhostcert.cer + # Copy the certificate to the clientcert folder + cp $OutDir/localhostcert.cer $OutDir/clientcert/ + # Export the certificate to pfx + Write-Output "Exporting certificate to pfx..." + openssl pkcs12 -export -in $OutDir/localhostcert.cer -inkey $OutDir/localhostcert.key -out $OutDir/localhostcert.pfx -password pass:nopassword + chmod 777 $OutDir/localhostcert.pfx + + Write-Output "Converting certificate to pem..." + # Create pem from cer + cp $OutDir/localhostcert.cer $OutDir/localhostcert.pem + chmod 777 $OutDir/localhostcert.pem + + # Add trust to the pem certificate + Write-Output "Adding trust to pem certificate..." + openssl x509 -trustout -addtrust "serverAuth" -in $OutDir/localhostcert.pem + + # Import the certificate to the Root store ------------------------------------------------------------------------------ + # NOTE: The process must have root privileges to add the certificate to the Root store. If not, then use + # "chmod 777 /usr/local/share/ca-certificates" to give read, write and execute privileges to anyone on that folder + # Copy the certificate to /usr/local/share/ca-certificates folder while changing the extension to "crt". + # Only certificates with extension "crt" gets added for some reason. + Write-Output "Copy the pem certificate to /usr/local/share/ca-certificates folder..." + cp $OutDir/localhostcert.pem /usr/local/share/ca-certificates/localhostcert.crt + + # Add trust to the mismatched certificate as well + $ openssl x509 -in $OutDir/mismatchedcert.cer -inform der -out $OutDir/mismatchedcert.pem + # Copy the mismatched certificate to the clientcert folder + cp $OutDir/mismatchedcert.cer $OutDir/clientcert/ + openssl x509 -trustout -addtrust "serverAuth" -in $OutDir/mismatchedcert.pem + cp $OutDir/mismatchedcert.pem /usr/local/share/ca-certificates/mismatchedcert.crt + + # enable certificate as CA certificate + dpkg-reconfigure ca-certificates -f noninteractive -p critical + + # Update the certificates store + Write-Output "Updating the certificates store..." + update-ca-certificates -v + } else { + Write-Output "Creating a self-signed certificate..." + $params = @{ + Type = "SSLServerAuthentication" + Subject = "CN=$fqdn" + KeyAlgorithm = "RSA" + KeyLength = 4096 + HashAlgorithm = "SHA256" + TextExtension = "2.5.29.37={text}1.3.6.1.5.5.7.3.1", "2.5.29.17={text}DNS=$fqdn&DNS=$localhost&IPAddress=$LoopBackIPV4&DNS=$sqlAliasName&IPAddress=$LoopBackIPV6" + NotAfter = (Get-Date).AddMonths(36) + KeySpec = "KeyExchange" + Provider = "Microsoft RSA SChannel Cryptographic Provider" + CertStoreLocation = $myCertStoreLocation + FriendlyName = "TestTDSServerCertificate" + } + + $certificate = New-SelfSignedCertificate @params + Write-Output "Certificate created successfully" + Write-Output "Certificate Thumbprint: $($certificate.Thumbprint)" + + # Export the certificate to a file + Write-Output "Exporting the certificate to a file..." + Export-Certificate -Cert $certificate -FilePath "$OutDir/$certificateName" -Type CERT + + # Copy the certificate to the clientcert folder + copy $OutDir/$certificateName $OutDir/clientcert/ + copy $OutDir/mismatchedcert.cer $OutDir/clientcert/ + + # Import the certificate to the Root store + Write-Output "Importing the certificate to the Root store..." + $params = @{ + FilePath = "$OutDir/$certificateName" + CertStoreLocation = $rootCertStoreLocation + } + Import-Certificate @params + + Write-Output "Converting certificate to pfx..." + Write-Output "Cert:\LocalMachine\my\$($certificate.Thumbprint)" + + $pwd = ConvertTo-SecureString -String 'nopassword' -Force -AsPlainText + # Export the certificate to a pfx format + Export-PfxCertificate -Password $pwd -FilePath "$OutDir\localhostcert.pfx" -Cert "Cert:\LocalMachine\my\$($certificate.Thumbprint)" + + # Write the certificate thumbprint to a file + echo $certificate.Thumbprint | Out-File -FilePath "$OutDir\thumbprint.txt" -Encoding ascii + } + + Write-Output "Done creating pfx certificate..." + } + catch { + $e = $_.Exception + $msg = $e.Message + while ($e.InnerException) { + $e = $e.InnerException + $msg += "`n" + $e.Message + } + + Write-Output "Certificate generation was not successfull. $msg" + } + + Write-Output "Certificate generation task completed." +} + +Invoke-SqlServerCertificateCommand diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer b/src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer new file mode 100644 index 0000000000000000000000000000000000000000..6b35e97a5534ea4c218c4df7c8874906248ae967 GIT binary patch literal 919 zcmXqLVxDZ!#8kb2nTe5!Ngy^P*GyUZ-a7B}EvW(eTUiWv**LY@JlekVGBR?rG8h;d z>Ko{?F^94+^Qak_8JJiZrx;jRS)`h$SfwT#SQ(m_8e18r7@1flCmUN>85@~f7|4n9 z8kqn!8X6cFTN)We0lB6St|^F1j*(4_O2`glWMyD(V&rEqXkz4IYGPz$SbOK-j9&TV zEgRNvuu-@i@;fWtudU~!iqntVJ}2GYS=8;|itsC3$D4V?#`L7UfI4%*`2waxd(+vv zwAKfR|GZieThy9zBSOKIcfrM1o{y6F51ib|vG?(Dm`V_WUN%W?Dgiha#mwg;~^ExIkpuww6)OtVU-e`1>ssRvbcEU%ki z6UxNQ$iTR`ahXBmVgo*4Y{~L7GX7^_VP;}oU?2JvoW%=vNJQmS&Rn3 zAZbAs9|Nx@ejmqx5dQ$(0ArtEcRw%7c9wbu2F7*)22{YfK%R{YXc7x!leq{J^8!I0 zbd3-@`B=nQL^y+2NAGaD968U_Qe$GxadoS&C635Z2~1O`5AbNofAd?B{41$IBVlICa^LjYly7sGdwi`9u_UiCKQD5n`kU%biB%6K zG7HaTx-9W^-7y(^MURXQ0RwqnQJ!|eUA)t#967$F!8L8O@b3I|J?9b_clWAgr!M-u zvew4PMd)Fq!`f(_%*i70JT=lsrmwd=D9=~Kc&=09-9cv0ywC0J+{> literal 0 HcmV?d00001 diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 b/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 new file mode 100644 index 0000000000..14b944de80 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 @@ -0,0 +1,21 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# Script: removecert.ps1 +# Author: SqlClient Team +# Date: May 24, 2024 +# Comments: This script deletes the SSL Self-Signed Certificate from Linux certificate store. +# This script is not intended to be used in any production environments. + +param ($OutDir) + +# Delete all certificates +rm $OutDir/clientcer/*.cer +rm $OutDir/localhostcert.pem +rm $OutDir/mismatchedcert.pem +rm /usr/local/share/ca-certificates/localhostcert.crt +rm /usr/local/share/ca-certificates/mismatchedcert.crt + +# Update the certificates store +Write-Output "Updating the certificates store..." +update-ca-certificates -v diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs index 94abbf5818..80d8633501 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs @@ -264,6 +264,10 @@ public override int Read(byte[] buffer, int offset, int count) // Calculate how much data can be read until the end of the packet is reached long packetDataAvailable = IncomingPacketHeader.Length - IncomingPacketPosition; + // Set count to actual size of data to be read from the buffer so this loop can exit + if (packetDataAvailable < count) + count = (int)packetDataAvailable; + // Check how much data we should give back in the current iteration int packetDataToRead = Math.Min((int)packetDataAvailable, count - bufferReadPosition);