:: commit c945ebc4b272b5f65586d09b3b2340f7d953dd2f

mintsuki <mintsuki@protonmail.com> — 2022-09-01 12:02

parents: 2eadcc33c1

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,
                    &current_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);
     }
tab: 248 wrap: offon