Skip to content

Commit d5df671

Browse files
authored
Fix | Fixing issue for SQL named Instances in Managed SNI using named pipes. (#2142)
1 parent 5a4feed commit d5df671

4 files changed

Lines changed: 30 additions & 6 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, boo
6868
{
6969
int timeoutMilliseconds = timeout.MillisecondsRemainingInt;
7070
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO,
71-
"Connection Id {0}, Setting server name = {1}, pipe name = {2}. Connecting within the {3} sepecified milliseconds.",
71+
"Connection Id {0}, Setting server name = {1}, pipe name = {2}. Connecting within the {3} specified milliseconds.",
7272
args0: _connectionId,
7373
args1: serverName,
7474
args2: pipeName,

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ internal class DataSource
418418
private const string LocalDbHost_NP = @"np:\\.\pipe\LOCALDB#";
419419
private const string NamedPipeInstanceNameHeader = "mssql$";
420420
private const string DefaultPipeName = "sql\\query";
421+
private const string InstancePrefix = "MSSQL$";
422+
private const string PathSeparator = "\\";
421423

422424
internal enum Protocol { TCP, NP, None, Admin };
423425

@@ -683,12 +685,35 @@ private bool InferNamedPipesInformation()
683685
// If we have a datasource beginning with a pipe or we have already determined that the protocol is Named Pipe
684686
if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning, StringComparison.Ordinal) || _connectionProtocol == Protocol.NP)
685687
{
686-
// If the data source is "np:servername"
688+
// If the data source starts with "np:servername"
687689
if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning))
688690
{
689-
PipeHostName = ServerName = _dataSourceAfterTrimmingProtocol;
691+
// Assuming that user did not change default NamedPipe name, if the datasource is in the format servername\instance,
692+
// separate servername and instance and prepend instance with MSSQL$ and append default pipe path
693+
// https://learn.microsoft.com/en-us/sql/tools/configuration-manager/named-pipes-properties?view=sql-server-ver16
694+
if (_dataSourceAfterTrimmingProtocol.Contains(PathSeparator) && _connectionProtocol == Protocol.NP)
695+
{
696+
string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter);
697+
if (tokensByBackSlash.Length == 2)
698+
{
699+
// NamedPipeClientStream object will create the network path using PipeHostName and PipeName
700+
// and can be seen in its _normalizedPipePath variable in the format \\servername\pipe\MSSQL$<instancename>\sql\query
701+
PipeHostName = ServerName = tokensByBackSlash[0];
702+
PipeName = $"{InstancePrefix}{tokensByBackSlash[1]}{PathSeparator}{DefaultPipeName}";
703+
}
704+
else
705+
{
706+
ReportSNIError(SNIProviders.NP_PROV);
707+
return false;
708+
}
709+
}
710+
else
711+
{
712+
PipeHostName = ServerName = _dataSourceAfterTrimmingProtocol;
713+
PipeName = SNINpHandle.DefaultPipePath;
714+
}
715+
690716
InferLocalServerName();
691-
PipeName = SNINpHandle.DefaultPipePath;
692717
return true;
693718
}
694719

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove
7676
if (!IsValidInstance(hostname, instanceName))
7777
{
7878
builder.DataSource = hostname + "\\" + instanceName;
79-
79+
8080
using SqlConnection connection = new(builder.ConnectionString);
8181
SqlException ex = Assert.Throws<SqlException>(() => connection.Open());
8282
Assert.Contains("Error Locating Server/Instance Specified", ex.Message);

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCredentialTest/SqlCredentialTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests
1212
{
1313
public static class SqlCredentialTest
1414
{
15-
1615
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
1716
public static void CreateSqlConnectionWithCredential()
1817
{

0 commit comments

Comments
 (0)