diff --git a/src/c#/DrivelutionTest/GeneralDrivelutionTests.cs b/src/c#/DrivelutionTest/GeneralDrivelutionTests.cs
index cd22a06d..87973a42 100644
--- a/src/c#/DrivelutionTest/GeneralDrivelutionTests.cs
+++ b/src/c#/DrivelutionTest/GeneralDrivelutionTests.cs
@@ -327,4 +327,185 @@ public void GetPlatformInfo_ReportsCorrectSupportStatus()
Assert.False(platformInfo.IsSupported); // MacOS not yet implemented
}
}
+
+ ///
+ /// Tests that GetDriversFromDirectoryAsync returns empty list for non-existent directory.
+ ///
+ [Fact]
+ public async Task GetDriversFromDirectoryAsync_WithNonExistentDirectory_ReturnsEmptyList()
+ {
+ // Arrange
+ var nonExistentPath = Path.Combine(Path.GetTempPath(), $"nonexistent_{Guid.NewGuid()}");
+
+ // Act
+ var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(nonExistentPath);
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.Empty(result);
+ }
+
+ ///
+ /// Tests that GetDriversFromDirectoryAsync returns empty list for empty directory.
+ ///
+ [Fact]
+ public async Task GetDriversFromDirectoryAsync_WithEmptyDirectory_ReturnsEmptyList()
+ {
+ // Arrange
+ var emptyDir = Path.Combine(Path.GetTempPath(), $"empty_{Guid.NewGuid()}");
+ Directory.CreateDirectory(emptyDir);
+
+ try
+ {
+ // Act
+ var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(emptyDir);
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.Empty(result);
+ }
+ finally
+ {
+ if (Directory.Exists(emptyDir))
+ {
+ Directory.Delete(emptyDir, true);
+ }
+ }
+ }
+
+ ///
+ /// Tests that GetDriversFromDirectoryAsync discovers driver files in directory.
+ ///
+ [Fact]
+ public async Task GetDriversFromDirectoryAsync_WithDriverFiles_ReturnsDriverInfoList()
+ {
+ // Arrange
+ var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
+ Directory.CreateDirectory(testDir);
+
+ try
+ {
+ // Create test driver files based on platform
+ var platformInfo = GeneralDrivelution.GetPlatformInfo();
+ var testFiles = new List();
+
+ if (platformInfo.Platform == "Windows")
+ {
+ // Create mock .inf file
+ var infFile = Path.Combine(testDir, "test_driver.inf");
+ File.WriteAllText(infFile, @"
+[Version]
+Signature=""$Windows NT$""
+DriverVer=01/15/2024,1.0.0.0
+
+[DriverInfo]
+DriverDesc=""Test Driver""
+");
+ testFiles.Add(infFile);
+ }
+ else if (platformInfo.Platform == "Linux")
+ {
+ // Create mock .ko file
+ var koFile = Path.Combine(testDir, "test_driver.ko");
+ File.WriteAllText(koFile, "Mock kernel module content");
+ testFiles.Add(koFile);
+ }
+
+ // Act
+ var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir);
+
+ // Assert
+ Assert.NotNull(result);
+
+ // Should find at least one driver if platform is supported
+ if (platformInfo.IsSupported && testFiles.Any())
+ {
+ Assert.NotEmpty(result);
+
+ // Check that driver info has expected properties
+ var driver = result.First();
+ Assert.NotNull(driver.Name);
+ Assert.NotEmpty(driver.Name);
+ Assert.NotNull(driver.FilePath);
+ Assert.NotEmpty(driver.FilePath);
+ Assert.NotNull(driver.Version);
+ Assert.NotEmpty(driver.Version);
+ Assert.NotNull(driver.Hash);
+ Assert.NotEmpty(driver.Hash);
+ }
+ }
+ finally
+ {
+ if (Directory.Exists(testDir))
+ {
+ Directory.Delete(testDir, true);
+ }
+ }
+ }
+
+ ///
+ /// Tests that GetDriversFromDirectoryAsync with search pattern filters correctly.
+ ///
+ [Fact]
+ public async Task GetDriversFromDirectoryAsync_WithSearchPattern_FiltersCorrectly()
+ {
+ // Arrange
+ var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
+ Directory.CreateDirectory(testDir);
+
+ try
+ {
+ // Create different types of files
+ var infFile = Path.Combine(testDir, "driver1.inf");
+ var txtFile = Path.Combine(testDir, "readme.txt");
+ File.WriteAllText(infFile, "INF content");
+ File.WriteAllText(txtFile, "Text content");
+
+ // Act
+ var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir, "*.inf");
+
+ // Assert
+ Assert.NotNull(result);
+
+ // Should only find .inf files
+ // The count depends on whether the platform supports parsing .inf files
+ }
+ finally
+ {
+ if (Directory.Exists(testDir))
+ {
+ Directory.Delete(testDir, true);
+ }
+ }
+ }
+
+ ///
+ /// Tests that GetDriversFromDirectoryAsync handles cancellation.
+ ///
+ [Fact]
+ public async Task GetDriversFromDirectoryAsync_WithCancellation_HandlesCancellation()
+ {
+ // Arrange
+ var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
+ Directory.CreateDirectory(testDir);
+
+ try
+ {
+ var cts = new CancellationTokenSource();
+ cts.Cancel();
+
+ // Act
+ var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir, null, cts.Token);
+
+ // Assert - Should complete without throwing or return empty list
+ Assert.NotNull(result);
+ }
+ finally
+ {
+ if (Directory.Exists(testDir))
+ {
+ Directory.Delete(testDir, true);
+ }
+ }
+ }
}
diff --git a/src/c#/GeneralUpdate.Drivelution/Abstractions/IGeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/Abstractions/IGeneralDrivelution.cs
index e43aa145..093e0360 100644
--- a/src/c#/GeneralUpdate.Drivelution/Abstractions/IGeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/Abstractions/IGeneralDrivelution.cs
@@ -4,19 +4,17 @@
namespace GeneralUpdate.Drivelution.Abstractions;
///
-/// 驱动更新器核心接口
/// Core interface for driver updater
///
public interface IGeneralDrivelution
{
///
- /// 异步更新驱动
/// Updates driver asynchronously
///
- /// 驱动信息 / Driver information
- /// 更新策略 / Update strategy
- /// 取消令牌 / Cancellation token
- /// 更新结果 / Update result
+ /// Driver information
+ /// Update strategy
+ /// Cancellation token
+ /// Update result
///
/// Note: Update process may include signature validation that requires reflection on some platforms.
///
@@ -25,12 +23,11 @@ public interface IGeneralDrivelution
Task UpdateAsync(DriverInfo driverInfo, UpdateStrategy strategy, CancellationToken cancellationToken = default);
///
- /// 异步验证驱动
/// Validates driver asynchronously
///
- /// 驱动信息 / Driver information
- /// 取消令牌 / Cancellation token
- /// 验证是否通过 / Validation result
+ /// Driver information
+ /// Cancellation token
+ /// Validation result
///
/// Note: Includes signature validation that may require reflection on some platforms.
///
@@ -39,21 +36,28 @@ public interface IGeneralDrivelution
Task ValidateAsync(DriverInfo driverInfo, CancellationToken cancellationToken = default);
///
- /// 异步备份驱动
/// Backs up driver asynchronously
///
- /// 驱动信息 / Driver information
- /// 备份路径 / Backup path
- /// 取消令牌 / Cancellation token
- /// 备份结果 / Backup result
+ /// Driver information
+ /// Backup path
+ /// Cancellation token
+ /// Backup result
Task BackupAsync(DriverInfo driverInfo, string backupPath, CancellationToken cancellationToken = default);
///
- /// 异步回滚驱动
/// Rolls back driver asynchronously
///
- /// 备份路径 / Backup path
- /// 取消令牌 / Cancellation token
- /// 回滚结果 / Rollback result
+ /// Backup path
+ /// Cancellation token
+ /// Rollback result
Task RollbackAsync(string backupPath, CancellationToken cancellationToken = default);
+
+ ///
+ /// Reads driver information from local directory
+ ///
+ /// Directory path
+ /// Search pattern (optional, e.g., "*.inf", "*.ko")
+ /// Cancellation token
+ /// List of driver information
+ Task> GetDriversFromDirectoryAsync(string directoryPath, string? searchPattern = null, CancellationToken cancellationToken = default);
}
diff --git a/src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs
index fd2dd2df..bcdb417b 100644
--- a/src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs
@@ -8,18 +8,15 @@
namespace GeneralUpdate.Drivelution;
///
-/// 驱动更新器统一入口类 - 提供优雅的API,自动适配平台
/// Unified driver updater entry point - Provides elegant API with automatic platform adaptation
///
///
-/// 使用示例 / Usage example:
+/// Usage example:
///
-/// // 简单使用 - 自动检测平台
/// // Simple usage - automatic platform detection
/// var updater = GeneralDrivelution.Create();
/// var result = await updater.UpdateAsync(driverInfo, strategy);
///
-/// // 带配置使用
/// // With configuration
/// var options = new DrivelutionOptions { LogLevel = "Info" };
/// var updater = GeneralDrivelution.Create(options);
@@ -29,12 +26,11 @@ namespace GeneralUpdate.Drivelution;
public static class GeneralDrivelution
{
///
- /// 创建驱动更新器实例(自动检测当前平台)
/// Creates a driver updater instance (automatically detects current platform)
///
- /// 配置选项(可选)/ Configuration options (optional)
- /// 适配当前平台的驱动更新器 / Platform-adapted driver updater
- /// 当前平台不支持时抛出 / Thrown when platform is not supported
+ /// Configuration options (optional)
+ /// Platform-adapted driver updater
+ /// Thrown when platform is not supported
public static IGeneralDrivelution Create(DrivelutionOptions? options = null)
{
var logger = options != null
@@ -45,24 +41,22 @@ public static IGeneralDrivelution Create(DrivelutionOptions? options = null)
}
///
- /// 创建驱动更新器实例(使用自定义日志记录器)
/// Creates a driver updater instance (with custom logger)
///
- /// 自定义日志记录器 / Custom logger
- /// 配置选项(可选)/ Configuration options (optional)
- /// 适配当前平台的驱动更新器 / Platform-adapted driver updater
+ /// Custom logger
+ /// Configuration options (optional)
+ /// Platform-adapted driver updater
public static IGeneralDrivelution Create(ILogger logger, DrivelutionOptions? options = null)
{
return Core.DrivelutionFactory.Create(logger, options);
}
///
- /// 快速更新驱动(使用默认配置)
/// Quick driver update (with default configuration)
///
- /// 驱动信息 / Driver information
- /// 取消令牌 / Cancellation token
- /// 更新结果 / Update result
+ /// Driver information
+ /// Cancellation token
+ /// Update result
public static async Task QuickUpdateAsync(
DriverInfo driverInfo,
CancellationToken cancellationToken = default)
@@ -79,13 +73,12 @@ public static async Task QuickUpdateAsync(
}
///
- /// 快速更新驱动(带自定义策略)
/// Quick driver update (with custom strategy)
///
- /// 驱动信息 / Driver information
- /// 更新策略 / Update strategy
- /// 取消令牌 / Cancellation token
- /// 更新结果 / Update result
+ /// Driver information
+ /// Update strategy
+ /// Cancellation token
+ /// Update result
public static async Task QuickUpdateAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
@@ -96,12 +89,11 @@ public static async Task QuickUpdateAsync(
}
///
- /// 验证驱动文件(自动选择平台验证器)
/// Validates driver file (automatically selects platform validator)
///
- /// 驱动信息 / Driver information
- /// 取消令牌 / Cancellation token
- /// 是否验证通过 / Whether validation passed
+ /// Driver information
+ /// Cancellation token
+ /// Whether validation passed
public static async Task ValidateAsync(
DriverInfo driverInfo,
CancellationToken cancellationToken = default)
@@ -111,10 +103,9 @@ public static async Task ValidateAsync(
}
///
- /// 获取当前平台信息
/// Gets current platform information
///
- /// 平台信息 / Platform information
+ /// Platform information
public static PlatformInfo GetPlatformInfo()
{
return new PlatformInfo
@@ -126,31 +117,45 @@ public static PlatformInfo GetPlatformInfo()
SystemVersion = CompatibilityChecker.GetSystemVersion()
};
}
+
+ ///
+ /// Reads driver information from local directory
+ ///
+ /// Directory path
+ /// Search pattern (optional, e.g., "*.inf", "*.ko")
+ /// Cancellation token
+ /// List of driver information
+ public static async Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
+ {
+ var updater = Create();
+ return await updater.GetDriversFromDirectoryAsync(directoryPath, searchPattern, cancellationToken);
+ }
}
///
-/// 平台信息
/// Platform information
///
public class PlatformInfo
{
- /// 平台名称 / Platform name
+ /// Platform name
public string Platform { get; set; } = string.Empty;
- /// 是否支持 / Is supported
+ /// Is supported
public bool IsSupported { get; set; }
- /// 操作系统 / Operating system
+ /// Operating system
public string OperatingSystem { get; set; } = string.Empty;
- /// 系统架构 / Architecture
+ /// Architecture
public string Architecture { get; set; } = string.Empty;
- /// 系统版本 / System version
+ /// System version
public string SystemVersion { get; set; } = string.Empty;
///
- /// 返回平台信息的字符串表示
/// Returns string representation of platform information
///
public override string ToString()
diff --git a/src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs
index 710df524..fa6f5058 100644
--- a/src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs
@@ -359,4 +359,243 @@ private string GenerateBackupPath(DriverInfo driverInfo, string baseBackupPath)
var fileName = Path.GetFileName(driverInfo.FilePath);
return Path.Combine(baseBackupPath, fileName);
}
+
+ ///
+ public async Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
+ {
+ var driverInfoList = new List();
+
+ try
+ {
+ _logger.Information("Reading driver information from directory: {DirectoryPath}", directoryPath);
+
+ if (!Directory.Exists(directoryPath))
+ {
+ _logger.Warning("Directory not found: {DirectoryPath}", directoryPath);
+ return driverInfoList;
+ }
+
+ // Default to kernel modules for Linux
+ var pattern = searchPattern ?? "*.ko";
+ var driverFiles = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
+
+ // Also look for .deb and .rpm packages if no specific pattern was provided
+ if (searchPattern == null)
+ {
+ var debFiles = Directory.GetFiles(directoryPath, "*.deb", SearchOption.AllDirectories);
+ var rpmFiles = Directory.GetFiles(directoryPath, "*.rpm", SearchOption.AllDirectories);
+ driverFiles = driverFiles.Concat(debFiles).Concat(rpmFiles).ToArray();
+ }
+
+ _logger.Information("Found {Count} driver files matching pattern: {Pattern}", driverFiles.Length, pattern);
+
+ foreach (var filePath in driverFiles)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ break;
+
+ try
+ {
+ var driverInfo = await ParseDriverFileAsync(filePath, cancellationToken);
+ if (driverInfo != null)
+ {
+ driverInfoList.Add(driverInfo);
+ _logger.Information("Parsed driver: {DriverName} v{Version}", driverInfo.Name, driverInfo.Version);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
+ }
+ }
+
+ _logger.Information("Successfully loaded {Count} driver(s) from directory", driverInfoList.Count);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex, "Error reading drivers from directory: {DirectoryPath}", directoryPath);
+ }
+
+ return driverInfoList;
+ }
+
+ ///
+ /// Parses driver file information
+ ///
+ private async Task ParseDriverFileAsync(string filePath, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var fileInfo = new FileInfo(filePath);
+ var fileName = Path.GetFileNameWithoutExtension(filePath);
+ var extension = Path.GetExtension(filePath).ToLowerInvariant();
+
+ var driverInfo = new DriverInfo
+ {
+ Name = fileName,
+ FilePath = filePath,
+ TargetOS = "Linux",
+ Architecture = Environment.Is64BitOperatingSystem ? "x64" : "x86"
+ };
+
+ // Parse based on file type
+ if (extension == ".ko")
+ {
+ await ParseKernelModuleAsync(filePath, driverInfo, cancellationToken);
+ }
+ else if (extension == ".deb")
+ {
+ await ParseDebPackageAsync(filePath, driverInfo, cancellationToken);
+ }
+ else if (extension == ".rpm")
+ {
+ await ParseRpmPackageAsync(filePath, driverInfo, cancellationToken);
+ }
+
+ // Get file hash for integrity validation
+ driverInfo.Hash = await HashValidator.ComputeHashAsync(filePath, "SHA256", cancellationToken);
+ driverInfo.HashAlgorithm = "SHA256";
+
+ return driverInfo;
+ }
+ catch (Exception ex)
+ {
+ _logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
+ return null;
+ }
+ }
+
+ ///
+ /// Parses kernel module
+ ///
+ private async Task ParseKernelModuleAsync(string koPath, DriverInfo driverInfo, CancellationToken cancellationToken)
+ {
+ try
+ {
+ // Try to get module info using modinfo command
+ var output = await ExecuteCommandAsync("modinfo", koPath, cancellationToken);
+ var lines = output.Split('\n');
+
+ foreach (var line in lines)
+ {
+ var trimmedLine = line.Trim();
+
+ if (trimmedLine.StartsWith("version:", StringComparison.OrdinalIgnoreCase))
+ {
+ driverInfo.Version = trimmedLine.Substring(8).Trim();
+ }
+ else if (trimmedLine.StartsWith("description:", StringComparison.OrdinalIgnoreCase))
+ {
+ driverInfo.Description = trimmedLine.Substring(12).Trim();
+ }
+ else if (trimmedLine.StartsWith("alias:", StringComparison.OrdinalIgnoreCase))
+ {
+ var alias = trimmedLine.Substring(6).Trim();
+ if (string.IsNullOrEmpty(driverInfo.HardwareId))
+ {
+ driverInfo.HardwareId = alias;
+ }
+ }
+ }
+
+ if (string.IsNullOrEmpty(driverInfo.Version))
+ {
+ driverInfo.Version = "1.0.0";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Debug(ex, "Could not get module info for: {KoPath}", koPath);
+ driverInfo.Version = "1.0.0";
+ }
+ }
+
+ ///
+ /// Parses Debian package
+ ///
+ private async Task ParseDebPackageAsync(string debPath, DriverInfo driverInfo, CancellationToken cancellationToken)
+ {
+ try
+ {
+ // Try to get package info using dpkg-deb command
+ // Use proper argument passing to avoid injection issues
+ var escapedPath = debPath.Replace("'", "'\\''");
+ var output = await ExecuteCommandAsync("dpkg-deb", $"-I '{escapedPath}'", cancellationToken);
+ var lines = output.Split('\n');
+
+ foreach (var line in lines)
+ {
+ var trimmedLine = line.Trim();
+
+ if (trimmedLine.StartsWith("Version:", StringComparison.OrdinalIgnoreCase))
+ {
+ driverInfo.Version = trimmedLine.Substring(8).Trim();
+ }
+ else if (trimmedLine.StartsWith("Description:", StringComparison.OrdinalIgnoreCase))
+ {
+ driverInfo.Description = trimmedLine.Substring(12).Trim();
+ }
+ }
+
+ if (string.IsNullOrEmpty(driverInfo.Version))
+ {
+ driverInfo.Version = "1.0.0";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Debug(ex, "Could not get package info for: {DebPath}", debPath);
+ driverInfo.Version = "1.0.0";
+ }
+ }
+
+ ///
+ /// Parses RPM package
+ ///
+ private async Task ParseRpmPackageAsync(string rpmPath, DriverInfo driverInfo, CancellationToken cancellationToken)
+ {
+ try
+ {
+ // Try to get package info using rpm command
+ // Use proper argument passing to avoid injection issues
+ var escapedPath = rpmPath.Replace("'", "'\\''");
+ var output = await ExecuteCommandAsync("rpm", $"-qip '{escapedPath}'", cancellationToken);
+ var lines = output.Split('\n');
+
+ foreach (var line in lines)
+ {
+ var trimmedLine = line.Trim();
+
+ if (trimmedLine.StartsWith("Version", StringComparison.OrdinalIgnoreCase))
+ {
+ var parts = trimmedLine.Split(':');
+ if (parts.Length > 1)
+ {
+ driverInfo.Version = parts[1].Trim();
+ }
+ }
+ else if (trimmedLine.StartsWith("Summary", StringComparison.OrdinalIgnoreCase))
+ {
+ var parts = trimmedLine.Split(':');
+ if (parts.Length > 1)
+ {
+ driverInfo.Description = parts[1].Trim();
+ }
+ }
+ }
+
+ if (string.IsNullOrEmpty(driverInfo.Version))
+ {
+ driverInfo.Version = "1.0.0";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Debug(ex, "Could not get package info for: {RpmPath}", rpmPath);
+ driverInfo.Version = "1.0.0";
+ }
+ }
}
diff --git a/src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs
index bf581403..2cfd84a6 100644
--- a/src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs
@@ -65,6 +65,16 @@ public Task RollbackAsync(
throw new PlatformNotSupportedException(
"MacOS driver rollback is not yet implemented.");
}
+
+ ///
+ public Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
+ {
+ throw new PlatformNotSupportedException(
+ "MacOS driver directory reading is not yet implemented.");
+ }
}
///
diff --git a/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
index 0e8ff2be..df7ba8fe 100644
--- a/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
@@ -457,4 +457,198 @@ private string GetSuggestedResolution(ErrorType type)
_ => "Contact support for assistance"
};
}
+
+ ///
+ public async Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
+ {
+ var driverInfoList = new List();
+
+ try
+ {
+ _logger.Information("Reading driver information from directory: {DirectoryPath}", directoryPath);
+
+ if (!Directory.Exists(directoryPath))
+ {
+ _logger.Warning("Directory not found: {DirectoryPath}", directoryPath);
+ return driverInfoList;
+ }
+
+ // Default to .inf files for Windows
+ var pattern = searchPattern ?? "*.inf";
+ var driverFiles = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
+
+ _logger.Information("Found {Count} driver files matching pattern: {Pattern}", driverFiles.Length, pattern);
+
+ foreach (var filePath in driverFiles)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ break;
+
+ try
+ {
+ var driverInfo = await ParseDriverFileAsync(filePath, cancellationToken);
+ if (driverInfo != null)
+ {
+ driverInfoList.Add(driverInfo);
+ _logger.Information("Parsed driver: {DriverName} v{Version}", driverInfo.Name, driverInfo.Version);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
+ }
+ }
+
+ _logger.Information("Successfully loaded {Count} driver(s) from directory", driverInfoList.Count);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex, "Error reading drivers from directory: {DirectoryPath}", directoryPath);
+ }
+
+ return driverInfoList;
+ }
+
+ ///
+ /// Parses driver file information
+ ///
+ private async Task ParseDriverFileAsync(string filePath, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var fileInfo = new FileInfo(filePath);
+ var fileName = Path.GetFileNameWithoutExtension(filePath);
+
+ var driverInfo = new DriverInfo
+ {
+ Name = fileName,
+ FilePath = filePath,
+ TargetOS = "Windows",
+ Architecture = Environment.Is64BitOperatingSystem ? "x64" : "x86"
+ };
+
+ // For .inf files, try to parse version and other metadata
+ if (filePath.EndsWith(".inf", StringComparison.OrdinalIgnoreCase))
+ {
+ await ParseInfFileAsync(filePath, driverInfo, cancellationToken);
+ }
+
+ // Get file hash for integrity validation
+ driverInfo.Hash = await HashValidator.ComputeHashAsync(filePath, "SHA256", cancellationToken);
+ driverInfo.HashAlgorithm = "SHA256";
+
+ // Get signature information if available
+ try
+ {
+ if (WindowsSignatureHelper.IsFileSigned(filePath))
+ {
+ // Try to extract publisher from certificate
+ using var cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(filePath);
+ var subject = cert2.Subject;
+
+ // Extract CN (Common Name) from subject
+ var cnIndex = subject.IndexOf("CN=");
+ if (cnIndex >= 0)
+ {
+ var cnStart = cnIndex + 3;
+ var cnEnd = subject.IndexOf(',', cnStart);
+
+ string publisher;
+ if (cnEnd > cnStart)
+ {
+ publisher = subject.Substring(cnStart, cnEnd - cnStart);
+ }
+ else
+ {
+ // No comma after CN, take the rest of the string
+ publisher = subject.Substring(cnStart);
+ }
+
+ if (!string.IsNullOrEmpty(publisher))
+ {
+ driverInfo.TrustedPublishers.Add(publisher);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Debug(ex, "Could not get signature for file: {FilePath}", filePath);
+ }
+
+ return driverInfo;
+ }
+ catch (Exception ex)
+ {
+ _logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
+ return null;
+ }
+ }
+
+ ///
+ /// Parses INF file
+ ///
+ private async Task ParseInfFileAsync(string infPath, DriverInfo driverInfo, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var content = await File.ReadAllTextAsync(infPath, cancellationToken);
+ var lines = content.Split('\n');
+
+ foreach (var line in lines)
+ {
+ var trimmedLine = line.Trim();
+
+ // Parse version
+ if (trimmedLine.StartsWith("DriverVer", StringComparison.OrdinalIgnoreCase))
+ {
+ var parts = trimmedLine.Split('=');
+ if (parts.Length > 1)
+ {
+ var verParts = parts[1].Split(',');
+ if (verParts.Length > 1)
+ {
+ driverInfo.Version = verParts[1].Trim();
+ }
+ if (verParts.Length > 0 && DateTime.TryParse(verParts[0].Trim(), out var releaseDate))
+ {
+ driverInfo.ReleaseDate = releaseDate;
+ }
+ }
+ }
+ // Parse description
+ else if (trimmedLine.StartsWith("DriverDesc", StringComparison.OrdinalIgnoreCase))
+ {
+ var parts = trimmedLine.Split('=');
+ if (parts.Length > 1)
+ {
+ driverInfo.Description = parts[1].Trim().Trim('"', '%');
+ }
+ }
+ // Parse hardware ID
+ else if (trimmedLine.StartsWith("HardwareId", StringComparison.OrdinalIgnoreCase) ||
+ trimmedLine.Contains("HW_ID", StringComparison.OrdinalIgnoreCase))
+ {
+ var parts = trimmedLine.Split('=');
+ if (parts.Length > 1)
+ {
+ driverInfo.HardwareId = parts[1].Trim().Trim('"');
+ }
+ }
+ }
+
+ // If version is still empty, try to infer from filename or use default
+ if (string.IsNullOrEmpty(driverInfo.Version))
+ {
+ driverInfo.Version = "1.0.0";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Debug(ex, "Could not parse INF file: {InfPath}", infPath);
+ }
+ }
}