Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified SQLCheck/.vs/SQLCheck/v15/Server/sqlite3/storage.ide
Binary file not shown.
204 changes: 108 additions & 96 deletions SQLCheck/SQLCheck/Collectors.cs

Large diffs are not rendered by default.

197 changes: 177 additions & 20 deletions SQLCheck/SQLCheck/DriverInfo.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Diagnostics;
using System.Data;
using System.Data.OleDb;
using Microsoft.Win32;

namespace SQLCheck
{
Expand Down Expand Up @@ -213,26 +216,180 @@ public static string[] GetOLEDBNames()
"MSOLEDBSQL19"};
}

public static string[] GetExtendedOLEDBNames()
//public static string[] GetExtendedOLEDBNames()
//{
// return new string[] {"SQLOLEDB",
// "SQLNCLI",
// "SQLNCLI10",
// "SQLNCLI11",
// "MSOLEDBSQL",
// "MSOLEDBSQL19",
// "Microsoft.ACE.OLEDB.10.0", // supported by Office (Access)
// "Microsoft.ACE.OLEDB.12.0", // supported by Office (Access)
// "Microsoft.ACE.OLEDB.16.0", // supported by Office (Access)
// "MSOLAP", // supported by Analysis Services (SSAS)
// "ADSDSOObject", // supported by Active Directory
// "Sybase.ASEOLEDBProvider", // supported by Sybase
// "MySQLProv", // supported by MySQL
// "Ifxoledbc", // supported by IBM/Informix
// "IBMDA400", // supported by IBM AS/400 DB/2 database
// "IBMDADB2", // supported by IBM DB/2 database
// "DB2OLEDB", // supported by Microsoft Host Integration Services (HIS)
// "OraOLEDB.Oracle"}; // supported by Oracle
//}

public static DataTable GetExtendedOLEDBNames(bool is64bit)
{
return new string[] {"SQLOLEDB",
"SQLNCLI",
"SQLNCLI10",
"SQLNCLI11",
"MSOLEDBSQL",
"MSOLEDBSQL19",
"Microsoft.ACE.OLEDB.10.0", // supported by Office (Access)
"Microsoft.ACE.OLEDB.12.0", // supported by Office (Access)
"Microsoft.ACE.OLEDB.16.0", // supported by Office (Access)
"MSOLAP", // supported by Analysis Services (SSAS)
"ADSDSOObject", // supported by Active Directory
"Sybase.ASEOLEDBProvider", // supported by Sybase
"MySQLProv", // supported by MySQL
"Ifxoledbc", // supported by IBM/Informix
"IBMDA400", // supported by IBM AS/400 DB/2 database
"IBMDADB2", // supported by IBM DB/2 database
"DB2OLEDB", // supported by Microsoft Host Integration Services (HIS)
"OraOLEDB.Oracle"}; // supported by Oracle
String[] MSFT_SQL_Providers = GetOLEDBNames();

// fill the list with unordered provider information
DataTable dtProviders = new DataTable("Unordered Providers");
dtProviders = GetOLEDBProvidersTable(); // 32-bit or 64-bit registry scan depending on OS architecture
if (is64bit) dtProviders.Merge(GetOLEDBProvidersTable(true)); // 32-bit registry scan

DataTable dt = new DataTable("EnumeratedProviders");
dt.AddColumn("ProgID", "String");
dt.AddColumn("CLSID", "String");
dt.AddColumn("Path", "String");
dt.AddColumn("Description", "String");

// Add the data for the Microsoft Providers for SQL Server

DataView dv = new DataView(dtProviders);
foreach (string ProgID in MSFT_SQL_Providers)
{
dv.RowFilter = $"ProgID='{ProgID}'";
dv.Sort = "ProgID,Path"; // keep the 64-bit and 32-bit ProgIDs together
foreach (DataRowView drv in dv) // the providers in our list have only 1 version each as they are side-by-side with different PROGID names, unlike MSOLAP
{
DataRow row = dt.NewRow();
row["ProgID"] = drv["ProgID"];
row["CLSID"] = drv["GUID"];
row["Path"] = drv["Path"];
row["Description"] = drv["Description"];
dt.Rows.Add(row);
dv[0].Row.Delete(); // removes the row from future consideration
}
}

// add Providers that are not on the list in alphabetical order
dv.RowFilter = "";
dv.Sort = "ProgID,Path";
foreach (DataRowView drv in dv)
{
DataRow row = dt.NewRow();
row["ProgID"] = drv["ProgID"];
row["CLSID"] = drv["GUID"];
row["Path"] = drv["Path"];
row["Description"] = drv["Description"];
dt.Rows.Add(row);
}

return dt;
}

// this is based on they way MSDAENUM.GetRootEnumerator works
public static DataTable GetOLEDBProvidersTable(bool WowMode = false)
{
DataTable dt = new DataTable();
dt.AddColumn("ProgID", "String");
dt.AddColumn("GUID", "String");
dt.AddColumn("Path", "String");
dt.AddColumn("Description", "String");

RegistryKey hive = null;
RegistryKey key = null;
RegistryKey subKey = null;
RegistryKey inProc32Key = null;
RegistryKey OLEDBProviderKey = null;
RegistryKey ProgIDKey = null;
string RegistryPath = (WowMode ? @"WOW6432Node\CLSID" : "CLSID");

try
{
// open the CLSID registry key for enumeration
hive = Registry.ClassesRoot;
key = hive.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.ReadPermissions |
System.Security.AccessControl.RegistryRights.ReadKey |
System.Security.AccessControl.RegistryRights.EnumerateSubKeys |
System.Security.AccessControl.RegistryRights.QueryValues);
if (key is null) throw new InvalidOperationException($@"Registry key {RegistryPath} could not be opened.");

// enumerate all the GUID sub keys
string[] subKeyNames = key.GetSubKeyNames();
foreach (string subKeyName in subKeyNames)
{
try
{
subKey = key.OpenSubKey(subKeyName, RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.ReadPermissions |
System.Security.AccessControl.RegistryRights.ReadKey |
System.Security.AccessControl.RegistryRights.EnumerateSubKeys |
System.Security.AccessControl.RegistryRights.QueryValues);
if (subKey != null) // ignore keys we cannot open
{
inProc32Key = subKey.OpenSubKey("InprocServer32", RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.ReadPermissions |
System.Security.AccessControl.RegistryRights.ReadKey |
System.Security.AccessControl.RegistryRights.EnumerateSubKeys |
System.Security.AccessControl.RegistryRights.QueryValues);
if (inProc32Key == null) continue;

OLEDBProviderKey = subKey.OpenSubKey("OLE DB Provider", RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.ReadPermissions |
System.Security.AccessControl.RegistryRights.ReadKey |
System.Security.AccessControl.RegistryRights.EnumerateSubKeys |
System.Security.AccessControl.RegistryRights.QueryValues);
if (OLEDBProviderKey == null) continue;

ProgIDKey = subKey.OpenSubKey("ProgID", RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.ReadPermissions |
System.Security.AccessControl.RegistryRights.ReadKey |
System.Security.AccessControl.RegistryRights.EnumerateSubKeys |
System.Security.AccessControl.RegistryRights.QueryValues);
if (ProgIDKey == null) continue;

// all the subkeys exist - add values to the DataTable

string inProc32 = inProc32Key.GetValue(null, "").ToString(); // null -> default value
string description = OLEDBProviderKey.GetValue(null, "").ToString(); // null -> default value
string ProgID = ProgIDKey.GetValue(null, "").ToString(); // null -> default value

if (ProgID.EndsWith(".1")) ProgID = ProgID.Substring(0, ProgID.Length - 2); // trim .1 but not other values; may have multiple drivers with the same ProgID

DataRow row = dt.NewRow();

row["ProgID"] = ProgID;
row["Description"] = description;
row["GUID"] = SmartString.GetBetween(subKey.Name, "{", "}"); // between { }
row["Path"] = inProc32;

dt.Rows.Add(row);
}
}
finally
{
if (inProc32Key != null) inProc32Key.Dispose();
if (OLEDBProviderKey != null) OLEDBProviderKey.Dispose();
if (ProgIDKey != null) ProgIDKey.Dispose();
if (subKey != null) subKey.Dispose();
}
}

key.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine($"An exception happened opening a GUID subkey under {RegistryPath}. {ex.Message}");
}
finally
{
if (key != null) key.Dispose();
if (hive != null) hive.Dispose();
}

return dt;
}

public static string[] GetODBCNames()
Expand All @@ -247,4 +404,4 @@ public static string[] GetODBCNames()
"ODBC Driver 18 for SQL Server"};
}
}
}
}
6 changes: 3 additions & 3 deletions SQLCheck/SQLCheck/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft Corporation - SQL Server Customer Support")]
[assembly: AssemblyProduct("SQLCheck")]
[assembly: AssemblyCopyright("Copyright © 2021, 2022, 2023")]
[assembly: AssemblyCopyright("Copyright © 2021, 2022, 2023, 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1310.0")]
[assembly: AssemblyFileVersion("1.0.1310.0")]
[assembly: AssemblyVersion("1.0.1409.0")]
[assembly: AssemblyFileVersion("1.0.1409.0")]
1 change: 1 addition & 0 deletions SQLCheck/SQLCheck/Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ public static DataSet CreateDataSet(String ComputerName)
dt.Columns["ID"].AutoIncrement = true;
dt.AddColumn("ParentID", "Integer");
dt.AddColumn("DriverName", "String");
dt.AddColumn("Description", "String");
dt.AddColumn("DriverType", "String");
dt.AddColumn("Guid", "String");
dt.AddColumn("Path", "String");
Expand Down
8 changes: 5 additions & 3 deletions SQLCheck/SQLCheck/TextReport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static void Report(DataSet ds, TextWriter s)
static void ReportHeading(DataSet ds, TextWriter s)
{
DataRow Computer = ds.Tables["Computer"].Rows[0];
s.WriteLine($"SQL Server Connectivity Check v{Program.version}, run on {DateTime.Now.ToString(@"MM/dd/yyyy hh:mm:ss tt")}");
s.WriteLine($"SQL Server Connectivity Check v{Program.version}, run on {DateTime.Now.ToString(@"MM/dd/yyyy hh:mm:ss tt")} {Utility.GetTimeZoneOffsetAndName(DateTime.Now)}");
s.WriteLine("by the Microsoft CSS SQL Networking Team");
s.WriteLine();
s.WriteLine("This report contains the following sections:");
Expand Down Expand Up @@ -720,12 +720,13 @@ static void ReportDatabaseDriver(DataSet ds, TextWriter s) // outputs computer
DataTable dtDatabaseDriver = ds.Tables["DatabaseDriver"];
ReportFormatter rf = new ReportFormatter();

rf.SetColumnNames("Name:L", "Type:L", "Version:L", "Supported:L", "TLS 1.2:L", "TLS 1.3:L", "MSF:L", "GUID:L", "Path:L", "Message:L");
rf.SetColumnNames("Name:L", "Description:L", "Type:L", "Version:L", "Supported:L", "TLS 1.2:L", "TLS 1.3:L", "MSF:L", "CLSID:L", "Path:L", "Message:L");
foreach (DataRow DatabaseDriver in dtDatabaseDriver.Rows)
{
if (DatabaseDriver.GetString("Supported") != "") // only SQL drivers and providers have this set
{
rf.SetcolumnData(DatabaseDriver.GetString("DriverName"),
DatabaseDriver.GetString("Description"),
DatabaseDriver.GetString("DriverType"),
DatabaseDriver.GetString("Version"),
DatabaseDriver.GetString("Supported"),
Expand All @@ -748,12 +749,13 @@ static void ReportDatabaseDriver(DataSet ds, TextWriter s) // outputs computer

s.WriteLine("Other OLE DB Providers and ODBC Drivers:");
s.WriteLine();
rf.SetColumnNames("Name:L", "Type:L", "Version:L", "GUID:L", "Path:L", "Message:L");
rf.SetColumnNames("Name:L", "Description:L", "Type:L", "Version:L", "CLSID:L", "Path:L", "Message:L");
foreach (DataRow DatabaseDriver in dtDatabaseDriver.Rows)
{
if (DatabaseDriver.GetString("Supported") == "") // only SQL drivers and providers have this set
{
rf.SetcolumnData(DatabaseDriver.GetString("DriverName"),
DatabaseDriver.GetString("Description"),
DatabaseDriver.GetString("DriverType"),
DatabaseDriver.GetString("Version"),
DatabaseDriver.GetString("Guid"),
Expand Down
12 changes: 12 additions & 0 deletions SQLCheck/SQLCheck/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,18 @@ public static string FormatInterval(TimeSpan ts)
return $"{ts.Days} Days, {ts.Hours} Hours, {ts.Minutes} Minutes";
}

public static string GetTimeZoneOffsetAndName(DateTime theDate)
{
TimeZoneInfo tz = TimeZoneInfo.Local;
if (tz.SupportsDaylightSavingTime)
{
TimeSpan offset = tz.GetUtcOffset(theDate);
string offsetText = "(UTC" + (offset.Hours < 0 ? "-" : "+") + offset.ToString(@"hh\:mm") + ")";
return $"{offsetText} {(tz.IsDaylightSavingTime(theDate) ? tz.DaylightName : tz.StandardName)}";
}
return tz.DisplayName;
}

}

public class StringIgnoreCaseComparer : System.Collections.Generic.IEqualityComparer<String>
Expand Down
6 changes: 4 additions & 2 deletions SQLTrace/SQLTrace.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ LogRaw "
/_______ /\_____\ \_/|_______ \|____| |__| (____ / \___ >\___ >
\/ \__> \/ \/ \/ \/

SQLTrace.ps1 version 1.0.0211.0
SQLTrace.ps1 version 1.0.0217.0
by the Microsoft SQL Server Networking Team
"

Expand Down Expand Up @@ -408,6 +408,7 @@ Function StartTraces

tasklist > "$($global:LogFolderName)\TasklistAtStart.txt"
netstat -abon > "$($global:LogFolderName)\NetStatAtStart.txt"
ipconfig -all > "$($global:LogFolderName)\IPCONFIG.txt"
StartBIDTraces
StartNetworkTraces
StartAuthenticationTraces
Expand Down Expand Up @@ -536,6 +537,7 @@ Function GETBIDTraceGuid($bidProvider)
"MSODBCSQL11" { return "{7C360F7F-7102-250A-A233-F9BEBB9875C2} 0x630ff 0 MSODBCSQL11.1 "}
"MSODBCSQL13" { return "{85DC6E48-9394-F805-45C9-C8B2ACA2E7FE} 0x630ff 0 MSODBCSQL13.1 "}
"MSODBCSQL17" { return "{053A11C4-BC2B-F7CE-4A10-9D2602643DA0} 0x630ff 0 MSODBCSQL17.1 "}
"MSODBCSQL18" { return "{1a1283ad-c65d-28ef-d729-39794ffdab32} 0x630ff 0 MSODBCSQL18.1 "}
"System.Data" { return "{914ABDE2-171E-C600-3348-C514171DE148} 0x630ff 0 System.Data.1 "}
"System.Data.OracleClient" { return "{DCD90923-4953-20C2-8708-01976FB15287} 0x630ff 0 System.Data.OracleClient.1 "}
"System.Data.SNI" { return "{C9996FA5-C06F-F20C-8A20-69B3BA392315} 0x630ff 0 System.Data.SNI.1 "}
Expand Down Expand Up @@ -1186,7 +1188,7 @@ Function CopySQLErrorLog()
mkdir $ValueName | out-null
$instanceFolderName = $SQLKey.GetValue($ValueName); #Get Instance Folder Name
$errorLogPath = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceFolderName\MSSQLServer\Parameters\").psobject.properties |
where {$_.name -like "xls*" -or $_.value -like "*ERRORLOG*"} |
where {$_.value -like "*ERRORLOG*"} |
select value

#Remove any parameter prior to the path
Expand Down
Binary file modified SQL_Network_Analyzer/.vs/SQLNetworkAnalyzer/v15/.suo
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.