@@ -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}
0 commit comments