using Microsoft.Win32; using Microsoft.Extensions.Logging; namespace CredentialManager.Services; /// /// Informazioni su un DSN ODBC /// public class OdbcDsnInfo { public string Name { get; set; } = string.Empty; public string Driver { get; set; } = string.Empty; public string? Description { get; set; } public bool IsUserDsn { get; set; } // true = User DSN, false = System DSN public Dictionary Properties { get; set; } = new(); } /// /// Interfaccia per il servizio di discovery DSN ODBC /// public interface IOdbcDsnDiscoveryService { /// /// Ottiene tutti i DSN ODBC configurati (sia User che System) /// List GetAllDsn(); /// /// Ottiene solo i DSN utente /// List GetUserDsn(); /// /// Ottiene solo i DSN di sistema /// List GetSystemDsn(); /// /// Ottiene i dettagli di un DSN specifico /// OdbcDsnInfo? GetDsnDetails(string dsnName, bool isUserDsn = true); /// /// Ottiene la lista dei driver ODBC installati /// List GetInstalledDrivers(); } /// /// Servizio per la scoperta e lettura dei DSN ODBC configurati sul sistema /// public class OdbcDsnDiscoveryService : IOdbcDsnDiscoveryService { private readonly ILogger _logger; // Percorsi del registro di Windows per ODBC private const string USER_DSN_PATH = @"SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources"; private const string SYSTEM_DSN_PATH = @"SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources"; private const string USER_DSN_DETAILS_PATH = @"SOFTWARE\ODBC\ODBC.INI\"; private const string SYSTEM_DSN_DETAILS_PATH = @"SOFTWARE\ODBC\ODBC.INI\"; private const string DRIVERS_PATH = @"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"; public OdbcDsnDiscoveryService(ILogger logger) { _logger = logger; } public List GetAllDsn() { var allDsn = new List(); allDsn.AddRange(GetUserDsn()); allDsn.AddRange(GetSystemDsn()); return allDsn; } public List GetUserDsn() { return GetDsnFromRegistry(Registry.CurrentUser, USER_DSN_PATH, USER_DSN_DETAILS_PATH, true); } public List GetSystemDsn() { return GetDsnFromRegistry(Registry.LocalMachine, SYSTEM_DSN_PATH, SYSTEM_DSN_DETAILS_PATH, false); } public OdbcDsnInfo? GetDsnDetails(string dsnName, bool isUserDsn = true) { var allDsn = isUserDsn ? GetUserDsn() : GetSystemDsn(); return allDsn.FirstOrDefault(d => d.Name.Equals(dsnName, StringComparison.OrdinalIgnoreCase)); } public List GetInstalledDrivers() { var drivers = new List(); try { using var key = Registry.LocalMachine.OpenSubKey(DRIVERS_PATH); if (key != null) { foreach (var driverName in key.GetValueNames()) { var value = key.GetValue(driverName)?.ToString(); if (value == "Installed") { drivers.Add(driverName); } } } } catch (Exception ex) { _logger.LogError(ex, "Errore nella lettura dei driver ODBC dal registro"); } return drivers.OrderBy(d => d).ToList(); } private List GetDsnFromRegistry(RegistryKey rootKey, string dsnPath, string detailsPath, bool isUserDsn) { var dsnList = new List(); try { using var dsnKey = rootKey.OpenSubKey(dsnPath); if (dsnKey == null) { _logger.LogWarning("Chiave registro ODBC non trovata: {Path}", dsnPath); return dsnList; } foreach (var dsnName in dsnKey.GetValueNames()) { try { var driver = dsnKey.GetValue(dsnName)?.ToString(); if (string.IsNullOrEmpty(driver)) continue; var dsnInfo = new OdbcDsnInfo { Name = dsnName, Driver = driver, IsUserDsn = isUserDsn }; // Leggi i dettagli del DSN using var detailKey = rootKey.OpenSubKey(detailsPath + dsnName); if (detailKey != null) { foreach (var valueName in detailKey.GetValueNames()) { var value = detailKey.GetValue(valueName)?.ToString(); if (!string.IsNullOrEmpty(value)) { dsnInfo.Properties[valueName] = value; // Popola proprietà comuni if (valueName.Equals("Description", StringComparison.OrdinalIgnoreCase)) dsnInfo.Description = value; } } } dsnList.Add(dsnInfo); _logger.LogDebug("DSN trovato: {Name} ({Driver}) - Type: {Type}", dsnName, driver, isUserDsn ? "User" : "System"); } catch (Exception ex) { _logger.LogWarning(ex, "Errore nella lettura del DSN: {DsnName}", dsnName); } } } catch (Exception ex) { _logger.LogError(ex, "Errore nella lettura dei DSN ODBC dal registro"); } return dsnList; } }