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 *);
