Skip to content

Commit 4919a2e

Browse files
committed
Merge main
2 parents d13d4d6 + ad01286 commit 4919a2e

File tree

55 files changed

+1711
-1765
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1711
-1765
lines changed

src/Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageVersion Include="System.Memory" Version="4.5.5" />
1111
<PackageVersion Include="System.Data.Common" Version="4.3.0" />
1212
<PackageVersion Include="System.Text.Encodings.Web" Version="8.0.0" />
13+
<PackageVersion Include="System.ValueTuple" Version="4.6.1" />
1314
</ItemGroup>
1415
<!-- NetFx and NetCore project dependencies -->
1516
<ItemGroup>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@
819819
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectManaged.cs" />
820820
<Compile Include="Microsoft.Data.SqlClient.TypeForwards.cs" />
821821
</ItemGroup>
822+
822823
<!-- Windows only -->
823824
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
824825
<Compile Include="$(CommonSourceRoot)\Interop\Windows\Handles\SafeLibraryHandle.netcore.cs">
@@ -962,9 +963,11 @@
962963
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlTypes\SqlFileStream.Windows.cs">
963964
<Link>Microsoft\Data\SqlTypes\SqlFileStream.Windows.cs</Link>
964965
</Compile>
966+
965967
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Windows.cs" />
966968
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectNative.cs" />
967969
</ItemGroup>
970+
968971
<!-- Unix only -->
969972
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
970973
<Compile Include="$(CommonSourceRoot)Microsoft\Data\Common\AdapterUtil.Unix.cs">
@@ -1000,8 +1003,10 @@
10001003
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlTypes\SqlFileStream.netcore.Unix.cs">
10011004
<Link>Microsoft\Data\SqlTypes\SqlFileStream.netcore.Unix.cs</Link>
10021005
</Compile>
1006+
10031007
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Unix.cs" />
10041008
</ItemGroup>
1009+
10051010
<!-- Resources -->
10061011
<ItemGroup>
10071012
<Compile Include="$(CommonSourceRoot)Resources\StringsHelper.cs">
@@ -1029,6 +1034,7 @@
10291034
<Link>Resources\Microsoft.Data.SqlClient.SqlMetaData.xml</Link>
10301035
</EmbeddedResource>
10311036
</ItemGroup>
1037+
10321038
<!-- Package References Etc -->
10331039
<ItemGroup>
10341040
<PackageReference Include="Azure.Identity" />

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,8 +1492,7 @@ private void ThrowIfReconnectionHasBeenCanceled()
14921492
}
14931493
}
14941494

1495-
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/EndExecuteNonQueryAsync[@name="IAsyncResult"]/*'/>
1496-
public int EndExecuteNonQueryAsync(IAsyncResult asyncResult)
1495+
private int EndExecuteNonQueryAsync(IAsyncResult asyncResult)
14971496
{
14981497
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlCommand.EndExecuteNonQueryAsync | Info | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}, Command Text '{3}'", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId, CommandText);
14991498
Debug.Assert(!_internalEndExecuteInitiated || _stateObj == null);

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ public override int ConnectionTimeout
663663
get
664664
{
665665
SqlConnectionString constr = (SqlConnectionString)ConnectionOptions;
666-
return constr != null ? constr.ConnectTimeout : SqlConnectionString.DEFAULT.Connect_Timeout;
666+
return constr != null ? constr.ConnectTimeout : DbConnectionStringDefaults.ConnectTimeout;
667667
}
668668
}
669669

@@ -675,7 +675,7 @@ public int CommandTimeout
675675
get
676676
{
677677
SqlConnectionString constr = (SqlConnectionString)ConnectionOptions;
678-
return constr != null ? constr.CommandTimeout : SqlConnectionString.DEFAULT.Command_Timeout;
678+
return constr != null ? constr.CommandTimeout : DbConnectionStringDefaults.CommandTimeout;
679679
}
680680
}
681681

@@ -757,7 +757,7 @@ public override string Database
757757
else
758758
{
759759
SqlConnectionString constr = (SqlConnectionString)ConnectionOptions;
760-
result = constr != null ? constr.InitialCatalog : SqlConnectionString.DEFAULT.Initial_Catalog;
760+
result = constr != null ? constr.InitialCatalog : DbConnectionStringDefaults.InitialCatalog;
761761
}
762762
return result;
763763
}
@@ -830,7 +830,7 @@ public override string DataSource
830830
else
831831
{
832832
SqlConnectionString constr = (SqlConnectionString)ConnectionOptions;
833-
result = constr != null ? constr.DataSource : SqlConnectionString.DEFAULT.Data_Source;
833+
result = constr != null ? constr.DataSource : DbConnectionStringDefaults.DataSource;
834834
}
835835
return result;
836836
}
@@ -857,7 +857,7 @@ public int PacketSize
857857
else
858858
{
859859
SqlConnectionString constr = (SqlConnectionString)ConnectionOptions;
860-
result = constr != null ? constr.PacketSize : SqlConnectionString.DEFAULT.Packet_Size;
860+
result = constr != null ? constr.PacketSize : DbConnectionStringDefaults.PacketSize;
861861
}
862862
return result;
863863
}
@@ -2272,7 +2272,7 @@ public static void ChangePassword(string connectionString, string newPassword)
22722272
}
22732273
if (!string.IsNullOrEmpty(connectionOptions.AttachDBFilename))
22742274
{
2275-
throw SQL.ChangePasswordUseOfUnallowedKey(SqlConnectionString.KEY.AttachDBFilename);
2275+
throw SQL.ChangePasswordUseOfUnallowedKey(DbConnectionStringKeywords.AttachDbFilename);
22762276
}
22772277

22782278
ChangePassword(connectionString, connectionOptions, null, newPassword, null);
@@ -2329,7 +2329,7 @@ public static void ChangePassword(string connectionString, SqlCredential credent
23292329

23302330
if (!string.IsNullOrEmpty(connectionOptions.AttachDBFilename))
23312331
{
2332-
throw SQL.ChangePasswordUseOfUnallowedKey(SqlConnectionString.KEY.AttachDBFilename);
2332+
throw SQL.ChangePasswordUseOfUnallowedKey(DbConnectionStringKeywords.AttachDbFilename);
23332333
}
23342334

23352335
ChangePassword(connectionString, connectionOptions, credential, null, newSecurePassword);

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ internal bool IsDNSCachingBeforeRedirectSupported
207207
// Json Support Flag
208208
internal bool IsJsonSupportEnabled = false;
209209

210+
// User Agent Flag
211+
internal bool IsUserAgentEnabled = true;
212+
210213
// Vector Support Flag
211214
internal bool IsVectorSupportEnabled = false;
212215

@@ -1430,6 +1433,10 @@ private void Login(ServerInfo server, TimeoutTimer timeout, string newPassword,
14301433
requestedFeatures |= TdsEnums.FeatureExtension.JsonSupport;
14311434
requestedFeatures |= TdsEnums.FeatureExtension.VectorSupport;
14321435

1436+
#if DEBUG
1437+
requestedFeatures |= TdsEnums.FeatureExtension.UserAgent;
1438+
#endif
1439+
14331440
_parser.TdsLogin(login, requestedFeatures, _recoverySessionData, _fedAuthFeatureExtensionData, encrypt);
14341441
}
14351442

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,5 @@ private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersi
2222
{
2323
// No - Op
2424
}
25-
26-
private SNIErrorDetails GetSniErrorDetails()
27-
{
28-
SNIErrorDetails details;
29-
SniError sniError = SniProxy.Instance.GetLastError();
30-
details.sniErrorNumber = sniError.sniError;
31-
details.errorMessage = sniError.errorMessage;
32-
details.nativeError = sniError.nativeError;
33-
details.provider = (int)sniError.provider;
34-
details.lineNumber = sniError.lineNumber;
35-
details.function = sniError.function;
36-
details.exception = sniError.exception;
37-
38-
return details;
39-
}
40-
4125
}
4226
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
using System;
66
using System.Diagnostics;
7-
using Interop.Windows.Sni;
8-
using Microsoft.Data.SqlClient.ManagedSni;
9-
using SniError = Microsoft.Data.SqlClient.ManagedSni.SniError;
107

118
namespace Microsoft.Data.SqlClient
129
{
@@ -62,34 +59,5 @@ private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersi
6259
ThrowExceptionAndWarning(_physicalStateObj);
6360
}
6461
}
65-
66-
private SNIErrorDetails GetSniErrorDetails()
67-
{
68-
SNIErrorDetails details = new SNIErrorDetails();
69-
70-
if (TdsParserStateObjectFactory.UseManagedSNI)
71-
{
72-
SniError sniError = SniProxy.Instance.GetLastError();
73-
details.sniErrorNumber = sniError.sniError;
74-
details.errorMessage = sniError.errorMessage;
75-
details.nativeError = sniError.nativeError;
76-
details.provider = (int)sniError.provider;
77-
details.lineNumber = sniError.lineNumber;
78-
details.function = sniError.function;
79-
details.exception = sniError.exception;
80-
}
81-
else
82-
{
83-
SniNativeWrapper.SniGetLastError(out Interop.Windows.Sni.SniError sniError);
84-
details.sniErrorNumber = sniError.sniError;
85-
details.errorMessage = sniError.errorMessage;
86-
details.nativeError = sniError.nativeError;
87-
details.provider = (int)sniError.provider;
88-
details.lineNumber = sniError.lineNumber;
89-
details.function = sniError.function;
90-
}
91-
return details;
92-
}
93-
9462
} // tdsparser
9563
}//namespace

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,12 +1450,12 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14501450
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.ProcessSNIError|ERR> SNIContext must not be None = {0}, _fMARS = {1}, TDS Parser State = {2}", stateObj.DebugOnlyCopyOfSniContext, _fMARS, _state);
14511451

14521452
#endif
1453-
SNIErrorDetails details = GetSniErrorDetails();
1453+
TdsParserStateObject.SniErrorDetails details = stateObj.GetErrorDetails();
14541454

1455-
if (details.sniErrorNumber != 0)
1455+
if (details.SniErrorNumber != 0)
14561456
{
14571457
// handle special SNI error codes that are converted into exception which is not a SqlException.
1458-
switch (details.sniErrorNumber)
1458+
switch (details.SniErrorNumber)
14591459
{
14601460
case SniErrors.MultiSubnetFailoverWithMoreThan64IPs:
14611461
// Connecting with the MultiSubnetFailover connection option to a SQL Server instance configured with more than 64 IP addresses is not supported.
@@ -1476,8 +1476,8 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14761476
}
14771477
// PInvoke code automatically sets the length of the string for us
14781478
// So no need to look for \0
1479-
string errorMessage = details.errorMessage;
1480-
SqlClientEventSource.Log.TryAdvancedTraceEvent("< sc.TdsParser.ProcessSNIError |ERR|ADV > Error message Detail: {0}", details.errorMessage);
1479+
string errorMessage = details.ErrorMessage;
1480+
SqlClientEventSource.Log.TryAdvancedTraceEvent("< sc.TdsParser.ProcessSNIError |ERR|ADV > Error message Detail: {0}", details.ErrorMessage);
14811481

14821482
/* Format SNI errors and add Context Information
14831483
*
@@ -1494,25 +1494,25 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14941494

14951495
if (TdsParserStateObjectFactory.UseManagedSNI)
14961496
{
1497-
Debug.Assert(!string.IsNullOrEmpty(details.errorMessage) || details.sniErrorNumber != 0, "Empty error message received from SNI");
1498-
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}, SNI Error Number ={1}", details.errorMessage, details.sniErrorNumber);
1497+
Debug.Assert(!string.IsNullOrEmpty(details.ErrorMessage) || details.SniErrorNumber != 0, "Empty error message received from SNI");
1498+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}, SNI Error Number ={1}", details.ErrorMessage, details.SniErrorNumber);
14991499
}
15001500
else
15011501
{
1502-
Debug.Assert(!string.IsNullOrEmpty(details.errorMessage), "Empty error message received from SNI");
1503-
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}", details.errorMessage);
1502+
Debug.Assert(!string.IsNullOrEmpty(details.ErrorMessage), "Empty error message received from SNI");
1503+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}", details.ErrorMessage);
15041504
}
15051505

15061506
string sqlContextInfo = StringsHelper.GetResourceString(stateObj.SniContext.ToString());
1507-
string providerRid = string.Format("SNI_PN{0}", details.provider);
1507+
string providerRid = string.Format("SNI_PN{0}", details.Provider);
15081508
string providerName = StringsHelper.GetResourceString(providerRid);
15091509
Debug.Assert(!string.IsNullOrEmpty(providerName), $"invalid providerResourceId '{providerRid}'");
1510-
uint win32ErrorCode = details.nativeError;
1510+
uint win32ErrorCode = details.NativeError;
15111511

15121512
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > SNI Native Error Code = {0}", win32ErrorCode);
1513-
if (details.sniErrorNumber == 0)
1513+
if (details.SniErrorNumber == 0)
15141514
{
1515-
// Provider error. The message from provider is preceeded with non-localizable info from SNI
1515+
// Provider error. The message from provider is preceded with non-localizable info from SNI
15161516
// strip provider info from SNI
15171517
//
15181518
int iColon = errorMessage.IndexOf(':');
@@ -1544,33 +1544,33 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
15441544
if (TdsParserStateObjectFactory.UseManagedSNI)
15451545
{
15461546
// SNI error. Append additional error message info if available and hasn't been included.
1547-
string sniLookupMessage = SQL.GetSNIErrorMessage(details.sniErrorNumber);
1547+
string sniLookupMessage = SQL.GetSNIErrorMessage(details.SniErrorNumber);
15481548
errorMessage = (string.IsNullOrEmpty(errorMessage) || errorMessage.Contains(sniLookupMessage))
15491549
? sniLookupMessage
15501550
: (sniLookupMessage + ": " + errorMessage);
15511551
}
15521552
else
15531553
{
15541554
// SNI error. Replace the entire message.
1555-
errorMessage = SQL.GetSNIErrorMessage(details.sniErrorNumber);
1555+
errorMessage = SQL.GetSNIErrorMessage(details.SniErrorNumber);
15561556

15571557
// If its a LocalDB error, then nativeError actually contains a LocalDB-specific error code, not a win32 error code
1558-
if (details.sniErrorNumber == SniErrors.LocalDBErrorCode)
1558+
if (details.SniErrorNumber == SniErrors.LocalDBErrorCode)
15591559
{
1560-
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.nativeError);
1560+
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.NativeError);
15611561
win32ErrorCode = 0;
15621562
}
15631563
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Extracting the latest exception from native SNI. errorMessage: {0}", errorMessage);
15641564
}
15651565
}
15661566
errorMessage = string.Format("{0} (provider: {1}, error: {2} - {3})",
1567-
sqlContextInfo, providerName, (int)details.sniErrorNumber, errorMessage);
1567+
sqlContextInfo, providerName, (int)details.SniErrorNumber, errorMessage);
15681568

15691569
SqlClientEventSource.Log.TryAdvancedTraceErrorEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > SNI Error Message. Native Error = {0}, Line Number ={1}, Function ={2}, Exception ={3}, Server = {4}",
1570-
(int)details.nativeError, (int)details.lineNumber, details.function, details.exception, _server);
1570+
(int)details.NativeError, (int)details.LineNumber, details.Function, details.Exception, _server);
15711571

1572-
return new SqlError(infoNumber: (int)details.nativeError, errorState: 0x00, TdsEnums.FATAL_ERROR_CLASS, _server,
1573-
errorMessage, details.function, (int)details.lineNumber, win32ErrorCode: details.nativeError, details.exception);
1572+
return new SqlError(infoNumber: (int)details.NativeError, errorState: 0x00, TdsEnums.FATAL_ERROR_CLASS, _server,
1573+
errorMessage, details.Function, (int)details.LineNumber, win32ErrorCode: details.NativeError, details.Exception);
15741574
}
15751575
}
15761576

@@ -8579,6 +8579,49 @@ internal int WriteVectorSupportFeatureRequest(bool write)
85798579
return len;
85808580
}
85818581

8582+
/// <summary>
8583+
/// Writes the User Agent feature request to the physical state object.
8584+
/// The request includes the feature ID, feature data length, version number and encoded JSON payload.
8585+
/// </summary>
8586+
/// <param name="userAgentJsonPayload"> Byte array of UTF-8 encoded JSON payload for User Agent</param>
8587+
/// <param name="write">
8588+
/// If true, writes the feature request to the physical state object.
8589+
/// If false, just calculates the length.
8590+
/// </param>
8591+
/// <returns>The length of the feature request in bytes.</returns>
8592+
/// <remarks>
8593+
/// The feature request consists of:
8594+
/// - 1 byte for the feature ID.
8595+
/// - 4 bytes for the feature data length.
8596+
/// - 1 byte for the version number.
8597+
/// - N bytes for the JSON payload
8598+
/// </remarks>
8599+
internal int WriteUserAgentFeatureRequest(byte[] userAgentJsonPayload,
8600+
bool write)
8601+
{
8602+
// 1byte (Feature Version) + size of UTF-8 encoded JSON payload
8603+
int dataLen = 1 + userAgentJsonPayload.Length;
8604+
// 1byte (Feature ID) + 4bytes (Feature Data Length) + 1byte (Version) + N(JSON payload size)
8605+
int totalLen = 1 + 4 + dataLen;
8606+
8607+
if (write)
8608+
{
8609+
// Write Feature ID
8610+
_physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_USERAGENT);
8611+
8612+
// Feature Data Length
8613+
WriteInt(dataLen, _physicalStateObj);
8614+
8615+
// Write Feature Version
8616+
_physicalStateObj.WriteByte(TdsEnums.SUPPORTED_USER_AGENT_VERSION);
8617+
8618+
// Write encoded JSON payload
8619+
_physicalStateObj.WriteByteArray(userAgentJsonPayload, userAgentJsonPayload.Length, 0);
8620+
}
8621+
8622+
return totalLen;
8623+
}
8624+
85828625
private void WriteLoginData(SqlLogin rec,
85838626
TdsEnums.FeatureExtension requestedFeatures,
85848627
SessionData recoverySessionData,

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,15 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
392392
return 0;
393393
}
394394

395+
internal override SniErrorDetails GetErrorDetails()
396+
{
397+
SniError sniError = SniProxy.Instance.GetLastError();
398+
399+
return new SniErrorDetails(sniError.errorMessage, sniError.nativeError, sniError.sniError,
400+
(int)sniError.provider, sniError.lineNumber, sniError.function,
401+
sniError.exception);
402+
}
403+
395404
private SniHandle GetSessionSNIHandleHandleOrThrow()
396405
{
397406
SniHandle? sessionHandle = _sessionHandle;

0 commit comments

Comments
 (0)