diff --git a/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs b/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
index bbcdc600..74102c16 100644
--- a/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
+++ b/src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs
@@ -2,331 +2,240 @@
using System.Runtime.Versioning;
using GeneralUpdate.Common.Shared;
using GeneralUpdate.Drivelution.Abstractions;
+using GeneralUpdate.Drivelution.Abstractions.Configuration;
using GeneralUpdate.Drivelution.Abstractions.Exceptions;
using GeneralUpdate.Drivelution.Abstractions.Models;
+using GeneralUpdate.Drivelution.Core.Pipeline;
using GeneralUpdate.Drivelution.Core.Utilities;
using GeneralUpdate.Drivelution.Windows.Helpers;
namespace GeneralUpdate.Drivelution.Windows.Implementation;
///
-/// Windows驱动更新器实现
-/// Windows driver updater implementation
+/// Windows driver updater implementation.
+/// Inherits the unified pipeline from and adds Windows-specific
+/// permission checks, PnPUtil-based installation, and INF file parsing.
///
[SupportedOSPlatform("windows")]
-public class WindowsGeneralDrivelution : IGeneralDrivelution
+public class WindowsGeneralDrivelution : BaseDriverUpdater
{
- private readonly IDriverValidator _validator;
- private readonly IDriverBackup _backup;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Driver validator.
+ /// Driver backup manager.
+ /// Configuration options (optional).
+ public WindowsGeneralDrivelution(
+ IDriverValidator validator,
+ IDriverBackup backup,
+ DrivelutionOptions? options = null)
+ : base(validator, backup, options)
+ {
+ }
+
+ // ─── Pipeline overrides ────────────────────────────────────────────
- public WindowsGeneralDrivelution(IDriverValidator validator, IDriverBackup backup)
+ ///
+ protected override IEnumerable GetPipelineSteps(UpdateStrategy strategy)
{
- _validator = validator ?? throw new ArgumentNullException(nameof(validator));
- _backup = backup ?? throw new ArgumentNullException(nameof(backup));
+ // Prepend Windows permission check before the default pipeline
+ yield return CreatePermissionCheckStep();
+
+ foreach (var step in base.GetPipelineSteps(strategy))
+ yield return step;
}
///
- public async Task UpdateAsync(
+ protected override async Task InstallCoreAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
- CancellationToken cancellationToken = default)
+ CancellationToken cancellationToken)
{
- var result = new UpdateResult
- {
- StartTime = DateTime.UtcNow,
- Status = UpdateStatus.NotStarted
- };
+ GeneralTracer.Info($"Installing Windows driver via PnPUtil: {driverInfo.FilePath}");
+ await InstallDriverUsingPnPUtilAsync(driverInfo.FilePath, cancellationToken);
+ }
+ ///
+ protected override async Task VerifyInstallationAsync(
+ DriverInfo driverInfo,
+ CancellationToken cancellationToken)
+ {
try
{
- GeneralTracer.Info($"Starting driver update for: {driverInfo.Name} v{driverInfo.Version}");
-
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Starting driver update");
+ GeneralTracer.Info($"Verifying Windows driver installation for: {driverInfo.FilePath}");
- // Step 1: Permission check
- GeneralTracer.Info("Checking permissions...");
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Checking permissions");
-
- if (!WindowsPermissionHelper.IsAdministrator())
+ var psi = new ProcessStartInfo
{
- throw new DriverPermissionException(
- "Administrator privileges are required for driver updates. " +
- "Please restart the application as administrator.");
- }
+ FileName = "pnputil.exe",
+ Arguments = "/enum-drivers",
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
- // Step 2: Validation
- result.Status = UpdateStatus.Validating;
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Validating driver");
-
- if (!await ValidateAsync(driverInfo, cancellationToken))
+ using var process = Process.Start(psi);
+ if (process is null)
{
- throw new DriverValidationException(
- "Driver validation failed. Please check the driver file and try again.",
- "General");
+ GeneralTracer.Warn("Failed to start PnPUtil for verification");
+ return false;
}
- // Step 3: Backup (if required)
- if (strategy.RequireBackup)
- {
- result.Status = UpdateStatus.BackingUp;
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Creating backup");
-
- var backupPath = GenerateBackupPath(driverInfo, strategy.BackupPath);
- if (await BackupAsync(driverInfo, backupPath, cancellationToken))
- {
- result.BackupPath = backupPath;
- GeneralTracer.Info($"Backup created at: {backupPath}");
- }
- }
+ var output = await process.StandardOutput.ReadToEndAsync(cancellationToken);
+ await process.WaitForExitAsync(cancellationToken);
- // Step 4: Execute update
- result.Status = UpdateStatus.Updating;
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Installing driver");
-
- await ExecuteDriverInstallationAsync(driverInfo, strategy, cancellationToken);
-
- // Step 5: Verify installation
- result.Status = UpdateStatus.Verifying;
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Verifying installation");
-
- bool verified = await VerifyDriverInstallationAsync(driverInfo, cancellationToken);
- if (!verified)
- {
- GeneralTracer.Warn("Driver installation verification failed");
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] WARNING: Installation verification failed");
- }
- GeneralTracer.Info("Driver installation verification completed");
+ var driverFileName = Path.GetFileName(driverInfo.FilePath);
+ var driverName = Path.GetFileNameWithoutExtension(driverInfo.FilePath);
- // Step 6: Handle restart if needed
- if (RestartHelper.IsRestartRequired(strategy.RestartMode))
- {
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] System restart is required");
- GeneralTracer.Info("System restart is required for driver update");
- }
+ bool isInstalled = output.Contains(driverFileName, StringComparison.OrdinalIgnoreCase)
+ || output.Contains(driverName, StringComparison.OrdinalIgnoreCase);
- result.Success = true;
- result.Status = UpdateStatus.Succeeded;
- result.Message = "Driver update completed successfully";
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Update completed successfully");
-
- GeneralTracer.Info("Driver update completed successfully");
- }
- catch (DriverPermissionException ex)
- {
- GeneralTracer.Error("Permission denied during driver update", ex);
- result.Success = false;
- result.Status = UpdateStatus.Failed;
- result.Error = CreateErrorInfo(ex, ErrorType.PermissionDenied, false);
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
- }
- catch (DriverValidationException ex)
- {
- GeneralTracer.Error("Validation failed during driver update", ex);
- result.Success = false;
- result.Status = UpdateStatus.Failed;
- result.Error = CreateErrorInfo(ex, ErrorType.HashValidationFailed, false);
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
- }
- catch (DriverInstallationException ex)
- {
- GeneralTracer.Error("Installation failed during driver update", ex);
- result.Success = false;
- result.Status = UpdateStatus.Failed;
- result.Error = CreateErrorInfo(ex, ErrorType.InstallationFailed, ex.CanRetry);
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
-
- // Attempt rollback if backup exists
- if (!string.IsNullOrEmpty(result.BackupPath))
- {
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Attempting rollback");
- if (await TryRollbackAsync(result.BackupPath, cancellationToken))
- {
- result.RolledBack = true;
- result.Status = UpdateStatus.RolledBack;
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Rollback completed");
- }
- }
+ GeneralTracer.Info($"Driver verification result: {isInstalled}");
+ return isInstalled;
}
catch (Exception ex)
{
- GeneralTracer.Error("Unexpected error during driver update", ex);
- result.Success = false;
- result.Status = UpdateStatus.Failed;
- result.Error = CreateErrorInfo(ex, ErrorType.Unknown, false);
- result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
- }
- finally
- {
- result.EndTime = DateTime.UtcNow;
- GeneralTracer.Info($"Driver update process ended. Duration: {result.DurationMs}ms, Success: {result.Success}");
+ GeneralTracer.Warn($"Failed to verify driver installation - {ex.Message}");
+ return true; // Non-fatal: don't block the update
}
-
- return result;
}
+ // ─── Rollback override ─────────────────────────────────────────────
+
///
- public async Task ValidateAsync(DriverInfo driverInfo, CancellationToken cancellationToken = default)
+ public override async Task RollbackAsync(
+ string backupPath,
+ CancellationToken cancellationToken = default)
{
- GeneralTracer.Info($"Validating driver: {driverInfo.Name}");
-
try
{
- // Validate file exists
- if (!File.Exists(driverInfo.FilePath))
+ GeneralTracer.Info($"Rolling back Windows driver from backup: {backupPath}");
+
+ if (!Directory.Exists(backupPath))
{
- GeneralTracer.Error($"Driver file not found: {driverInfo.FilePath}");
+ GeneralTracer.Error($"Backup directory not found: {backupPath}");
return false;
}
- // Validate hash if provided and not skipped
- if (!string.IsNullOrEmpty(driverInfo.Hash))
+ var backupFiles = Directory.GetFiles(backupPath, "*.*", SearchOption.AllDirectories);
+ if (backupFiles.Length == 0)
{
- if (!await _validator.ValidateIntegrityAsync(
- driverInfo.FilePath,
- driverInfo.Hash,
- driverInfo.HashAlgorithm,
- cancellationToken))
- {
- return false;
- }
+ GeneralTracer.Warn($"No backup files found in: {backupPath}");
+ return false;
}
- // Validate signature if publishers provided
- if (driverInfo.TrustedPublishers.Any())
+ GeneralTracer.Info($"Found {backupFiles.Length} backup files");
+
+ // Reinstall backed-up INF drivers via PnPUtil
+ foreach (var infFile in backupFiles.Where(
+ f => f.EndsWith(".inf", StringComparison.OrdinalIgnoreCase)))
{
- if (!await _validator.ValidateSignatureAsync(
- driverInfo.FilePath,
- driverInfo.TrustedPublishers,
- cancellationToken))
+ try
{
- return false;
+ GeneralTracer.Info($"Restoring driver from: {infFile}");
+ await InstallDriverUsingPnPUtilAsync(infFile, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Warn($"Failed to restore driver from {infFile}: {ex.Message}");
}
- }
-
- // Validate compatibility
- if (!await _validator.ValidateCompatibilityAsync(driverInfo, cancellationToken))
- {
- return false;
}
return true;
}
catch (Exception ex)
{
- GeneralTracer.Error("Driver validation failed", ex);
- return false;
+ GeneralTracer.Error("Windows driver rollback failed", ex);
+ throw new DriverRollbackException($"Failed to rollback driver: {ex.Message}", ex);
}
}
+ // ─── Driver discovery overrides ────────────────────────────────────
+
///
- public async Task BackupAsync(DriverInfo driverInfo, string backupPath, CancellationToken cancellationToken = default)
- {
- try
- {
- return await _backup.BackupAsync(driverInfo.FilePath, backupPath, cancellationToken);
- }
- catch (Exception ex)
- {
- GeneralTracer.Error("Failed to backup driver", ex);
- return false;
- }
- }
+ protected override string GetDefaultSearchPattern() => "*.inf";
///
- public async Task RollbackAsync(string backupPath, CancellationToken cancellationToken = default)
+ public override async Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
{
+ var drivers = new List();
+
try
{
- GeneralTracer.Info($"Rolling back driver from backup: {backupPath}");
-
- // Implement rollback logic
- // This involves:
- // 1. Restoring from backup
- // 2. Optionally reinstalling the old driver
-
- if (!Directory.Exists(backupPath))
- {
- GeneralTracer.Error($"Backup directory not found: {backupPath}");
- return false;
- }
+ GeneralTracer.Info($"Reading Windows drivers from directory: {directoryPath}");
- // Find the backed up driver files
- var backupFiles = Directory.GetFiles(backupPath, "*.*", SearchOption.AllDirectories);
- if (!backupFiles.Any())
+ if (!Directory.Exists(directoryPath))
{
- GeneralTracer.Warn($"No backup files found in: {backupPath}");
- return false;
+ GeneralTracer.Warn($"Directory not found: {directoryPath}");
+ return drivers;
}
- GeneralTracer.Info($"Found {backupFiles.Length} backup files");
-
- // For INF-based drivers, try to reinstall the backed up version
- var infFiles = backupFiles.Where(f => f.EndsWith(".inf", StringComparison.OrdinalIgnoreCase)).ToArray();
-
- if (infFiles.Any())
+ var pattern = searchPattern ?? "*.inf";
+ var files = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
+
+ foreach (var filePath in files)
{
- foreach (var infFile in infFiles)
+ if (cancellationToken.IsCancellationRequested)
+ break;
+
+ try
{
- try
- {
- GeneralTracer.Info($"Attempting to restore driver from: {infFile}");
- await InstallDriverUsingPnPUtilAsync(infFile, cancellationToken);
- }
- catch (Exception ex)
- {
- GeneralTracer.Warn($"Failed to restore driver from: {infFile} - {ex.Message}");
- }
+ var info = await ParseWindowsDriverFileAsync(filePath, cancellationToken);
+ if (info is not null)
+ drivers.Add(info);
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Warn($"Failed to parse driver file: {filePath} - {ex.Message}");
}
}
- return true;
+ GeneralTracer.Info($"Loaded {drivers.Count} Windows driver(s) from directory");
}
catch (Exception ex)
{
- GeneralTracer.Error("Failed to rollback driver", ex);
- throw new DriverRollbackException($"Failed to rollback driver: {ex.Message}", ex);
+ GeneralTracer.Error($"Error reading drivers from directory: {directoryPath}", ex);
}
+
+ return drivers;
}
+ // ─── Private helpers ────────────────────────────────────────────────
+
///
- /// 执行驱动安装
- /// Executes driver installation
+ /// Creates a Windows admin-privilege check as the first pipeline step.
///
- private async Task ExecuteDriverInstallationAsync(
- DriverInfo driverInfo,
- UpdateStrategy strategy,
- CancellationToken cancellationToken)
+ private static IPipelineStep CreatePermissionCheckStep()
{
- GeneralTracer.Info($"Executing driver installation: {driverInfo.FilePath}");
+ return new DelegateStep("CheckPermissions",
+ execute: (context, ct) =>
+ {
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Checking Windows administrator privileges");
- try
- {
- // TODO: Implement actual driver installation using SetupDi APIs
- // This is a placeholder that would use Windows Device Manager APIs:
- // - SetupDiGetClassDevs
- // - SetupDiEnumDeviceInfo
- // - UpdateDriverForPlugAndPlayDevices
- // - DiInstallDriver (for .inf files)
-
- // For demonstration, we'll use PnPUtil as a fallback
- await InstallDriverUsingPnPUtilAsync(driverInfo.FilePath, cancellationToken);
- }
- catch (Exception ex)
- {
- GeneralTracer.Error("Driver installation failed", ex);
- throw new DriverInstallationException($"Failed to install driver: {ex.Message}", ex);
- }
+ if (!WindowsPermissionHelper.IsAdministrator())
+ {
+ return Task.FromResult(PipelineResult.Fail(
+ "Administrator privileges are required for driver updates. " +
+ "Please restart the application as administrator."));
+ }
+
+ return Task.FromResult(PipelineResult.Ok());
+ });
}
///
- /// 使用PnPUtil安装驱动
- /// Installs driver using PnPUtil
+ /// Installs a driver using the Windows PnPUtil command-line tool.
///
- private async Task InstallDriverUsingPnPUtilAsync(string driverPath, CancellationToken cancellationToken)
+ private static async Task InstallDriverUsingPnPUtilAsync(
+ string driverPath,
+ CancellationToken cancellationToken)
{
- GeneralTracer.Info($"Installing driver using PnPUtil: {driverPath}");
+ GeneralTracer.Info($"PnPUtil installing: {driverPath}");
- var startInfo = new ProcessStartInfo
+ var psi = new ProcessStartInfo
{
FileName = "pnputil.exe",
Arguments = $"/add-driver \"{driverPath}\" /install",
@@ -336,257 +245,102 @@ private async Task InstallDriverUsingPnPUtilAsync(string driverPath, Cancellatio
RedirectStandardError = true
};
- using var process = new Process { StartInfo = startInfo };
- process.Start();
+ using var process = Process.Start(psi)
+ ?? throw new DriverInstallationException("Failed to start PnPUtil process.");
var output = await process.StandardOutput.ReadToEndAsync(cancellationToken);
var error = await process.StandardError.ReadToEndAsync(cancellationToken);
-
await process.WaitForExitAsync(cancellationToken);
GeneralTracer.Info($"PnPUtil output: {output}");
if (process.ExitCode != 0)
{
- GeneralTracer.Error($"PnPUtil failed with exit code {process.ExitCode}. Error: {error}");
+ GeneralTracer.Error($"PnPUtil failed (exit {process.ExitCode}): {error}");
throw new DriverInstallationException(
$"PnPUtil failed with exit code {process.ExitCode}: {error}");
}
}
///
- /// 验证驱动安装
- /// Verify driver installation
+ /// Parses a Windows driver file (INF) and extracts metadata, hash, and signature info.
///
- private async Task VerifyDriverInstallationAsync(DriverInfo driverInfo, CancellationToken cancellationToken)
+ private async Task ParseWindowsDriverFileAsync(
+ string filePath,
+ CancellationToken cancellationToken)
{
try
{
- GeneralTracer.Info($"Verifying driver installation for: {driverInfo.FilePath}");
-
- // Use PnPUtil to enumerate installed drivers and check if our driver is present
- var processStartInfo = new ProcessStartInfo
+ var driverInfo = new DriverInfo
{
- FileName = "pnputil.exe",
- Arguments = "/enum-drivers",
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- UseShellExecute = false,
- CreateNoWindow = true
+ Name = Path.GetFileNameWithoutExtension(filePath),
+ FilePath = filePath,
+ TargetOS = "Windows",
+ Architecture = Environment.Is64BitOperatingSystem ? "x64" : "x86"
};
- using var process = Process.Start(processStartInfo);
- if (process == null)
- {
- GeneralTracer.Warn("Failed to start PnPUtil for verification");
- return false;
- }
-
- string output = await process.StandardOutput.ReadToEndAsync(cancellationToken);
- await process.WaitForExitAsync(cancellationToken);
-
- // Check if the driver file name appears in the output
- string driverFileName = Path.GetFileName(driverInfo.FilePath);
- bool isInstalled = output.Contains(driverFileName, StringComparison.OrdinalIgnoreCase) ||
- output.Contains(Path.GetFileNameWithoutExtension(driverInfo.FilePath), StringComparison.OrdinalIgnoreCase);
-
- GeneralTracer.Info($"Driver verification result: {isInstalled}");
- return isInstalled;
- }
- catch (Exception ex)
- {
- GeneralTracer.Warn($"Failed to verify driver installation - {ex.Message}");
- // Return true to not block the update if verification fails
- return true;
- }
- }
-
- private string GenerateBackupPath(DriverInfo driverInfo, string baseBackupPath)
- {
- if (string.IsNullOrEmpty(baseBackupPath))
- {
- baseBackupPath = "./DriverBackups";
- }
-
- var fileName = Path.GetFileName(driverInfo.FilePath);
- return Path.Combine(baseBackupPath, fileName);
- }
-
- private async Task TryRollbackAsync(string backupPath, CancellationToken cancellationToken)
- {
- try
- {
- return await RollbackAsync(backupPath, cancellationToken);
- }
- catch (Exception ex)
- {
- GeneralTracer.Error("Rollback failed", ex);
- return false;
- }
- }
-
- private ErrorInfo CreateErrorInfo(Exception ex, ErrorType type, bool canRetry)
- {
- return new ErrorInfo
- {
- Code = ex is DrivelutionException dex ? dex.ErrorCode : "DR_UNKNOWN",
- Type = type,
- Message = ex.Message,
- Details = ex.ToString(),
- StackTrace = ex.StackTrace,
- InnerException = ex.InnerException,
- CanRetry = canRetry,
- SuggestedResolution = GetSuggestedResolution(type)
- };
- }
-
- private string GetSuggestedResolution(ErrorType type)
- {
- return type switch
- {
- ErrorType.PermissionDenied => "Run the application as administrator",
- ErrorType.SignatureValidationFailed => "Ensure the driver is properly signed by a trusted publisher",
- ErrorType.HashValidationFailed => "Re-download the driver file and verify its integrity",
- ErrorType.CompatibilityValidationFailed => "Check if the driver is compatible with your system",
- ErrorType.InstallationFailed => "Check Windows Event Viewer for more details",
- _ => "Contact support for assistance"
- };
- }
-
- ///
- public async Task> GetDriversFromDirectoryAsync(
- string directoryPath,
- string? searchPattern = null,
- CancellationToken cancellationToken = default)
- {
- var driverInfoList = new List();
-
- try
- {
- GeneralTracer.Info($"Reading driver information from directory: {directoryPath}");
-
- if (!Directory.Exists(directoryPath))
+ // Parse INF metadata
+ if (filePath.EndsWith(".inf", StringComparison.OrdinalIgnoreCase))
{
- GeneralTracer.Warn($"Directory not found: {directoryPath}");
- return driverInfoList;
+ await ParseInfFileAsync(filePath, driverInfo, cancellationToken);
}
- // Default to .inf files for Windows
- var pattern = searchPattern ?? "*.inf";
- var driverFiles = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
-
- GeneralTracer.Info($"Found {driverFiles.Length} driver files matching pattern: {pattern}");
+ // Compute file hash
+ driverInfo.Hash = await HashValidator.ComputeHashAsync(filePath, "SHA256", cancellationToken);
+ driverInfo.HashAlgorithm = "SHA256";
- foreach (var filePath in driverFiles)
- {
- if (cancellationToken.IsCancellationRequested)
- break;
+ // Extract signature info
+ ExtractSignatureInfo(filePath, driverInfo);
- try
- {
- var driverInfo = await ParseDriverFileAsync(filePath, cancellationToken);
- if (driverInfo != null)
- {
- driverInfoList.Add(driverInfo);
- GeneralTracer.Info($"Parsed driver: {driverInfo.Name} v{driverInfo.Version}");
- }
- }
- catch (Exception ex)
- {
- GeneralTracer.Warn($"Failed to parse driver file: {filePath} - {ex.Message}");
- }
- }
-
- GeneralTracer.Info($"Successfully loaded {driverInfoList.Count} driver(s) from directory");
+ return driverInfo;
}
catch (Exception ex)
{
- GeneralTracer.Error($"Error reading drivers from directory: {directoryPath}", ex);
+ GeneralTracer.Warn($"Failed to parse driver file: {filePath} - {ex.Message}");
+ return null;
}
-
- return driverInfoList;
}
///
- /// Parses driver file information
+ /// Extracts digital signature / publisher information from a signed Windows driver file.
///
- private async Task ParseDriverFileAsync(string filePath, CancellationToken cancellationToken)
+ private static void ExtractSignatureInfo(string filePath, DriverInfo driverInfo)
{
+ if (!WindowsSignatureHelper.IsFileSigned(filePath))
+ return;
+
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"
- };
+ using var cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(filePath);
+ var subject = cert2.Subject;
+ var cnIndex = subject.IndexOf("CN=", StringComparison.Ordinal);
- // For .inf files, try to parse version and other metadata
- if (filePath.EndsWith(".inf", StringComparison.OrdinalIgnoreCase))
- {
- await ParseInfFileAsync(filePath, driverInfo, cancellationToken);
- }
+ if (cnIndex < 0)
+ return;
- // Get file hash for integrity validation
- driverInfo.Hash = await HashValidator.ComputeHashAsync(filePath, "SHA256", cancellationToken);
- driverInfo.HashAlgorithm = "SHA256";
+ var cnStart = cnIndex + 3;
+ var cnEnd = subject.IndexOf(',', cnStart);
- // 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)
- {
- GeneralTracer.Debug($"Could not get signature for file: {filePath} - {ex.Message}");
- }
+ var publisher = cnEnd > cnStart
+ ? subject[cnStart..cnEnd]
+ : subject[cnStart..];
- return driverInfo;
+ if (!string.IsNullOrEmpty(publisher))
+ driverInfo.TrustedPublishers.Add(publisher);
}
catch (Exception ex)
{
- GeneralTracer.Warn($"Failed to parse driver file: {filePath} - {ex.Message}");
- return null;
+ GeneralTracer.Debug($"Could not extract signature for {filePath}: {ex.Message}");
}
}
///
- /// Parses INF file
+ /// Parses a Windows INF file to extract DriverVer, DriverDesc, and HardwareId.
///
- private async Task ParseInfFileAsync(string infPath, DriverInfo driverInfo, CancellationToken cancellationToken)
+ private static async Task ParseInfFileAsync(
+ string infPath,
+ DriverInfo driverInfo,
+ CancellationToken cancellationToken)
{
try
{
@@ -595,55 +349,69 @@ private async Task ParseInfFileAsync(string infPath, DriverInfo driverInfo, Canc
foreach (var line in lines)
{
- var trimmedLine = line.Trim();
+ var trimmed = line.Trim();
- // Parse version
- if (trimmedLine.StartsWith("DriverVer", StringComparison.OrdinalIgnoreCase))
+ if (trimmed.StartsWith("DriverVer", StringComparison.OrdinalIgnoreCase))
{
- var parts = trimmedLine.Split('=');
+ var parts = trimmed.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))
- {
+ if (verParts.Length > 0
+ && DateTime.TryParse(verParts[0].Trim(), out var releaseDate))
driverInfo.ReleaseDate = releaseDate;
- }
}
}
- // Parse description
- else if (trimmedLine.StartsWith("DriverDesc", StringComparison.OrdinalIgnoreCase))
+ else if (trimmed.StartsWith("DriverDesc", StringComparison.OrdinalIgnoreCase))
{
- var parts = trimmedLine.Split('=');
+ var parts = trimmed.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))
+ else if (trimmed.StartsWith("HardwareId", StringComparison.OrdinalIgnoreCase)
+ || trimmed.Contains("HW_ID", StringComparison.OrdinalIgnoreCase))
{
- var parts = trimmedLine.Split('=');
+ var parts = trimmed.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)
{
GeneralTracer.Debug($"Could not parse INF file: {infPath} - {ex.Message}");
}
}
+
+ // ─── Nested type ──────────────────────────────────────────────────
+
+ ///
+ /// A lightweight pipeline step backed by delegates.
+ ///
+ private sealed class DelegateStep : IPipelineStep
+ {
+ private readonly Func> _execute;
+
+ public string StepName { get; }
+
+ public DelegateStep(
+ string stepName,
+ Func> execute)
+ {
+ StepName = stepName;
+ _execute = execute;
+ }
+
+ public bool ShouldExecute(PipelineContext context) => true;
+
+ public Task ExecuteAsync(
+ PipelineContext context,
+ CancellationToken cancellationToken)
+ => _execute(context, cancellationToken);
+ }
}