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 350fa8c9bf..5d19cc3a23 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -659,7 +659,7 @@
-
+
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 bb9008f017..80d58289da 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
@@ -26,43 +26,10 @@
namespace Microsoft.Data.SqlClient
{
-
- internal struct SNIErrorDetails
- {
- public string errorMessage;
- public uint nativeError;
- public uint sniErrorNumber;
- public int provider;
- public uint lineNumber;
- public string function;
- public Exception exception;
- }
-
// The TdsParser Object controls reading/writing to the netlib, parsing the tds,
// and surfacing objects to the user.
internal sealed partial class TdsParser
{
- internal struct ReliabilitySection
- {
- ///
- /// This is a no-op in netcore version. Only needed for merging with netfx codebase.
- ///
- [Conditional("NETFRAMEWORK")]
- internal static void Assert(string message)
- {
- }
-
- [Conditional("NETFRAMEWORK")]
- internal void Start()
- {
- }
-
- [Conditional("NETFRAMEWORK")]
- internal void Stop()
- {
- }
- }
-
private static int _objectTypeCount; // EventSource counter
private readonly SqlClientLogger _logger = new SqlClientLogger();
@@ -1959,8 +1926,6 @@ internal void PrepareResetConnection(bool preserveTransaction)
_fPreserveTransaction = preserveTransaction;
}
-
-
internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
bool syncOverAsync = stateObj._syncOverAsync;
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.netcore.cs
similarity index 54%
rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.NetCoreApp.cs
rename to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.netcore.cs
index 95dd0d9731..f6e639c5f9 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.netcore.cs
@@ -10,6 +10,38 @@ namespace Microsoft.Data.SqlClient
{
internal sealed partial class TdsParser
{
+ internal struct SNIErrorDetails
+ {
+ public string errorMessage;
+ public uint nativeError;
+ public uint sniErrorNumber;
+ public int provider;
+ public uint lineNumber;
+ public string function;
+ public Exception exception;
+ }
+
+ internal struct ReliabilitySection
+ {
+ ///
+ /// This is a no-op in netcore version. Only needed for merging with netfx codebase.
+ ///
+ [Conditional("NETFRAMEWORK")]
+ internal static void Assert(string message)
+ {
+ }
+
+ [Conditional("NETFRAMEWORK")]
+ internal void Start()
+ {
+ }
+
+ [Conditional("NETFRAMEWORK")]
+ internal void Stop()
+ {
+ }
+ }
+
internal static void FillGuidBytes(Guid guid, Span buffer) => guid.TryWriteBytes(buffer);
internal static void FillDoubleBytes(double value, Span buffer) => BinaryPrimitives.TryWriteInt64LittleEndian(buffer, BitConverter.DoubleToInt64Bits(value));
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 10fdb263b9..69bf5a85cd 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -841,6 +841,7 @@
+
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 03889347ae..ea5e5a8bbc 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
@@ -66,89 +66,7 @@ internal int ObjectID
/// Verify client encryption possibility.
///
private bool ClientOSEncryptionSupport => SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport;
-
- // ReliabilitySection Usage:
- //
- // #if DEBUG
- // TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
- //
- // RuntimeHelpers.PrepareConstrainedRegions();
- // try {
- // tdsReliabilitySection.Start();
- // #else
- // {
- // #endif //DEBUG
- //
- // // code that requires reliability
- //
- // }
- // #if DEBUG
- // finally {
- // tdsReliabilitySection.Stop();
- // }
- // #endif //DEBUG
-
- internal struct ReliabilitySection
- {
-#if DEBUG
- // do not allocate TLS data in RETAIL bits
- [ThreadStatic]
- private static int s_reliabilityCount; // initialized to 0 by CLR
-
- private bool m_started; // initialized to false (not started) by CLR
-#endif //DEBUG
-
- [Conditional("DEBUG")]
- internal void Start()
- {
-#if DEBUG
- Debug.Assert(!m_started);
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- }
- finally
- {
- ++s_reliabilityCount;
- m_started = true;
- }
-#endif //DEBUG
- }
-
- [Conditional("DEBUG")]
- internal void Stop()
- {
-#if DEBUG
- // cannot assert m_started - ThreadAbortException can be raised before Start is called
-
- if (m_started)
- {
- Debug.Assert(s_reliabilityCount > 0);
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- }
- finally
- {
- --s_reliabilityCount;
- m_started = false;
- }
- }
-#endif //DEBUG
- }
-
- // you need to setup for a thread abort somewhere before you call this method
- [Conditional("DEBUG")]
- internal static void Assert(string message)
- {
-#if DEBUG
- Debug.Assert(s_reliabilityCount > 0, message);
-#endif //DEBUG
- }
- }
-
+
// Default state object for parser
internal TdsParserStateObject _physicalStateObj = null; // Default stateObj and connection for Dbnetlib and non-MARS SNI.
@@ -805,60 +723,6 @@ internal void Connect(ServerInfo serverInfo,
return;
}
- // Retrieve the IP and port number from native SNI for TCP protocol. The IP information is stored temporarily in the
- // pendingSQLDNSObject but not in the DNS Cache at this point. We only add items to the DNS Cache after we receive the
- // IsSupported flag as true in the feature ext ack from server.
- internal void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey)
- {
- UInt32 result;
- ushort portFromSNI = 0;
- string IPStringFromSNI = string.Empty;
- IPAddress IPFromSNI;
- isTcpProtocol = false;
- Provider providerNumber = Provider.INVALID_PROV;
-
- if (string.IsNullOrEmpty(userProtocol))
- {
-
- result = SNINativeMethodWrapper.SniGetProviderNumber(_physicalStateObj.Handle, ref providerNumber);
- Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber");
- isTcpProtocol = (providerNumber == Provider.TCP_PROV);
- }
- else if (userProtocol == TdsEnums.TCP)
- {
- isTcpProtocol = true;
- }
-
- // serverInfo.UserProtocol could be empty
- if (isTcpProtocol)
- {
- result = SNINativeMethodWrapper.SniGetConnectionPort(_physicalStateObj.Handle, ref portFromSNI);
- Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionPort");
-
-
- result = SNINativeMethodWrapper.SniGetConnectionIPString(_physicalStateObj.Handle, ref IPStringFromSNI);
- Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionIPString");
-
- _connHandler.pendingSQLDNSObject = new SQLDNSInfo(DNSCacheKey, null, null, portFromSNI.ToString());
-
- if (IPAddress.TryParse(IPStringFromSNI, out IPFromSNI))
- {
- if (System.Net.Sockets.AddressFamily.InterNetwork == IPFromSNI.AddressFamily)
- {
- _connHandler.pendingSQLDNSObject.AddrIPv4 = IPStringFromSNI;
- }
- else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == IPFromSNI.AddressFamily)
- {
- _connHandler.pendingSQLDNSObject.AddrIPv6 = IPStringFromSNI;
- }
- }
- }
- else
- {
- _connHandler.pendingSQLDNSObject = null;
- }
- }
-
internal void RemoveEncryption()
{
Debug.Assert((_encryptionOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.LOGIN, "Invalid encryption option state");
@@ -989,41 +853,6 @@ internal void PutSession(TdsParserStateObject session)
}
}
- // This is called from a ThreadAbort - ensure that it can be run from a CER Catch
- internal void BestEffortCleanup()
- {
- _state = TdsParserState.Broken;
-
- var stateObj = _physicalStateObj;
- if (stateObj != null)
- {
- var stateObjHandle = stateObj.Handle;
- if (stateObjHandle != null)
- {
- stateObjHandle.Dispose();
- }
- }
-
- if (_fMARS)
- {
- var sessionPool = _sessionPool;
- if (sessionPool != null)
- {
- sessionPool.BestEffortCleanup();
- }
-
- var marsStateObj = _pMarsPhysicalConObj;
- if (marsStateObj != null)
- {
- var marsStateObjHandle = marsStateObj.Handle;
- if (marsStateObjHandle != null)
- {
- marsStateObjHandle.Dispose();
- }
- }
- }
- }
-
private void SendPreLoginHandshake(
byte[] instanceName,
SqlConnectionEncryptOption encrypt,
@@ -2248,44 +2077,6 @@ internal void PrepareResetConnection(bool preserveTransaction)
_fPreserveTransaction = preserveTransaction;
}
- internal bool RunReliably(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
- {
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
-#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- tdsReliabilitySection.Start();
-#endif //DEBUG
- return Run(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj);
-#if DEBUG
- }
- finally
- {
- tdsReliabilitySection.Stop();
- }
-#endif //DEBUG
- }
- catch (OutOfMemoryException)
- {
- _connHandler.DoomThisConnection();
- throw;
- }
- catch (StackOverflowException)
- {
- _connHandler.DoomThisConnection();
- throw;
- }
- catch (ThreadAbortException)
- {
- _connHandler.DoomThisConnection();
- throw;
- }
- }
-
internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
bool syncOverAsync = stateObj._syncOverAsync;
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.netfx.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.netfx.cs
new file mode 100644
index 0000000000..98101a2bc4
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.netfx.cs
@@ -0,0 +1,221 @@
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System;
+using System.Net;
+using System.Threading;
+using Interop.Windows.Sni;
+
+namespace Microsoft.Data.SqlClient
+{
+ internal sealed partial class TdsParser
+ {
+ // ReliabilitySection Usage:
+ //
+ // #if DEBUG
+ // TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ //
+ // RuntimeHelpers.PrepareConstrainedRegions();
+ // try {
+ // tdsReliabilitySection.Start();
+ // #else
+ // {
+ // #endif //DEBUG
+ //
+ // // code that requires reliability
+ //
+ // }
+ // #if DEBUG
+ // finally {
+ // tdsReliabilitySection.Stop();
+ // }
+ // #endif //DEBUG
+
+ internal struct ReliabilitySection
+ {
+#if DEBUG
+ // do not allocate TLS data in RETAIL bits
+ [ThreadStatic]
+ private static int s_reliabilityCount; // initialized to 0 by CLR
+
+ private bool m_started; // initialized to false (not started) by CLR
+#endif //DEBUG
+
+ [Conditional("DEBUG")]
+ internal void Start()
+ {
+#if DEBUG
+ Debug.Assert(!m_started);
+
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ }
+ finally
+ {
+ ++s_reliabilityCount;
+ m_started = true;
+ }
+#endif //DEBUG
+ }
+
+ [Conditional("DEBUG")]
+ internal void Stop()
+ {
+#if DEBUG
+ // cannot assert m_started - ThreadAbortException can be raised before Start is called
+
+ if (m_started)
+ {
+ Debug.Assert(s_reliabilityCount > 0);
+
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ }
+ finally
+ {
+ --s_reliabilityCount;
+ m_started = false;
+ }
+ }
+#endif //DEBUG
+ }
+
+ // you need to setup for a thread abort somewhere before you call this method
+ [Conditional("DEBUG")]
+ internal static void Assert(string message)
+ {
+#if DEBUG
+ Debug.Assert(s_reliabilityCount > 0, message);
+#endif //DEBUG
+ }
+ }
+
+ // This is called from a ThreadAbort - ensure that it can be run from a CER Catch
+ internal void BestEffortCleanup()
+ {
+ _state = TdsParserState.Broken;
+
+ var stateObj = _physicalStateObj;
+ if (stateObj != null)
+ {
+ var stateObjHandle = stateObj.Handle;
+ if (stateObjHandle != null)
+ {
+ stateObjHandle.Dispose();
+ }
+ }
+
+ if (_fMARS)
+ {
+ var sessionPool = _sessionPool;
+ if (sessionPool != null)
+ {
+ sessionPool.BestEffortCleanup();
+ }
+
+ var marsStateObj = _pMarsPhysicalConObj;
+ if (marsStateObj != null)
+ {
+ var marsStateObjHandle = marsStateObj.Handle;
+ if (marsStateObjHandle != null)
+ {
+ marsStateObjHandle.Dispose();
+ }
+ }
+ }
+ }
+
+ // Retrieve the IP and port number from native SNI for TCP protocol. The IP information is stored temporarily in the
+ // pendingSQLDNSObject but not in the DNS Cache at this point. We only add items to the DNS Cache after we receive the
+ // IsSupported flag as true in the feature ext ack from server.
+ internal void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey)
+ {
+ uint result;
+ ushort portFromSNI = 0;
+ string IPStringFromSNI = string.Empty;
+ IPAddress IPFromSNI;
+ isTcpProtocol = false;
+ Provider providerNumber = Provider.INVALID_PROV;
+
+ if (string.IsNullOrEmpty(userProtocol))
+ {
+
+ result = SNINativeMethodWrapper.SniGetProviderNumber(_physicalStateObj.Handle, ref providerNumber);
+ Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber");
+ isTcpProtocol = (providerNumber == Provider.TCP_PROV);
+ }
+ else if (userProtocol == TdsEnums.TCP)
+ {
+ isTcpProtocol = true;
+ }
+
+ // serverInfo.UserProtocol could be empty
+ if (isTcpProtocol)
+ {
+ result = SNINativeMethodWrapper.SniGetConnectionPort(_physicalStateObj.Handle, ref portFromSNI);
+ Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionPort");
+
+
+ result = SNINativeMethodWrapper.SniGetConnectionIPString(_physicalStateObj.Handle, ref IPStringFromSNI);
+ Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionIPString");
+
+ _connHandler.pendingSQLDNSObject = new SQLDNSInfo(DNSCacheKey, null, null, portFromSNI.ToString());
+
+ if (IPAddress.TryParse(IPStringFromSNI, out IPFromSNI))
+ {
+ if (System.Net.Sockets.AddressFamily.InterNetwork == IPFromSNI.AddressFamily)
+ {
+ _connHandler.pendingSQLDNSObject.AddrIPv4 = IPStringFromSNI;
+ }
+ else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == IPFromSNI.AddressFamily)
+ {
+ _connHandler.pendingSQLDNSObject.AddrIPv6 = IPStringFromSNI;
+ }
+ }
+ }
+ else
+ {
+ _connHandler.pendingSQLDNSObject = null;
+ }
+ }
+
+ internal bool RunReliably(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
+ {
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+#if DEBUG
+ TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ tdsReliabilitySection.Start();
+#endif //DEBUG
+ return Run(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj);
+#if DEBUG
+ }
+ finally
+ {
+ tdsReliabilitySection.Stop();
+ }
+#endif //DEBUG
+ }
+ catch (OutOfMemoryException)
+ {
+ _connHandler.DoomThisConnection();
+ throw;
+ }
+ catch (StackOverflowException)
+ {
+ _connHandler.DoomThisConnection();
+ throw;
+ }
+ catch (ThreadAbortException)
+ {
+ _connHandler.DoomThisConnection();
+ throw;
+ }
+ }
+ }
+}