diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.Windows.cs
index e77b93f5f0..3df18d1148 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.Windows.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.Windows.cs
@@ -88,6 +88,25 @@ internal static uint MapLocalDBErrorStateToCode(LocalDBErrorState errorState)
}
}
+ internal static string MapLocalDBErrorStateToErrorMessage(LocalDBErrorState errorState)
+ {
+ switch (errorState)
+ {
+ case LocalDBErrorState.NO_INSTALLATION:
+ return Strings.SNI_ERROR_52;
+ case LocalDBErrorState.INVALID_CONFIG:
+ return Strings.SNI_ERROR_53;
+ case LocalDBErrorState.NO_SQLUSERINSTANCEDLL_PATH:
+ return Strings.SNI_ERROR_54;
+ case LocalDBErrorState.INVALID_SQLUSERINSTANCEDLL_PATH:
+ return Strings.SNI_ERROR_55;
+ case LocalDBErrorState.NONE:
+ return Strings.SNI_ERROR_50;
+ default:
+ return Strings.SNI_ERROR_53;
+ }
+ }
+
///
/// Loads the User Instance dll.
///
@@ -117,7 +136,7 @@ private bool LoadUserInstanceDll()
// If there was no DLL path found, then there is an error.
if (dllPath == null)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, MapLocalDBErrorStateToCode(registryQueryErrorState), string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, MapLocalDBErrorStateToCode(registryQueryErrorState), MapLocalDBErrorStateToErrorMessage(registryQueryErrorState));
SqlClientEventSource.Log.TrySNITraceEvent("User instance DLL path is null.");
return false;
}
@@ -125,7 +144,7 @@ private bool LoadUserInstanceDll()
// In case the registry had an empty path for dll
if (string.IsNullOrWhiteSpace(dllPath))
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBInvalidSqlUserInstanceDllPath, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBInvalidSqlUserInstanceDllPath, Strings.SNI_ERROR_55);
SqlClientEventSource.Log.TrySNITraceEvent(" User instance DLL path is invalid. DLL path ={0}", dllPath);
return false;
}
@@ -135,7 +154,7 @@ private bool LoadUserInstanceDll()
if (libraryHandle.IsInvalid)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBFailedToLoadDll, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBFailedToLoadDll, Strings.SNI_ERROR_56);
SqlClientEventSource.Log.TrySNITraceEvent(" Library Handle is invalid. Could not load the dll.");
libraryHandle.Dispose();
return false;
@@ -146,7 +165,7 @@ private bool LoadUserInstanceDll()
if (_startInstanceHandle == IntPtr.Zero)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, Strings.SNI_ERROR_57);
SqlClientEventSource.Log.TrySNITraceEvent(" Was not able to load the PROC from DLL. Bad Runtime.");
libraryHandle.Dispose();
return false;
@@ -157,7 +176,7 @@ private bool LoadUserInstanceDll()
if (localDBStartInstanceFunc == null)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, Strings.SNI_ERROR_57);
libraryHandle.Dispose();
_startInstanceHandle = IntPtr.Zero;
return false;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs
index 555f368241..19a4f8ea2b 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs
@@ -75,7 +75,7 @@ public uint StartReceive()
return TdsEnums.SNI_SUCCESS_IO_PENDING;
}
SqlClientEventSource.Log.TrySNITraceEvent(" Connection not useable.");
- return SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnNotUsableError, string.Empty);
+ return SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnNotUsableError, Strings.SNI_ERROR_19);
}
finally
{
@@ -293,7 +293,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode)
if (!_sessions.ContainsKey(_currentHeader.sessionId))
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, Strings.SNI_ERROR_5);
HandleReceiveError(packet);
_lowerHandle.Dispose();
_lowerHandle = null;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs
index 5f339f00a2..c6fd0a7620 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs
@@ -530,7 +530,7 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds)
if (!_packetEvent.Wait(timeoutInMilliseconds))
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnTimeoutError, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnTimeoutError, Strings.SNI_ERROR_11);
return TdsEnums.SNI_WAIT_TIMEOUT;
}
}
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 0132d7df58..2914ac3c1b 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
@@ -22,7 +22,6 @@ internal sealed class SNINpHandle : SNIPhysicalHandle
private const int MAX_PIPE_INSTANCES = 255;
private readonly string _targetServer;
- private readonly object _callbackObject;
private readonly object _sendSync;
private Stream _stream;
@@ -38,7 +37,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, long timerExpire, object callbackObject)
+ public SNINpHandle(string serverName, string pipeName, long timerExpire)
{
long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(" Constructor");
SqlClientEventSource.Log.TrySNITraceEvent(" Constructor. server name = {0}, pipe name = {1}", serverName, pipeName);
@@ -46,7 +45,6 @@ public SNINpHandle(string serverName, string pipeName, long timerExpire, object
{
_sendSync = new object();
_targetServer = serverName;
- _callbackObject = callbackObject;
try
{
@@ -86,7 +84,7 @@ public SNINpHandle(string serverName, string pipeName, long timerExpire, object
if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead)
{
- SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, string.Empty);
+ SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
_status = TdsEnums.SNI_ERROR;
SqlClientEventSource.Log.TrySNITraceEvent(" Pipe stream is not connected or cannot write or read to/from it.");
return;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs
index 0ab375b129..f25d916a65 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs
@@ -278,7 +278,7 @@ private void ReadFromStreamAsyncContinuation(Task t, object state)
if (_dataLength == 0)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.ConnTerminatedError, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.ConnTerminatedError, Strings.SNI_ERROR_2);
error = true;
}
}
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 8038220844..6b2e87d8ec 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
@@ -241,7 +241,6 @@ internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync)
///
/// Create a SNI connection handle
///
- /// Asynchronous I/O callback object
/// Full server name from connection string
/// Ignore open timeout
/// Timer expiration
@@ -254,7 +253,7 @@ internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync)
/// Used for DNS Cache
/// Used for DNS Cache
/// SNI handle
- internal SNIHandle CreateConnectionHandle(object callbackObject, string fullServerName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[] spnBuffer, bool flushCache, bool async, bool parallel, bool isIntegratedSecurity, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
+ internal SNIHandle CreateConnectionHandle(string fullServerName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[] spnBuffer, bool flushCache, bool async, bool parallel, bool isIntegratedSecurity, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
instanceName = new byte[1];
@@ -281,10 +280,10 @@ internal SNIHandle CreateConnectionHandle(object callbackObject, string fullServ
case DataSource.Protocol.Admin:
case DataSource.Protocol.None: // default to using tcp if no protocol is provided
case DataSource.Protocol.TCP:
- sniHandle = CreateTcpHandle(details, timerExpire, callbackObject, parallel, cachedFQDN, ref pendingDNSInfo);
+ sniHandle = CreateTcpHandle(details, timerExpire, parallel, cachedFQDN, ref pendingDNSInfo);
break;
case DataSource.Protocol.NP:
- sniHandle = CreateNpHandle(details, timerExpire, callbackObject, parallel);
+ sniHandle = CreateNpHandle(details, timerExpire, parallel);
break;
default:
Debug.Fail($"Unexpected connection protocol: {details._connectionProtocol}");
@@ -365,12 +364,11 @@ private static byte[] GetSqlServerSPN(string hostNameOrAddress, string portOrIns
///
/// Data source
/// Timer expiration
- /// Asynchronous I/O callback object
/// Should MultiSubnetFailover be used
/// Key for DNS Cache
/// Used for DNS Cache
/// SNITCPHandle
- private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, object callbackObject, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
+ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
// TCP Format:
// tcp:\
@@ -379,7 +377,7 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
string hostName = details.ServerName;
if (string.IsNullOrWhiteSpace(hostName))
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.InvalidConnStringError, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.InvalidConnStringError, Strings.SNI_ERROR_25);
return null;
}
@@ -408,7 +406,7 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
port = isAdminConnection ? DefaultSqlServerDacPort : DefaultSqlServerPort;
}
- return new SNITCPHandle(hostName, port, timerExpire, callbackObject, parallel, cachedFQDN, ref pendingDNSInfo);
+ return new SNITCPHandle(hostName, port, timerExpire, parallel, cachedFQDN, ref pendingDNSInfo);
}
@@ -418,17 +416,17 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
///
/// Data source
/// Timer expiration
- /// Asynchronous I/O callback object
/// Should MultiSubnetFailover be used. Only returns an error for named pipes.
/// SNINpHandle
- private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, object callbackObject, bool parallel)
+ private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, bool parallel)
{
if (parallel)
{
- SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, string.Empty);
+ // Connecting to a SQL Server instance using the MultiSubnetFailover connection option is only supported when using the TCP protocol
+ SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, Strings.SNI_ERROR_49);
return null;
}
- return new SNINpHandle(details.PipeHostName, details.PipeName, timerExpire, callbackObject);
+ return new SNINpHandle(details.PipeHostName, details.PipeName, timerExpire);
}
///
@@ -632,7 +630,7 @@ internal static string GetLocalDBInstance(string dataSource, out bool error)
}
else
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBNoInstanceName, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBNoInstanceName, Strings.SNI_ERROR_51);
error = true;
return null;
}
@@ -758,7 +756,7 @@ private bool InferConnectionDetails()
private void ReportSNIError(SNIProviders provider)
{
- SNILoadHandle.SingletonInstance.LastError = new SNIError(provider, 0, SNICommon.InvalidConnStringError, string.Empty);
+ SNILoadHandle.SingletonInstance.LastError = new SNIError(provider, 0, SNICommon.InvalidConnStringError, Strings.SNI_ERROR_25);
IsBadDataSource = true;
}
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 51932e9c95..1f900a43f0 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
@@ -23,7 +23,6 @@ namespace Microsoft.Data.SqlClient.SNI
internal sealed class SNITCPHandle : SNIPhysicalHandle
{
private readonly string _targetServer;
- private readonly object _callbackObject;
private readonly object _sendSync;
private readonly Socket _socket;
private NetworkStream _tcpStream;
@@ -114,13 +113,11 @@ public override int ProtocolVersion
/// Server name
/// TCP port number
/// Connection timer expiration
- /// Callback object
/// Parallel executions
/// Key for DNS Cache
/// Used for DNS Cache
- public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
+ public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
- _callbackObject = callbackObject;
_targetServer = serverName;
_sendSync = new object();
@@ -217,7 +214,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba
if (reportError)
{
- ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty);
+ ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
}
return;
}
@@ -259,7 +256,7 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
{
// Fail if above 64 to match legacy behavior
callerReportError = false;
- ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, string.Empty);
+ ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, Strings.SNI_ERROR_47);
return availableSocket;
}
@@ -288,7 +285,7 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts)))
{
callerReportError = false;
- ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty);
+ ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
return availableSocket;
}
@@ -644,7 +641,7 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds)
else
{
// otherwise it is timeout for 0 or less than -1
- ReportTcpSNIError(0, SNICommon.ConnTimeoutError, string.Empty);
+ ReportTcpSNIError(0, SNICommon.ConnTimeoutError, Strings.SNI_ERROR_11);
return TdsEnums.SNI_WAIT_TIMEOUT;
}
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 9e9e281a32..48a6196f28 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
@@ -51,7 +51,7 @@ protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, re
internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[] spnBuffer, bool flushCache, bool async, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo, bool isIntegratedSecurity)
{
- _sessionHandle = SNIProxy.GetInstance().CreateConnectionHandle(this, serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, cachedFQDN, ref pendingDNSInfo);
+ _sessionHandle = SNIProxy.GetInstance().CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, cachedFQDN, ref pendingDNSInfo);
if (_sessionHandle == null)
{
_parser.ProcessSNIError(this);