:: commit a9864a0ab4cbc623c1eb8a05bed9bca48c44d13d

mintsuki <mintsuki@protonmail.com> — 2020-10-17 09:08

parents: 47d517bec8

Implement string_to_guid()

diff --git a/limine.bin b/limine.bin
index 28833f5e..b9d1a300 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index ee53ec7f..f6b018a1 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -119,7 +119,58 @@ static int char_value(char c) {
         return c - '0';
     }
 
-    return 0;
+    return -1;
+}
+
+static bool is_valid_guid(const char *s) {
+    for (size_t i = 0; ; i++) {
+        switch (i) {
+            case 8:
+            case 13:
+            case 18:
+            case 23:
+                if (s[i] != '-')
+                    return false;
+                break;
+            case 36:
+                return s[i] == 0;
+            default:
+                if (char_value(s[i]) == -1)
+                    return false;
+                break;
+        }
+    }
+}
+
+static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
+    size_t p = 0;
+    for (int i = len - 1; i >= 0; i--) {
+        int val = char_value(s[i]);
+
+        i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
+    }
+}
+
+static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
+    size_t p = 0;
+    for (int i = 0; i < len; i++) {
+        int val = char_value(s[i]);
+
+        i % 2 ? (dest[p++] |= val) : (dest[p] = val << 4);
+    }
+}
+
+bool string_to_guid(struct guid *guid, const char *s) {
+    if (!is_valid_guid(s))
+        return false;
+
+    guid_convert_le_cluster((uint8_t *)guid + 0,  s + 0,  8);
+    guid_convert_le_cluster((uint8_t *)guid + 4,  s + 9,  4);
+    guid_convert_le_cluster((uint8_t *)guid + 6,  s + 14, 4);
+    guid_convert_be_cluster((uint8_t *)guid + 8,  s + 19, 4);
+    guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 16);
+
+    return true;
 }
 
 uint64_t strtoui(const char *s) {
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index af00263e..8dc60a53 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -8,6 +8,15 @@
 
 extern uint8_t boot_drive;
 
+struct guid {
+    uint32_t a;
+    uint16_t b;
+    uint16_t c;
+    uint8_t  d[8];
+} __attribute__((packed));
+
+bool string_to_guid(struct guid *guid, const char *s);
+
 bool uri_open(struct file_handle *fd, char *uri);
 
 uint64_t sqrt(uint64_t a_nInput);
diff --git a/stage2/lib/part.c b/stage2/lib/part.c
index a2cf71a4..9c3fe988 100644
--- a/stage2/lib/part.c
+++ b/stage2/lib/part.c
@@ -23,10 +23,7 @@ struct gpt_table_header {
     uint64_t last_usable_lba;
 
     // the guid
-    struct {
-        uint64_t low;
-        uint64_t high;
-    } disk_guid;
+    struct guid disk_guid;
 
     // entries related
     uint64_t partition_entry_lba;
@@ -36,15 +33,9 @@ struct gpt_table_header {
 } __attribute__((packed));
 
 struct gpt_entry {
-    struct {
-        uint64_t low;
-        uint64_t high;
-    } partition_type_guid;
+    struct guid partition_type_guid;
 
-    struct {
-        uint64_t low;
-        uint64_t high;
-    } unique_partition_guid;
+    struct guid unique_partition_guid;
 
     uint64_t starting_lba;
     uint64_t ending_lba;
@@ -74,8 +65,9 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
          (header.partition_entry_lba * 512) + (partition * sizeof(entry)),
          sizeof(entry));
 
-    if (entry.unique_partition_guid.low  == 0 &&
-        entry.unique_partition_guid.high == 0) return NO_PARTITION;
+    struct guid empty_guid = {0};
+    if (!memcmp(&entry.unique_partition_guid, &empty_guid, sizeof(struct guid)))
+        return NO_PARTITION;
 
     ret->first_sect = entry.starting_lba;
     ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
tab: 248 wrap: offon