[syslinux] [PATCH 08/12] core: introduce multidisk syntax for accessing a disk using it's MBR signature

Andre Ericson de.ericson at gmail.com
Mon Aug 20 01:16:50 PDT 2012


Introduce "(mbr:0x12345678,2)/foo/bar" like syntax to access the disk with
MBR signature of 0x1234568 and the partition number 2.

Signed-off-by: Andre Ericson <de.ericson at gmail.com>
---
 core/fs/fs.c             |  2 +-
 core/fs/readdir.c        |  2 +-
 core/include/multidisk.h |  2 +-
 core/multidisk.c         | 94 +++++++++++++++++++++++++++++++++++++-----------
 4 files changed, 76 insertions(+), 24 deletions(-)

diff --git a/core/fs/fs.c b/core/fs/fs.c
index 9f9e4fc..df82578 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -494,7 +494,7 @@ int open_file(const char *name, struct com32_filedata *filedata)
     struct muldisk_path *mul_path;
 
     if (name[0] == '(') {
-        mul_path = muldisk_path_parse(name);
+        mul_path = hdd_part_from_mdpath(name);
         if (!mul_path)
             return -1;
 
diff --git a/core/fs/readdir.c b/core/fs/readdir.c
index fe68b01..20f60d7 100644
--- a/core/fs/readdir.c
+++ b/core/fs/readdir.c
@@ -16,7 +16,7 @@ DIR *opendir(const char *path)
 
     if (path[0] == '(') {
 
-        mul_path = muldisk_path_parse(path);
+        mul_path = hdd_part_from_mdpath(path);
         if (!mul_path)
             return NULL;
 
diff --git a/core/include/multidisk.h b/core/include/multidisk.h
index 2515887..1e43d4a 100644
--- a/core/include/multidisk.h
+++ b/core/include/multidisk.h
@@ -11,6 +11,6 @@ struct muldisk_path {
 int find_partition(struct part_iter **_iter, int drive, int partition);
 int add_fs(struct fs_info *fs, uint8_t disk, uint8_t partition);
 struct fs_info *get_fs(uint8_t disk, uint8_t partition);
-struct muldisk_path* muldisk_path_parse(const char *path);
+struct muldisk_path* hdd_part_from_mdpath(const char *path);
 
 #endif /* MULTIDISK_H */
diff --git a/core/multidisk.c b/core/multidisk.c
index 78d3dbf..3cc8f7b 100644
--- a/core/multidisk.c
+++ b/core/multidisk.c
@@ -104,13 +104,28 @@ bail:
     return -1;
 }
 
-struct muldisk_path* muldisk_path_parse(const char *path)
+static uint8_t charhex_to_hex(char c)
+{
+    if (c >= '0' && c <= '9')
+        return c - '0';
+    if (c >= 'A' && c <= 'F')
+        return c - 'A' + 0xa;
+    if (c >= 'a' && c <= 'f')
+        return c - 'a' + 0xa;
+    return 0xff;
+}
+
+struct muldisk_path* hdd_part_from_mdpath(const char *path)
 {
     struct muldisk_path *mpath;
+    struct disk_dos_mbr *mbr = NULL;
+    struct disk_info diskinfo;
     const char *c = path;
     char buff[4];
     uint8_t hdd = 0;
     uint8_t partition = 0;
+    uint32_t mbr_sig = 0;
+    int disk;
     int i = 0;
     int mult = 1;
 
@@ -120,6 +135,7 @@ struct muldisk_path* muldisk_path_parse(const char *path)
 
     if (path[1] == 'h' && path[2] == 'd') {
         c += 2;
+
         /* get hdd number */
         for (++c; *c && *c != ','; ++c)
             buff[i++] = *c;
@@ -129,32 +145,68 @@ struct muldisk_path* muldisk_path_parse(const char *path)
 
         /* str to uint8_t */
         while (i--) {
+            if (buff[i] < '0' || buff[i] > '9')
+                goto bail;
             hdd += (buff[i] - 48) * mult;
             mult *= 10;
         }
-        mpath->hdd = hdd;
-        /* get partition number */
-        i = 0;
-        for (++c; *c && *c != ')'; ++c)
-            buff[i++] = *c;
-        if (!*c)
-            goto bail;
-        buff[i] = '\0';
+    } else if (!strncmp(path + 1, "mbr:0x", 6)) {
+        c += 6;
+
+        /* get mbr sig */
+        for (++c; *c && *c != ','; ++c) {
+            mbr_sig = mbr_sig << 4;
+            i = charhex_to_hex(*c);
+            if (i == 0xff)
+                goto bail;
+            mbr_sig += i;
+        }
 
-        /* str to uint8_t */
-        mult = 1;
-        while (i--) {
-            partition += (buff[i] - 48) * mult;
-            mult *= 10;
+        /* find hdd from mbr */
+        for (disk = 0x80; disk < 0xff; disk++) {
+            if (disk_get_params(disk, &diskinfo))
+                continue;
+            if (!(mbr = disk_read_sectors(&diskinfo, 0, 1)))
+                continue;
+            if (mbr->sig != disk_mbr_sig_magic)
+                continue;
+            if (mbr_sig == mbr->disk_sig) {
+                hdd = disk - 0x80;
+                free(mbr);
+                break;
+            }
+            free(mbr);
         }
-        mpath->partition = partition;
-        i = 0;
-        /* c was on ')' jump it and stop at beginning of path */
-        for (c++; *c; c++)
-            mpath->relative_name[i++] = *c;
-        mpath->relative_name[i] = '\0';
-        return mpath;
+        if (disk == 0xff)
+            goto bail;
+
+    } else {
+        goto bail;
+    }
+    /* get partition number */
+    i = 0;
+    for (++c; *c && *c != ')'; ++c)
+        buff[i++] = *c;
+    if (!*c)
+        goto bail;
+    buff[i] = '\0';
+
+    /* str to uint8_t */
+    mult = 1;
+    while (i--) {
+        if (buff[i] < '0' || buff[i] > '9')
+            goto bail;
+        partition += (buff[i] - 48) * mult;
+        mult *= 10;
     }
+    mpath->partition = partition;
+    mpath->hdd = hdd;
+    i = 0;
+    /* c was on ')' jump it and stop at beginning of path */
+    for (c++; *c; c++)
+        mpath->relative_name[i++] = *c;
+    mpath->relative_name[i] = '\0';
+    return mpath;
 
 bail:
     free(mpath);
-- 
1.7.11.3




More information about the Syslinux mailing list