diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs
index 7c16bb0afb..7f181d89d4 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs
@@ -31,8 +31,11 @@ internal enum SniSpecialErrors : uint
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumCloseWrapper")]
internal static extern void SNIServerEnumClose([In] IntPtr packet);
- [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper")]
- internal static extern int SNIServerEnumRead([In] IntPtr packet, [In, Out] char[] readBuffer, int bufferLength, out bool more);
+ [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper", CharSet = CharSet.Unicode)]
+ internal static extern int SNIServerEnumRead([In] IntPtr packet,
+ [In][MarshalAs(UnmanagedType.LPArray)] char[] readBuffer,
+ [In] int bufferLength,
+ [MarshalAs(UnmanagedType.Bool)] out bool more);
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs
index 0f3d54e474..a171752ebf 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs
@@ -11,7 +11,7 @@
namespace Microsoft.Data.SqlClient.SNI
{
- internal class SSRP
+ internal sealed class SSRP
{
private const char SemicolonSeparator = ';';
private const int SqlServerBrowserPort = 1434; //port SQL Server Browser
@@ -78,11 +78,11 @@ private static byte[] CreateInstanceInfoRequest(string instanceName)
{
const byte ClntUcastInst = 0x04;
instanceName += char.MinValue;
- int byteCount = Encoding.ASCII.GetByteCount(instanceName);
+ int byteCount = Encoding.UTF7.GetByteCount(instanceName);
byte[] requestPacket = new byte[byteCount + 1];
requestPacket[0] = ClntUcastInst;
- Encoding.ASCII.GetBytes(instanceName, 0, instanceName.Length, requestPacket, 1);
+ Encoding.UTF7.GetBytes(instanceName, 0, instanceName.Length, requestPacket, 1);
return requestPacket;
}
@@ -127,12 +127,12 @@ private static byte[] CreateDacPortInfoRequest(string instanceName)
const byte ClntUcastDac = 0x0F;
const byte ProtocolVersion = 0x01;
instanceName += char.MinValue;
- int byteCount = Encoding.ASCII.GetByteCount(instanceName);
+ int byteCount = Encoding.UTF7.GetByteCount(instanceName);
byte[] requestPacket = new byte[byteCount + 2];
requestPacket[0] = ClntUcastDac;
requestPacket[1] = ProtocolVersion;
- Encoding.ASCII.GetBytes(instanceName, 0, instanceName.Length, requestPacket, 2);
+ Encoding.UTF7.GetBytes(instanceName, 0, instanceName.Length, requestPacket, 2);
return requestPacket;
}
@@ -184,7 +184,9 @@ internal static string SendBroadcastUDPRequest()
{
StringBuilder response = new StringBuilder();
byte[] CLNT_BCAST_EX_Request = new byte[1] { CLNT_BCAST_EX }; //0x02
- int currentTimeOut = FirstTimeoutForCLNT_BCAST_EX; //wait 5 secs for first response and every 1 sec upto 15 secs (https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-sqlr/f2640a2d-3beb-464b-a443-f635842ebc3e#Appendix_A_3)
+ // Waits 5 seconds for the first response and every 1 second up to 15 seconds
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-sqlr/f2640a2d-3beb-464b-a443-f635842ebc3e#Appendix_A_3
+ int currentTimeOut = FirstTimeoutForCLNT_BCAST_EX;
using (TrySNIEventScope.Create(nameof(SSRP)))
{
@@ -203,7 +205,7 @@ internal static string SendBroadcastUDPRequest()
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SSRP), EventType.INFO, "Received instnace info from UDP Client.");
if (receiveTask.Result.Buffer.Length < ValidResponseSizeForCLNT_BCAST_EX) //discard invalid response
{
- response.Append(Encoding.ASCII.GetString(receiveTask.Result.Buffer, ServerResponseHeaderSizeForCLNT_BCAST_EX, receiveTask.Result.Buffer.Length - ServerResponseHeaderSizeForCLNT_BCAST_EX)); //RESP_DATA(VARIABLE) - 3 (RESP_SIZE + SVR_RESP)
+ response.Append(Encoding.UTF7.GetString(receiveTask.Result.Buffer, ServerResponseHeaderSizeForCLNT_BCAST_EX, receiveTask.Result.Buffer.Length - ServerResponseHeaderSizeForCLNT_BCAST_EX)); //RESP_DATA(VARIABLE) - 3 (RESP_SIZE + SVR_RESP)
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs
index d851c01eda..13e35363a8 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs
@@ -141,7 +141,10 @@ internal static extern unsafe uint SNISecGenClientContextWrapper(
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumCloseWrapper")]
internal static extern void SNIServerEnumClose([In] IntPtr packet);
- [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper")]
- internal static extern int SNIServerEnumRead([In] IntPtr packet, [In, Out] char[] readBuffer, int bufferLength, out bool more);
+ [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper", CharSet = CharSet.Unicode)]
+ internal static extern int SNIServerEnumRead([In] IntPtr packet,
+ [In, Out][MarshalAs(UnmanagedType.LPArray)] char[] readBuffer,
+ [In] int bufferLength,
+ [MarshalAs(UnmanagedType.Bool)] out bool more);
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs
index 276e8cdc29..5517ba8c0e 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs
@@ -141,7 +141,10 @@ internal static extern unsafe uint SNISecGenClientContextWrapper(
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumCloseWrapper")]
internal static extern void SNIServerEnumClose([In] IntPtr packet);
- [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper")]
- internal static extern int SNIServerEnumRead([In] IntPtr packet, [In, Out] char[] readBuffer, int bufferLength, out bool more);
+ [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper", CharSet = CharSet.Unicode)]
+ internal static extern int SNIServerEnumRead([In] IntPtr packet,
+ [In, Out][MarshalAs(UnmanagedType.LPArray)] char[] readBuffer,
+ [In] int bufferLength,
+ [MarshalAs(UnmanagedType.Bool)] out bool more);
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs
index 7d093d487d..02ed400aea 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs
@@ -1,10 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Collections.Generic;
using System.Data;
-using System.Globalization;
using Microsoft.Data.Sql;
using Microsoft.Data.SqlClient.SNI;
@@ -13,27 +11,21 @@ namespace Microsoft.Data.SqlClient.Server
///
/// Provides a mechanism for enumerating all available instances of SQL Server within the local network
///
- internal static class SqlDataSourceEnumeratorManagedHelper
+ internal static class SqlDataSourceEnumeratorManagedHelper
{
///
/// Provides a mechanism for enumerating all available instances of SQL Server within the local network.
///
/// DataTable with ServerName,InstanceName,IsClustered and Version
internal static DataTable GetDataSources()
- {
+ {
return ParseServerEnumString(SSRP.SendBroadcastUDPRequest());
}
- static private System.Data.DataTable ParseServerEnumString(string serverInstances)
+ private static DataTable ParseServerEnumString(string serverInstances)
{
- DataTable dataTable = new("SqlDataSources")
- {
- Locale = CultureInfo.InvariantCulture
- };
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.ServerName, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.InstanceName, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.IsClustered, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.Version, typeof(string));
+ System.Console.WriteLine(serverInstances);
+ DataTable dataTable = SqlDataSourceEnumeratorUtil.PrepareDataTable();
DataRow dataRow;
if (serverInstances.Length == 0)
@@ -41,8 +33,9 @@ static private System.Data.DataTable ParseServerEnumString(string serverInstance
return dataTable;
}
- string[] numOfServerInstances = serverInstances.Split(new[] { SqlDataSourceEnumeratorUtil.EndOfServerInstanceDelimiterManaged }, StringSplitOptions.None);
- SqlClientEventSource.Log.TryTraceEvent(" Number of server instances results recieved are {0}", numOfServerInstances.Length);
+ string[] numOfServerInstances = serverInstances.Split(SqlDataSourceEnumeratorUtil.s_endOfServerInstanceDelimiter_Managed, System.StringSplitOptions.None);
+ SqlClientEventSource.Log.TryTraceEvent(" Number of recieved server instances are {2}",
+ nameof(SqlDataSourceEnumeratorManagedHelper), nameof(ParseServerEnumString), numOfServerInstances.Length);
foreach (string currentServerInstance in numOfServerInstances)
{
@@ -65,24 +58,19 @@ static private System.Data.DataTable ParseServerEnumString(string serverInstance
if (InstanceDetails.Count > 0)
{
dataRow = dataTable.NewRow();
- dataRow[0] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.ServerName) == true ?
- InstanceDetails[SqlDataSourceEnumeratorUtil.ServerName] : string.Empty;
- dataRow[1] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.InstanceName) == true ?
- InstanceDetails[SqlDataSourceEnumeratorUtil.InstanceName] : string.Empty;
- dataRow[2] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.IsClustered) == true ?
- InstanceDetails[SqlDataSourceEnumeratorUtil.IsClustered] : string.Empty;
- dataRow[3] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.Version) == true ?
- InstanceDetails[SqlDataSourceEnumeratorUtil.Version] : string.Empty;
+ dataRow[0] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.ServerNameCol) == true ?
+ InstanceDetails[SqlDataSourceEnumeratorUtil.ServerNameCol] : string.Empty;
+ dataRow[1] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.InstanceNameCol) == true ?
+ InstanceDetails[SqlDataSourceEnumeratorUtil.InstanceNameCol] : string.Empty;
+ dataRow[2] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.IsClusteredCol) == true ?
+ InstanceDetails[SqlDataSourceEnumeratorUtil.IsClusteredCol] : string.Empty;
+ dataRow[3] = InstanceDetails.ContainsKey(SqlDataSourceEnumeratorUtil.VersionNameCol) == true ?
+ InstanceDetails[SqlDataSourceEnumeratorUtil.VersionNameCol] : string.Empty;
dataTable.Rows.Add(dataRow);
}
}
-
- foreach (DataColumn column in dataTable.Columns)
- {
- column.ReadOnly = true;
- }
- return dataTable;
+ return dataTable.SetColumnsReadOnly();
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs
index 016dea0f2e..db40a6439e 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs
@@ -1,22 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+
using System;
using System.Data;
using System.Diagnostics;
-using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using Microsoft.Data.Common;
using Microsoft.Data.SqlClient;
+using static Microsoft.Data.Sql.SqlDataSourceEnumeratorUtil;
namespace Microsoft.Data.Sql
{
///
/// Provides a mechanism for enumerating all available instances of SQL Server within the local network
///
- internal class SqlDataSourceEnumeratorNativeHelper
+ internal static class SqlDataSourceEnumeratorNativeHelper
{
///
/// Retrieves a DataTable containing information about all visible SQL Server instances
@@ -28,7 +29,7 @@ internal static DataTable GetDataSources()
char[] buffer = null;
StringBuilder strbldr = new();
- int bufferSize = 65536;
+ int bufferSize = 1024;
int readLength = 0;
buffer = new char[bufferSize];
bool more = true;
@@ -45,26 +46,31 @@ internal static DataTable GetDataSources()
finally
{
handle = SNINativeMethodWrapper.SNIServerEnumOpen();
+ SqlClientEventSource.Log.TryTraceEvent(" {3} returned handle = {4}.",
+ nameof(SqlDataSourceEnumeratorNativeHelper),
+ nameof(GetDataSources),
+ nameof(SNINativeMethodWrapper.SNIServerEnumOpen), handle);
}
if (handle != ADP.s_ptrZero)
{
while (more && !TdsParserStaticMethods.TimeoutHasExpired(s_timeoutTime))
{
-#if NETFRAMEWORK
- readLength = SNINativeMethodWrapper.SNIServerEnumRead(handle, buffer, bufferSize, out more);
-#else
readLength = SNINativeMethodWrapper.SNIServerEnumRead(handle, buffer, bufferSize, out more);
-#endif
- SqlClientEventSource.Log.TryTraceEvent(" GetDataSources:SNIServerEnumRead returned readlength {0}", readLength);
+
+ SqlClientEventSource.Log.TryTraceEvent(" {2} returned 'readlength':{3}, and 'more':{4} with 'bufferSize' of {5}",
+ nameof(SqlDataSourceEnumeratorNativeHelper),
+ nameof(GetDataSources),
+ nameof(SNINativeMethodWrapper.SNIServerEnumRead),
+ readLength, more, bufferSize);
if (readLength > bufferSize)
{
failure = true;
more = false;
}
- else if (0 < readLength)
+ else if (readLength > 0)
{
- strbldr.Append(buffer);
+ strbldr.Append(buffer, 0, readLength);
}
}
}
@@ -74,69 +80,75 @@ internal static DataTable GetDataSources()
if (handle != ADP.s_ptrZero)
{
SNINativeMethodWrapper.SNIServerEnumClose(handle);
+ SqlClientEventSource.Log.TryTraceEvent(" {3} called.",
+ nameof(SqlDataSourceEnumeratorNativeHelper),
+ nameof(GetDataSources),
+ nameof(SNINativeMethodWrapper.SNIServerEnumClose));
}
}
if (failure)
{
- Debug.Assert(false, "GetDataSources:SNIServerEnumRead returned bad length");
- SqlClientEventSource.Log.TryTraceEvent(" GetDataSources:SNIServerEnumRead returned bad length, requested %d, received %d", bufferSize, readLength);
- throw ADP.ArgumentOutOfRange("readLength");
+ Debug.Assert(false, $"{nameof(GetDataSources)}:{nameof(SNINativeMethodWrapper.SNIServerEnumRead)} returned bad length");
+ SqlClientEventSource.Log.TryTraceEvent(" {2} returned bad length, requested buffer {3}, received {4}",
+ nameof(SqlDataSourceEnumeratorNativeHelper),
+ nameof(GetDataSources),
+ nameof(SNINativeMethodWrapper.SNIServerEnumRead),
+ bufferSize, readLength);
+
+ throw ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.ADP_ParameterValueOutOfRange, readLength), nameof(readLength));
}
return ParseServerEnumString(strbldr.ToString());
}
- static private System.Data.DataTable ParseServerEnumString(string serverInstances)
+ private static DataTable ParseServerEnumString(string serverInstances)
{
- DataTable dataTable = new("SqlDataSources");
- dataTable.Locale = CultureInfo.InvariantCulture;
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.ServerName, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.InstanceName, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.IsClustered, typeof(string));
- dataTable.Columns.Add(SqlDataSourceEnumeratorUtil.Version, typeof(string));
+ DataTable dataTable = PrepareDataTable();
string serverName = null;
string instanceName = null;
string isClustered = null;
string version = null;
- string[] serverinstanceslist = serverInstances.Split(new string[] { SqlDataSourceEnumeratorUtil.EndOfServerInstanceDelimiterNative }, StringSplitOptions.None);
- SqlClientEventSource.Log.TryTraceEvent(" Number of server instances results recieved are {0}", serverinstanceslist.Length);
+ string[] serverinstanceslist = serverInstances.Split(EndOfServerInstanceDelimiter_Native);
+ SqlClientEventSource.Log.TryTraceEvent(" Number of recieved server instances are {2}",
+ nameof(SqlDataSourceEnumeratorNativeHelper), nameof(ParseServerEnumString), serverinstanceslist.Length);
// Every row comes in the format "serverName\instanceName;Clustered:[Yes|No];Version:.."
// Every row is terminated by a null character.
// Process one row at a time
foreach (string instance in serverinstanceslist)
{
- // string value = instance.Trim('\0'); // MDAC 91934
- string value = instance.Replace("\0", "");
- if (0 == value.Length)
+ string value = instance.Trim(EndOfServerInstanceDelimiter_Native); // MDAC 91934
+ if (value.Length == 0)
{
continue;
}
- foreach (string instance2 in value.Split(SqlDataSourceEnumeratorUtil.InstanceKeysDelimiter))
+ foreach (string instance2 in value.Split(InstanceKeysDelimiter))
{
if (serverName == null)
{
- foreach (string instance3 in instance2.Split(SqlDataSourceEnumeratorUtil.ServerNamesAndInstanceDelimiter))
+ foreach (string instance3 in instance2.Split(ServerNamesAndInstanceDelimiter))
{
if (serverName == null)
{
serverName = instance3;
continue;
}
- Debug.Assert(instanceName == null);
+ Debug.Assert(instanceName == null, $"{nameof(instanceName)}({instanceName}) is not null.");
instanceName = instance3;
}
continue;
}
if (isClustered == null)
{
- Debug.Assert(string.Compare(SqlDataSourceEnumeratorUtil.s_cluster, 0, instance2, 0, SqlDataSourceEnumeratorUtil.s_clusterLength, StringComparison.OrdinalIgnoreCase) == 0);
- isClustered = instance2.Substring(SqlDataSourceEnumeratorUtil.s_clusterLength);
+ Debug.Assert(string.Compare(Clustered, 0, instance2, 0, s_clusteredLength, StringComparison.OrdinalIgnoreCase) == 0,
+ $"{nameof(Clustered)} ({Clustered}) doesn't equal {nameof(instance2)} ({instance2})");
+ isClustered = instance2.Substring(s_clusteredLength);
continue;
}
- Debug.Assert(version == null);
- Debug.Assert(string.Compare(SqlDataSourceEnumeratorUtil.s_version, 0, instance2, 0, SqlDataSourceEnumeratorUtil.s_versionLength, StringComparison.OrdinalIgnoreCase) == 0);
- version = instance2.Substring(SqlDataSourceEnumeratorUtil.s_versionLength);
+ Debug.Assert(version == null, $"{nameof(version)}({version}) is not null.");
+ Debug.Assert(string.Compare(SqlDataSourceEnumeratorUtil.Version, 0, instance2, 0, s_versionLength, StringComparison.OrdinalIgnoreCase) == 0,
+ $"{nameof(SqlDataSourceEnumeratorUtil.Version)} ({SqlDataSourceEnumeratorUtil.Version}) doesn't equal {nameof(instance2)} ({instance2})");
+ version = instance2.Substring(s_versionLength);
}
string query = "ServerName='" + serverName + "'";
@@ -161,11 +173,7 @@ static private System.Data.DataTable ParseServerEnumString(string serverInstance
isClustered = null;
version = null;
}
- foreach (DataColumn column in dataTable.Columns)
- {
- column.ReadOnly = true;
- }
- return dataTable;
+ return dataTable.SetColumnsReadOnly();
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorUtil.cs
index e1179e73fe..fb6972d8cf 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorUtil.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorUtil.cs
@@ -1,21 +1,54 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Data;
+using System.Globalization;
+
namespace Microsoft.Data.Sql
{
///
/// const values for SqlDataSourceEnumerator
///
- internal class SqlDataSourceEnumeratorUtil
+ internal static class SqlDataSourceEnumeratorUtil
{
- internal const string ServerName = "ServerName";
- internal const string InstanceName = "InstanceName";
- internal const string IsClustered = "IsClustered";
- internal const string Version = "Version";
- internal static readonly string s_version = "Version:";
- internal static readonly string s_cluster = "Clustered:";
- internal static readonly int s_clusterLength = s_cluster.Length;
- internal static readonly int s_versionLength = s_version.Length;
- internal const string EndOfServerInstanceDelimiterManaged = ";;";
+ internal const string ServerNameCol = "ServerName";
+ internal const string InstanceNameCol = "InstanceName";
+ internal const string IsClusteredCol = "IsClustered";
+ internal const string VersionNameCol = "Version";
+
+ internal const string Version = "Version:";
+ internal const string Clustered = "Clustered:";
+ internal static readonly int s_versionLength = Version.Length;
+ internal static readonly int s_clusteredLength = Clustered.Length;
+
+ internal static readonly string[] s_endOfServerInstanceDelimiter_Managed = new[] { ";;" };
+ internal const char EndOfServerInstanceDelimiter_Native = '\0';
internal const char InstanceKeysDelimiter = ';';
- internal const string EndOfServerInstanceDelimiterNative = "\0\0\0";
internal const char ServerNamesAndInstanceDelimiter = '\\';
+
+ internal static DataTable PrepareDataTable()
+ {
+ DataTable dataTable = new("SqlDataSources");
+ dataTable.Locale = CultureInfo.InvariantCulture;
+ dataTable.Columns.Add(ServerNameCol, typeof(string));
+ dataTable.Columns.Add(InstanceNameCol, typeof(string));
+ dataTable.Columns.Add(IsClusteredCol, typeof(string));
+ dataTable.Columns.Add(VersionNameCol, typeof(string));
+
+ return dataTable;
+ }
+
+ ///
+ /// Sets all columns read-only.
+ ///
+ internal static DataTable SetColumnsReadOnly(this DataTable dataTable)
+ {
+ foreach (DataColumn column in dataTable.Columns)
+ {
+ column.ReadOnly = true;
+ }
+ return dataTable;
+ }
}
}