@@ -6,9 +6,10 @@ use crate::generators::GeneratorDeclaration;
66use crate :: generators:: list:: ListConfiguration ;
77use crate :: utils;
88use anyhow:: { Context , Result } ;
9+ use log:: info;
910use std:: collections:: BTreeMap ;
1011use uefi:: CString16 ;
11- use uefi:: fs:: { FileSystem , Path } ;
12+ use uefi:: fs:: { FileSystem , Path , PathBuf } ;
1213use uefi:: proto:: device_path:: DevicePath ;
1314use uefi:: proto:: device_path:: text:: { AllowShortcuts , DisplayOnly } ;
1415
@@ -17,7 +18,8 @@ const LINUX_CHAINLOAD_ACTION_PREFIX: &str = "linux-chainload-";
1718
1819/// The locations to scan for kernel pairs.
1920/// We will check for symlinks and if this directory is a symlink, we will skip it.
20- const SCAN_LOCATIONS : & [ & str ] = & [ "/boot" , "/" ] ;
21+ /// The empty string represents the root of the filesystem.
22+ const SCAN_LOCATIONS : & [ & str ] = & [ "\\ boot" , "\\ " ] ;
2123
2224/// Prefixes of kernel files to scan for.
2325const KERNEL_PREFIXES : & [ & str ] = & [ "vmlinuz" ] ;
@@ -39,6 +41,9 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
3941 // All the discovered kernel pairs.
4042 let mut pairs = Vec :: new ( ) ;
4143
44+ // We have to special-case the root directory due to path logic in the uefi crate.
45+ let is_root = path. is_empty ( ) || path == "\\ " ;
46+
4247 // Construct a filesystem path from the path string.
4348 let path = CString16 :: try_from ( path) . context ( "unable to convert path to CString16" ) ?;
4449 let path = Path :: new ( & path) ;
@@ -62,6 +67,16 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
6267 return Ok ( pairs) ;
6368 } ;
6469
70+ // Create a new path used for joining file names below.
71+ // All attempts to derive paths for the files in the directory should use this instead.
72+ // The uefi crate does not handle push correctly for the root directory.
73+ // It will add a second slash, which will cause our path logic to fail.
74+ let path_for_join = if is_root {
75+ PathBuf :: new ( )
76+ } else {
77+ path. clone ( )
78+ } ;
79+
6580 // For each item in the directory, find a kernel.
6681 for item in directory {
6782 let item = item. context ( "unable to read directory item" ) ?;
@@ -74,11 +89,14 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
7489 // Convert the name from a CString16 to a String.
7590 let name = item. file_name ( ) . to_string ( ) ;
7691
92+ // Convert the name to lowercase to make all of this case-insensitive.
93+ let name_for_match = name. to_lowercase ( ) ;
94+
7795 // Find a kernel prefix that matches, if any.
78- let Some ( prefix ) = KERNEL_PREFIXES
79- . iter ( )
80- . find ( |prefix| name == * * prefix || name . starts_with ( & format ! ( "{}-" , prefix) ) )
81- else {
96+ // This is case-insensitive to ensure we pick up all possibilities.
97+ let Some ( prefix ) = KERNEL_PREFIXES . iter ( ) . find ( |prefix| {
98+ name_for_match == * * prefix || name_for_match . starts_with ( & format ! ( "{}-" , prefix) )
99+ } ) else {
82100 // Skip over anything that doesn't match a kernel prefix.
83101 continue ;
84102 } ;
@@ -96,8 +114,10 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
96114 let initramfs = format ! ( "{}{}" , prefix, suffix) ;
97115 let initramfs = CString16 :: try_from ( initramfs. as_str ( ) )
98116 . context ( "unable to convert initramfs name to CString16" ) ?;
99- let mut initramfs_path = path . clone ( ) ;
117+ let mut initramfs_path = path_for_join . clone ( ) ;
100118 initramfs_path. push ( Path :: new ( & initramfs) ) ;
119+
120+ info ! ( "initramfs path: {:?} ({})" , initramfs_path, initramfs) ;
101121 // Check if the initramfs path exists, if it does, break out of the loop.
102122 if filesystem
103123 . try_exists ( & initramfs_path)
@@ -108,7 +128,7 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
108128 } ;
109129
110130 // Construct a kernel path from the kernel name.
111- let mut kernel = path . clone ( ) ;
131+ let mut kernel = path_for_join . clone ( ) ;
112132 kernel. push ( Path :: new ( & item. file_name ( ) ) ) ;
113133 let kernel = kernel. to_string ( ) ;
114134 let initramfs = matched_initramfs_path. map ( |initramfs_path| initramfs_path. to_string ( ) ) ;
0 commit comments