:: commit 2e96f8fe6a2951437980751baf101f2fbbcad429

mintsuki <mintsuki@protonmail.com> — 2020-06-11 10:13

parents: 22ac79080e

fat32: Fix handling of non-lfn files

diff --git a/qloader2.bin b/qloader2.bin
index 9bd7310e..7e9dfd8a 100644
Binary files a/qloader2.bin and b/qloader2.bin differ
diff --git a/src/fs/fat32.c b/src/fs/fat32.c
index 732a78ca..3707b63e 100644
--- a/src/fs/fat32.c
+++ b/src/fs/fat32.c
@@ -123,6 +123,26 @@ static void fat32_lfncpy(char* destination, const void* source, unsigned int siz
     }
 }
 
+static void fat32_filename_to_8_3(char *dest, const char *src) {
+    int i = 0, j = 0;
+
+conv:
+    while (src[i] && src[i] != '.')
+        dest[j++] = toupper(src[i++]);
+
+    if (!src[i]) {
+        while (j < 8+3)
+            dest[j++] = ' ';
+        return;
+    }
+
+    i++;
+    while (j < 8)
+        dest[j++] = ' ';
+
+    goto conv;
+}
+
 static int fat32_open_in(struct fat32_context* context, struct fat32_directory_entry* directory, struct fat32_directory_entry* file, const char* name) {
     int error;
     uint32_t current_cluster_number = directory->cluster_num_high << 16 | directory->cluster_num_low;
@@ -176,14 +196,21 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
                     }
                 }
 
-                if ((has_lfn && strcmp(current_lfn, name) == 0) || strncmp(directory_entries[i].file_name_and_ext, name, 8 + 3) == 0) {
-                    *file = directory_entries[i];
-                    return 0;
-                }
-
                 if (has_lfn) {
-                    has_lfn = false;
+                    if (!strcmp(current_lfn, name)) {
+                        *file = directory_entries[i];
+                        return 0;
+                    }
+                } else {
+                    char fn[8+3];
+                    fat32_filename_to_8_3(fn, name);
+                    if (!strncmp(directory_entries[i].file_name_and_ext, fn, 8+3)) {
+                        *file = directory_entries[i];
+                        return 0;
+                    }
                 }
+
+                has_lfn = false;
             }
         }
 
@@ -192,7 +219,7 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
         if (error != 0) {
             return error;
         }
-    } while (current_cluster_number >= 0x00000002 && current_cluster_number <= 0x0FFFFEF);
+    } while (current_cluster_number >= 0x00000002 && current_cluster_number <= 0x0FFFFFEF);
 
     // file not found
     return -1;
@@ -330,7 +357,7 @@ int fat32_read(struct fat32_file_handle* file, void* buf, uint64_t loc, uint64_t
             print("fat32: failed to read cluster %x from map\n", current_cluster_number);
             return r;
         }
-    } while (current_cluster_number >= 0x00000002 && current_cluster_number <= 0x0FFFFEF);
+    } while (current_cluster_number >= 0x00000002 && current_cluster_number <= 0x0FFFFFEF);
 
     print("fat32: read failed, unexpected end of cluster chain\n");
     return 0;
diff --git a/src/lib/libc.c b/src/lib/libc.c
index ce45acc5..08ecde55 100644
--- a/src/lib/libc.c
+++ b/src/lib/libc.c
@@ -2,6 +2,20 @@
 #include <stdint.h>
 #include <lib/libc.h>
 
+int toupper(int c) {
+    if (c >= 'a' && c <= 'z') {
+        return c - 0x20;
+    }
+    return c;
+}
+
+int tolower(int c) {
+    if (c >= 'A' && c <= 'Z') {
+        return c + 0x20;
+    }
+    return c;
+}
+
 void *memcpy(void *dest, const void *src, size_t n) {
     uint8_t *pdest = dest;
     const uint8_t *psrc = src;
diff --git a/src/lib/libc.h b/src/lib/libc.h
index a56bfb85..bffe94a1 100644
--- a/src/lib/libc.h
+++ b/src/lib/libc.h
@@ -3,10 +3,14 @@
 
 #include <stddef.h>
 
+int toupper(int c);
+int tolower(int c);
+
 void *memset(void *, int, size_t);
 void *memcpy(void *, const void *, size_t);
 int memcmp(const void *, const void *, size_t);
 void *memmove(void *, const void *, size_t);
+
 char *strcpy(char *, const char *);
 char *strncpy(char *, const char *, size_t);
 size_t strlen(const char *);
tab: 248 wrap: offon