Skip to content

Commit 54acd63

Browse files
CopilotJusterZhu
andcommitted
Add GetDriversFromDirectoryAsync method to read driver information from local directory
Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com>
1 parent 80c2344 commit 54acd63

5 files changed

Lines changed: 465 additions & 0 deletions

File tree

src/c#/GeneralUpdate.Drivelution/Abstractions/IGeneralDrivelution.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,14 @@ public interface IGeneralDrivelution
5656
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
5757
/// <returns>回滚结果 / Rollback result</returns>
5858
Task<bool> RollbackAsync(string backupPath, CancellationToken cancellationToken = default);
59+
60+
/// <summary>
61+
/// 从本地目录读取驱动信息
62+
/// Reads driver information from local directory
63+
/// </summary>
64+
/// <param name="directoryPath">目录路径 / Directory path</param>
65+
/// <param name="searchPattern">搜索模式(可选,例如 "*.inf", "*.ko")/ Search pattern (optional, e.g., "*.inf", "*.ko")</param>
66+
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
67+
/// <returns>驱动信息列表 / List of driver information</returns>
68+
Task<List<DriverInfo>> GetDriversFromDirectoryAsync(string directoryPath, string? searchPattern = null, CancellationToken cancellationToken = default);
5969
}

src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,23 @@ public static PlatformInfo GetPlatformInfo()
126126
SystemVersion = CompatibilityChecker.GetSystemVersion()
127127
};
128128
}
129+
130+
/// <summary>
131+
/// 从本地目录读取驱动信息
132+
/// Reads driver information from local directory
133+
/// </summary>
134+
/// <param name="directoryPath">目录路径 / Directory path</param>
135+
/// <param name="searchPattern">搜索模式(可选,例如 "*.inf", "*.ko")/ Search pattern (optional, e.g., "*.inf", "*.ko")</param>
136+
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
137+
/// <returns>驱动信息列表 / List of driver information</returns>
138+
public static async Task<List<DriverInfo>> GetDriversFromDirectoryAsync(
139+
string directoryPath,
140+
string? searchPattern = null,
141+
CancellationToken cancellationToken = default)
142+
{
143+
var updater = Create();
144+
return await updater.GetDriversFromDirectoryAsync(directoryPath, searchPattern, cancellationToken);
145+
}
129146
}
130147

131148
/// <summary>

src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,243 @@ private string GenerateBackupPath(DriverInfo driverInfo, string baseBackupPath)
359359
var fileName = Path.GetFileName(driverInfo.FilePath);
360360
return Path.Combine(baseBackupPath, fileName);
361361
}
362+
363+
/// <inheritdoc/>
364+
public async Task<List<DriverInfo>> GetDriversFromDirectoryAsync(
365+
string directoryPath,
366+
string? searchPattern = null,
367+
CancellationToken cancellationToken = default)
368+
{
369+
var driverInfoList = new List<DriverInfo>();
370+
371+
try
372+
{
373+
_logger.Information("Reading driver information from directory: {DirectoryPath}", directoryPath);
374+
375+
if (!Directory.Exists(directoryPath))
376+
{
377+
_logger.Warning("Directory not found: {DirectoryPath}", directoryPath);
378+
return driverInfoList;
379+
}
380+
381+
// Default to kernel modules for Linux
382+
var pattern = searchPattern ?? "*.ko";
383+
var driverFiles = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
384+
385+
// Also look for .deb and .rpm packages if no specific pattern was provided
386+
if (searchPattern == null)
387+
{
388+
var debFiles = Directory.GetFiles(directoryPath, "*.deb", SearchOption.AllDirectories);
389+
var rpmFiles = Directory.GetFiles(directoryPath, "*.rpm", SearchOption.AllDirectories);
390+
driverFiles = driverFiles.Concat(debFiles).Concat(rpmFiles).ToArray();
391+
}
392+
393+
_logger.Information("Found {Count} driver files matching pattern: {Pattern}", driverFiles.Length, pattern);
394+
395+
foreach (var filePath in driverFiles)
396+
{
397+
if (cancellationToken.IsCancellationRequested)
398+
break;
399+
400+
try
401+
{
402+
var driverInfo = await ParseDriverFileAsync(filePath, cancellationToken);
403+
if (driverInfo != null)
404+
{
405+
driverInfoList.Add(driverInfo);
406+
_logger.Information("Parsed driver: {DriverName} v{Version}", driverInfo.Name, driverInfo.Version);
407+
}
408+
}
409+
catch (Exception ex)
410+
{
411+
_logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
412+
}
413+
}
414+
415+
_logger.Information("Successfully loaded {Count} driver(s) from directory", driverInfoList.Count);
416+
}
417+
catch (Exception ex)
418+
{
419+
_logger.Error(ex, "Error reading drivers from directory: {DirectoryPath}", directoryPath);
420+
}
421+
422+
return driverInfoList;
423+
}
424+
425+
/// <summary>
426+
/// 解析驱动文件信息
427+
/// Parses driver file information
428+
/// </summary>
429+
private async Task<DriverInfo?> ParseDriverFileAsync(string filePath, CancellationToken cancellationToken)
430+
{
431+
try
432+
{
433+
var fileInfo = new FileInfo(filePath);
434+
var fileName = Path.GetFileNameWithoutExtension(filePath);
435+
var extension = Path.GetExtension(filePath).ToLowerInvariant();
436+
437+
var driverInfo = new DriverInfo
438+
{
439+
Name = fileName,
440+
FilePath = filePath,
441+
TargetOS = "Linux",
442+
Architecture = Environment.Is64BitOperatingSystem ? "x64" : "x86"
443+
};
444+
445+
// Parse based on file type
446+
if (extension == ".ko")
447+
{
448+
await ParseKernelModuleAsync(filePath, driverInfo, cancellationToken);
449+
}
450+
else if (extension == ".deb")
451+
{
452+
await ParseDebPackageAsync(filePath, driverInfo, cancellationToken);
453+
}
454+
else if (extension == ".rpm")
455+
{
456+
await ParseRpmPackageAsync(filePath, driverInfo, cancellationToken);
457+
}
458+
459+
// Get file hash for integrity validation
460+
driverInfo.Hash = await HashValidator.ComputeHashAsync(filePath, "SHA256", cancellationToken);
461+
driverInfo.HashAlgorithm = "SHA256";
462+
463+
return driverInfo;
464+
}
465+
catch (Exception ex)
466+
{
467+
_logger.Warning(ex, "Failed to parse driver file: {FilePath}", filePath);
468+
return null;
469+
}
470+
}
471+
472+
/// <summary>
473+
/// 解析内核模块
474+
/// Parses kernel module
475+
/// </summary>
476+
private async Task ParseKernelModuleAsync(string koPath, DriverInfo driverInfo, CancellationToken cancellationToken)
477+
{
478+
try
479+
{
480+
// Try to get module info using modinfo command
481+
var output = await ExecuteCommandAsync("modinfo", koPath, cancellationToken);
482+
var lines = output.Split('\n');
483+
484+
foreach (var line in lines)
485+
{
486+
var trimmedLine = line.Trim();
487+
488+
if (trimmedLine.StartsWith("version:", StringComparison.OrdinalIgnoreCase))
489+
{
490+
driverInfo.Version = trimmedLine.Substring(8).Trim();
491+
}
492+
else if (trimmedLine.StartsWith("description:", StringComparison.OrdinalIgnoreCase))
493+
{
494+
driverInfo.Description = trimmedLine.Substring(12).Trim();
495+
}
496+
else if (trimmedLine.StartsWith("alias:", StringComparison.OrdinalIgnoreCase))
497+
{
498+
var alias = trimmedLine.Substring(6).Trim();
499+
if (string.IsNullOrEmpty(driverInfo.HardwareId))
500+
{
501+
driverInfo.HardwareId = alias;
502+
}
503+
}
504+
}
505+
506+
if (string.IsNullOrEmpty(driverInfo.Version))
507+
{
508+
driverInfo.Version = "1.0.0";
509+
}
510+
}
511+
catch (Exception ex)
512+
{
513+
_logger.Debug(ex, "Could not get module info for: {KoPath}", koPath);
514+
driverInfo.Version = "1.0.0";
515+
}
516+
}
517+
518+
/// <summary>
519+
/// 解析Debian包
520+
/// Parses Debian package
521+
/// </summary>
522+
private async Task ParseDebPackageAsync(string debPath, DriverInfo driverInfo, CancellationToken cancellationToken)
523+
{
524+
try
525+
{
526+
// Try to get package info using dpkg-deb command
527+
var output = await ExecuteCommandAsync("dpkg-deb", $"-I {debPath}", cancellationToken);
528+
var lines = output.Split('\n');
529+
530+
foreach (var line in lines)
531+
{
532+
var trimmedLine = line.Trim();
533+
534+
if (trimmedLine.StartsWith("Version:", StringComparison.OrdinalIgnoreCase))
535+
{
536+
driverInfo.Version = trimmedLine.Substring(8).Trim();
537+
}
538+
else if (trimmedLine.StartsWith("Description:", StringComparison.OrdinalIgnoreCase))
539+
{
540+
driverInfo.Description = trimmedLine.Substring(12).Trim();
541+
}
542+
}
543+
544+
if (string.IsNullOrEmpty(driverInfo.Version))
545+
{
546+
driverInfo.Version = "1.0.0";
547+
}
548+
}
549+
catch (Exception ex)
550+
{
551+
_logger.Debug(ex, "Could not get package info for: {DebPath}", debPath);
552+
driverInfo.Version = "1.0.0";
553+
}
554+
}
555+
556+
/// <summary>
557+
/// 解析RPM包
558+
/// Parses RPM package
559+
/// </summary>
560+
private async Task ParseRpmPackageAsync(string rpmPath, DriverInfo driverInfo, CancellationToken cancellationToken)
561+
{
562+
try
563+
{
564+
// Try to get package info using rpm command
565+
var output = await ExecuteCommandAsync("rpm", $"-qip {rpmPath}", cancellationToken);
566+
var lines = output.Split('\n');
567+
568+
foreach (var line in lines)
569+
{
570+
var trimmedLine = line.Trim();
571+
572+
if (trimmedLine.StartsWith("Version", StringComparison.OrdinalIgnoreCase))
573+
{
574+
var parts = trimmedLine.Split(':');
575+
if (parts.Length > 1)
576+
{
577+
driverInfo.Version = parts[1].Trim();
578+
}
579+
}
580+
else if (trimmedLine.StartsWith("Summary", StringComparison.OrdinalIgnoreCase))
581+
{
582+
var parts = trimmedLine.Split(':');
583+
if (parts.Length > 1)
584+
{
585+
driverInfo.Description = parts[1].Trim();
586+
}
587+
}
588+
}
589+
590+
if (string.IsNullOrEmpty(driverInfo.Version))
591+
{
592+
driverInfo.Version = "1.0.0";
593+
}
594+
}
595+
catch (Exception ex)
596+
{
597+
_logger.Debug(ex, "Could not get package info for: {RpmPath}", rpmPath);
598+
driverInfo.Version = "1.0.0";
599+
}
600+
}
362601
}

src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ public Task<bool> RollbackAsync(
6565
throw new PlatformNotSupportedException(
6666
"MacOS driver rollback is not yet implemented.");
6767
}
68+
69+
/// <inheritdoc/>
70+
public Task<List<DriverInfo>> GetDriversFromDirectoryAsync(
71+
string directoryPath,
72+
string? searchPattern = null,
73+
CancellationToken cancellationToken = default)
74+
{
75+
throw new PlatformNotSupportedException(
76+
"MacOS driver directory reading is not yet implemented.");
77+
}
6878
}
6979

7080
/// <summary>

0 commit comments

Comments
 (0)