Skip to content

Commit c20d6cd

Browse files
[Release 2.1] Fix missing error messages in Managed SNI (#883)
1 parent 57fa416 commit c20d6cd

File tree

8 files changed

+48
-36
lines changed

8 files changed

+48
-36
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.Windows.cs

+24-5
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ internal static uint MapLocalDBErrorStateToCode(LocalDBErrorState errorState)
8888
}
8989
}
9090

91+
internal static string MapLocalDBErrorStateToErrorMessage(LocalDBErrorState errorState)
92+
{
93+
switch (errorState)
94+
{
95+
case LocalDBErrorState.NO_INSTALLATION:
96+
return Strings.SNI_ERROR_52;
97+
case LocalDBErrorState.INVALID_CONFIG:
98+
return Strings.SNI_ERROR_53;
99+
case LocalDBErrorState.NO_SQLUSERINSTANCEDLL_PATH:
100+
return Strings.SNI_ERROR_54;
101+
case LocalDBErrorState.INVALID_SQLUSERINSTANCEDLL_PATH:
102+
return Strings.SNI_ERROR_55;
103+
case LocalDBErrorState.NONE:
104+
return Strings.SNI_ERROR_50;
105+
default:
106+
return Strings.SNI_ERROR_53;
107+
}
108+
}
109+
91110
/// <summary>
92111
/// Loads the User Instance dll.
93112
/// </summary>
@@ -117,15 +136,15 @@ private bool LoadUserInstanceDll()
117136
// If there was no DLL path found, then there is an error.
118137
if (dllPath == null)
119138
{
120-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, MapLocalDBErrorStateToCode(registryQueryErrorState), string.Empty);
139+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, MapLocalDBErrorStateToCode(registryQueryErrorState), MapLocalDBErrorStateToErrorMessage(registryQueryErrorState));
121140
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.LocalDB.Windows.LoadUserInstanceDll |SNI|ERR >User instance DLL path is null.");
122141
return false;
123142
}
124143

125144
// In case the registry had an empty path for dll
126145
if (string.IsNullOrWhiteSpace(dllPath))
127146
{
128-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBInvalidSqlUserInstanceDllPath, string.Empty);
147+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBInvalidSqlUserInstanceDllPath, Strings.SNI_ERROR_55);
129148
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.LocalDB.Windows.LoadUserInstanceDll |SNI|ERR > User instance DLL path is invalid. DLL path ={0}", dllPath);
130149
return false;
131150
}
@@ -135,7 +154,7 @@ private bool LoadUserInstanceDll()
135154

136155
if (libraryHandle.IsInvalid)
137156
{
138-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBFailedToLoadDll, string.Empty);
157+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBFailedToLoadDll, Strings.SNI_ERROR_56);
139158
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.LocalDB.Windows.LoadUserInstanceDll |SNI|ERR > Library Handle is invalid. Could not load the dll.");
140159
libraryHandle.Dispose();
141160
return false;
@@ -146,7 +165,7 @@ private bool LoadUserInstanceDll()
146165

147166
if (_startInstanceHandle == IntPtr.Zero)
148167
{
149-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, string.Empty);
168+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, Strings.SNI_ERROR_57);
150169
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.LocalDB.Windows.LoadUserInstanceDll |SNI|ERR > Was not able to load the PROC from DLL. Bad Runtime.");
151170
libraryHandle.Dispose();
152171
return false;
@@ -157,7 +176,7 @@ private bool LoadUserInstanceDll()
157176

158177
if (localDBStartInstanceFunc == null)
159178
{
160-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, string.Empty);
179+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBBadRuntime, Strings.SNI_ERROR_57);
161180
libraryHandle.Dispose();
162181
_startInstanceHandle = IntPtr.Zero;
163182
return false;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public uint StartReceive()
7575
return TdsEnums.SNI_SUCCESS_IO_PENDING;
7676
}
7777
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNIMarsConnection.StartReceive |SNI|ERR> Connection not useable.");
78-
return SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnNotUsableError, string.Empty);
78+
return SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnNotUsableError, Strings.SNI_ERROR_19);
7979
}
8080
finally
8181
{
@@ -293,7 +293,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode)
293293

294294
if (!_sessions.ContainsKey(_currentHeader.sessionId))
295295
{
296-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, string.Empty);
296+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, Strings.SNI_ERROR_5);
297297
HandleReceiveError(packet);
298298
_lowerHandle.Dispose();
299299
_lowerHandle = null;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds)
530530

531531
if (!_packetEvent.Wait(timeoutInMilliseconds))
532532
{
533-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnTimeoutError, string.Empty);
533+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnTimeoutError, Strings.SNI_ERROR_11);
534534
return TdsEnums.SNI_WAIT_TIMEOUT;
535535
}
536536
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ internal sealed class SNINpHandle : SNIPhysicalHandle
2222
private const int MAX_PIPE_INSTANCES = 255;
2323

2424
private readonly string _targetServer;
25-
private readonly object _callbackObject;
2625
private readonly object _sendSync;
2726

2827
private Stream _stream;
@@ -38,15 +37,14 @@ internal sealed class SNINpHandle : SNIPhysicalHandle
3837
private int _bufferSize = TdsEnums.DEFAULT_LOGIN_PACKET_SIZE;
3938
private readonly Guid _connectionId = Guid.NewGuid();
4039

41-
public SNINpHandle(string serverName, string pipeName, long timerExpire, object callbackObject)
40+
public SNINpHandle(string serverName, string pipeName, long timerExpire)
4241
{
4342
long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|INFO|SCOPE> Constructor");
4443
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|INFO> Constructor. server name = {0}, pipe name = {1}", serverName, pipeName);
4544
try
4645
{
4746
_sendSync = new object();
4847
_targetServer = serverName;
49-
_callbackObject = callbackObject;
5048

5149
try
5250
{
@@ -86,7 +84,7 @@ public SNINpHandle(string serverName, string pipeName, long timerExpire, object
8684

8785
if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead)
8886
{
89-
SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, string.Empty);
87+
SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
9088
_status = TdsEnums.SNI_ERROR;
9189
SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|ERR> Pipe stream is not connected or cannot write or read to/from it.");
9290
return;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ private void ReadFromStreamAsyncContinuation(Task<int> t, object state)
278278

279279
if (_dataLength == 0)
280280
{
281-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.ConnTerminatedError, string.Empty);
281+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.ConnTerminatedError, Strings.SNI_ERROR_2);
282282
error = true;
283283
}
284284
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs

+12-14
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync)
241241
/// <summary>
242242
/// Create a SNI connection handle
243243
/// </summary>
244-
/// <param name="callbackObject">Asynchronous I/O callback object</param>
245244
/// <param name="fullServerName">Full server name from connection string</param>
246245
/// <param name="ignoreSniOpenTimeout">Ignore open timeout</param>
247246
/// <param name="timerExpire">Timer expiration</param>
@@ -254,7 +253,7 @@ internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync)
254253
/// <param name="cachedFQDN">Used for DNS Cache</param>
255254
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
256255
/// <returns>SNI handle</returns>
257-
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)
256+
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)
258257
{
259258
instanceName = new byte[1];
260259

@@ -281,10 +280,10 @@ internal SNIHandle CreateConnectionHandle(object callbackObject, string fullServ
281280
case DataSource.Protocol.Admin:
282281
case DataSource.Protocol.None: // default to using tcp if no protocol is provided
283282
case DataSource.Protocol.TCP:
284-
sniHandle = CreateTcpHandle(details, timerExpire, callbackObject, parallel, cachedFQDN, ref pendingDNSInfo);
283+
sniHandle = CreateTcpHandle(details, timerExpire, parallel, cachedFQDN, ref pendingDNSInfo);
285284
break;
286285
case DataSource.Protocol.NP:
287-
sniHandle = CreateNpHandle(details, timerExpire, callbackObject, parallel);
286+
sniHandle = CreateNpHandle(details, timerExpire, parallel);
288287
break;
289288
default:
290289
Debug.Fail($"Unexpected connection protocol: {details._connectionProtocol}");
@@ -365,12 +364,11 @@ private static byte[] GetSqlServerSPN(string hostNameOrAddress, string portOrIns
365364
/// </summary>
366365
/// <param name="details">Data source</param>
367366
/// <param name="timerExpire">Timer expiration</param>
368-
/// <param name="callbackObject">Asynchronous I/O callback object</param>
369367
/// <param name="parallel">Should MultiSubnetFailover be used</param>
370368
/// <param name="cachedFQDN">Key for DNS Cache</param>
371369
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
372370
/// <returns>SNITCPHandle</returns>
373-
private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, object callbackObject, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
371+
private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
374372
{
375373
// TCP Format:
376374
// tcp:<host name>\<instance name>
@@ -379,7 +377,7 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
379377
string hostName = details.ServerName;
380378
if (string.IsNullOrWhiteSpace(hostName))
381379
{
382-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.InvalidConnStringError, string.Empty);
380+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.InvalidConnStringError, Strings.SNI_ERROR_25);
383381
return null;
384382
}
385383

@@ -408,7 +406,7 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
408406
port = isAdminConnection ? DefaultSqlServerDacPort : DefaultSqlServerPort;
409407
}
410408

411-
return new SNITCPHandle(hostName, port, timerExpire, callbackObject, parallel, cachedFQDN, ref pendingDNSInfo);
409+
return new SNITCPHandle(hostName, port, timerExpire, parallel, cachedFQDN, ref pendingDNSInfo);
412410
}
413411

414412

@@ -418,17 +416,17 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, objec
418416
/// </summary>
419417
/// <param name="details">Data source</param>
420418
/// <param name="timerExpire">Timer expiration</param>
421-
/// <param name="callbackObject">Asynchronous I/O callback object</param>
422419
/// <param name="parallel">Should MultiSubnetFailover be used. Only returns an error for named pipes.</param>
423420
/// <returns>SNINpHandle</returns>
424-
private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, object callbackObject, bool parallel)
421+
private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, bool parallel)
425422
{
426423
if (parallel)
427424
{
428-
SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, string.Empty);
425+
// Connecting to a SQL Server instance using the MultiSubnetFailover connection option is only supported when using the TCP protocol
426+
SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, Strings.SNI_ERROR_49);
429427
return null;
430428
}
431-
return new SNINpHandle(details.PipeHostName, details.PipeName, timerExpire, callbackObject);
429+
return new SNINpHandle(details.PipeHostName, details.PipeName, timerExpire);
432430
}
433431

434432
/// <summary>
@@ -632,7 +630,7 @@ internal static string GetLocalDBInstance(string dataSource, out bool error)
632630
}
633631
else
634632
{
635-
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBNoInstanceName, string.Empty);
633+
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, 0, SNICommon.LocalDBNoInstanceName, Strings.SNI_ERROR_51);
636634
error = true;
637635
return null;
638636
}
@@ -758,7 +756,7 @@ private bool InferConnectionDetails()
758756

759757
private void ReportSNIError(SNIProviders provider)
760758
{
761-
SNILoadHandle.SingletonInstance.LastError = new SNIError(provider, 0, SNICommon.InvalidConnStringError, string.Empty);
759+
SNILoadHandle.SingletonInstance.LastError = new SNIError(provider, 0, SNICommon.InvalidConnStringError, Strings.SNI_ERROR_25);
762760
IsBadDataSource = true;
763761
}
764762

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs

+5-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ namespace Microsoft.Data.SqlClient.SNI
2323
internal sealed class SNITCPHandle : SNIPhysicalHandle
2424
{
2525
private readonly string _targetServer;
26-
private readonly object _callbackObject;
2726
private readonly object _sendSync;
2827
private readonly Socket _socket;
2928
private NetworkStream _tcpStream;
@@ -114,13 +113,11 @@ public override int ProtocolVersion
114113
/// <param name="serverName">Server name</param>
115114
/// <param name="port">TCP port number</param>
116115
/// <param name="timerExpire">Connection timer expiration</param>
117-
/// <param name="callbackObject">Callback object</param>
118116
/// <param name="parallel">Parallel executions</param>
119117
/// <param name="cachedFQDN">Key for DNS Cache</param>
120118
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
121-
public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
119+
public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
122120
{
123-
_callbackObject = callbackObject;
124121
_targetServer = serverName;
125122
_sendSync = new object();
126123

@@ -217,7 +214,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba
217214

218215
if (reportError)
219216
{
220-
ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty);
217+
ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
221218
}
222219
return;
223220
}
@@ -259,7 +256,7 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
259256
{
260257
// Fail if above 64 to match legacy behavior
261258
callerReportError = false;
262-
ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, string.Empty);
259+
ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, Strings.SNI_ERROR_47);
263260
return availableSocket;
264261
}
265262

@@ -288,7 +285,7 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
288285
if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts)))
289286
{
290287
callerReportError = false;
291-
ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty);
288+
ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40);
292289
return availableSocket;
293290
}
294291

@@ -644,7 +641,7 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds)
644641
else
645642
{
646643
// otherwise it is timeout for 0 or less than -1
647-
ReportTcpSNIError(0, SNICommon.ConnTimeoutError, string.Empty);
644+
ReportTcpSNIError(0, SNICommon.ConnTimeoutError, Strings.SNI_ERROR_11);
648645
return TdsEnums.SNI_WAIT_TIMEOUT;
649646
}
650647

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, re
5151

5252
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)
5353
{
54-
_sessionHandle = SNIProxy.GetInstance().CreateConnectionHandle(this, serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, cachedFQDN, ref pendingDNSInfo);
54+
_sessionHandle = SNIProxy.GetInstance().CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, cachedFQDN, ref pendingDNSInfo);
5555
if (_sessionHandle == null)
5656
{
5757
_parser.ProcessSNIError(this);

0 commit comments

Comments
 (0)