fs: Add case insensitive fopen() for config and system files
diff --git a/common/entry.s2.c b/common/entry.s2.c
index 7cb14620..5689603f 100644
--- a/common/entry.s2.c
+++ b/common/entry.s2.c
@@ -41,10 +41,14 @@ extern symbol build_id_s3;
static bool stage3_init(struct volume *part) {
struct file_handle *stage3;
+ bool old_cif = case_insensitive_fopen;
+ case_insensitive_fopen = true;
if ((stage3 = fopen(part, "/limine.sys")) == NULL
&& (stage3 = fopen(part, "/boot/limine.sys")) == NULL) {
+ case_insensitive_fopen = old_cif;
return false;
}
+ case_insensitive_fopen = old_cif;
stage3_found = true;
diff --git a/common/entry.s3.c b/common/entry.s3.c
index 4194e4dd..1a189259 100644
--- a/common/entry.s3.c
+++ b/common/entry.s3.c
@@ -71,11 +71,15 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
for (size_t i = 0; i < volume_index_i; i++) {
struct file_handle *f;
+ bool old_cif = case_insensitive_fopen;
+ case_insensitive_fopen = true;
if ((f = fopen(volume_index[i], "/limine.cfg")) == NULL
&& (f = fopen(volume_index[i], "/boot/limine.cfg")) == NULL
&& (f = fopen(volume_index[i], "/EFI/BOOT/limine.cfg")) == NULL) {
+ case_insensitive_fopen = old_cif;
continue;
}
+ case_insensitive_fopen = old_cif;
fclose(f);
diff --git a/common/fs/echfs.s2.c b/common/fs/echfs.s2.c
index 79c846cd..350164da 100644
--- a/common/fs/echfs.s2.c
+++ b/common/fs/echfs.s2.c
@@ -134,7 +134,9 @@ next:;
break;
}
- if (!strcmp(wanted_name, ret->dir_entry.name) &&
+ int (*strcmpfn)(const char *, const char *) = case_insensitive_fopen ? strcasecmp : strcmp;
+
+ if (strcmpfn(wanted_name, ret->dir_entry.name) == 0 &&
ret->dir_entry.parent_id == wanted_parent &&
ret->dir_entry.type == (last_elem ? FILE_TYPE : DIR_TYPE)) {
if (last_elem) {
diff --git a/common/fs/ext2.s2.c b/common/fs/ext2.s2.c
index 9afeb4bd..9c13f112 100644
--- a/common/fs/ext2.s2.c
+++ b/common/fs/ext2.s2.c
@@ -412,7 +412,9 @@ next:
inode_read(name, i + sizeof(struct ext2_dir_entry), dir->name_len,
¤t_inode, fd, alloc_map);
- int test = strcmp(token, name);
+ int (*strcmpfn)(const char *, const char *) = case_insensitive_fopen ? strcasecmp : strcmp;
+
+ int test = strcmpfn(token, name);
pmm_free(name, dir->name_len + 1);
if (test == 0) {
diff --git a/common/fs/fat32.s2.c b/common/fs/fat32.s2.c
index 9c781036..457dbc69 100644
--- a/common/fs/fat32.s2.c
+++ b/common/fs/fat32.s2.c
@@ -384,7 +384,9 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
}
}
- if (!strcmp(current_lfn, name)) {
+ int (*strcmpfn)(const char *, const char *) = case_insensitive_fopen ? strcasecmp : strcmp;
+
+ if (strcmpfn(current_lfn, name) == 0) {
*file = directory_entries[i+1];
ret = 0;
goto out;
diff --git a/common/fs/file.h b/common/fs/file.h
index a26c5daf..b7101787 100644
--- a/common/fs/file.h
+++ b/common/fs/file.h
@@ -9,6 +9,8 @@
# include <efi.h>
#endif
+extern bool case_insensitive_fopen;
+
bool fs_get_guid(struct guid *guid, struct volume *part);
char *fs_get_label(struct volume *part);
diff --git a/common/fs/file.s2.c b/common/fs/file.s2.c
index 4bbab15c..4bb5cd17 100644
--- a/common/fs/file.s2.c
+++ b/common/fs/file.s2.c
@@ -37,6 +37,8 @@ bool fs_get_guid(struct guid *guid, struct volume *part) {
return false;
}
+bool case_insensitive_fopen = false;
+
struct file_handle *fopen(struct volume *part, const char *filename) {
size_t filename_new_len = strlen(filename) + 2;
char *filename_new = ext_mem_alloc(filename_new_len);
diff --git a/common/fs/iso9660.s2.c b/common/fs/iso9660.s2.c
index 8aac409d..822e2966 100644
--- a/common/fs/iso9660.s2.c
+++ b/common/fs/iso9660.s2.c
@@ -195,7 +195,7 @@ static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size,
char entry_filename[128];
bool rr = load_name(entry_filename, entry);
- if (rr) {
+ if (rr && !case_insensitive_fopen) {
if (strcmp(filename, entry_filename) == 0) {
return buffer;
}
diff --git a/common/lib/config.c b/common/lib/config.c
index 8ae6765b..e5b78a75 100644
--- a/common/lib/config.c
+++ b/common/lib/config.c
@@ -21,11 +21,15 @@ static char *config_addr;
int init_config_disk(struct volume *part) {
struct file_handle *f;
+ bool old_cif = case_insensitive_fopen;
+ case_insensitive_fopen = true;
if ((f = fopen(part, "/limine.cfg")) == NULL
&& (f = fopen(part, "/boot/limine.cfg")) == NULL
&& (f = fopen(part, "/EFI/BOOT/limine.cfg")) == NULL) {
+ case_insensitive_fopen = old_cif;
return -1;
}
+ case_insensitive_fopen = old_cif;
size_t config_size = f->size + 2;
config_addr = ext_mem_alloc(config_size);
diff --git a/common/protos/chainload_next.c b/common/protos/chainload_next.c
index 05d62f66..ac2648ad 100644
--- a/common/protos/chainload_next.c
+++ b/common/protos/chainload_next.c
@@ -20,11 +20,13 @@ static void try(char *config, struct volume *v) {
struct file_handle *image;
struct volume *p = volume_get_by_coord(v->is_optical, v->index, i);
- if ((image = fopen(p, "/EFI/BOOT/BOOTX64.EFI")) == NULL
- && (image = fopen(p, "/efi/boot/bootx64.efi")) == NULL
- && (image = fopen(p, "/EFI/BOOT/BOOTx64.EFI")) == NULL) {
+ bool old_cif = case_insensitive_fopen;
+ case_insensitive_fopen = true;
+ if ((image = fopen(p, "/EFI/BOOT/BOOTX64.EFI")) == NULL) {
+ case_insensitive_fopen = old_cif;
continue;
}
+ case_insensitive_fopen = old_cif;
efi_chainload_file(config, image);
}
