]> code.delx.au - refind/blobdiff - gptsync/gptsync.c
Significant reworking of Makefile structure. Added Apple Core Storage
[refind] / gptsync / gptsync.c
index 2ba441845df9fd195c403ad2f24dcbafe1ccc8c9..c711186c97fc02115f44bee4fd50a8ccafea291c 100644 (file)
@@ -38,6 +38,7 @@
 #include "gptsync.h"
 
 #include "syslinux_mbr.h"
+#define memcpy(a, b, c) CopyMem(a, b, c)
 
 //
 // MBR functions
@@ -138,16 +139,16 @@ static UINTN write_mbr(VOID)
             table[i].end_chs[2]   = 0xff;
 
             lba = new_mbr_parts[k].start_lba;
-            if (lba > 0xffffffffULL) {
+            if (lba > MAX_MBR_LBA) {
                 Print(L"Warning: Partition %d starts beyond 2 TiB limit\n", i+1);
-                lba = 0xffffffffULL;
+                lba = MAX_MBR_LBA;
             }
             table[i].start_lba    = (UINT32)lba;
 
             lba = new_mbr_parts[k].end_lba + 1 - new_mbr_parts[k].start_lba;
-            if (lba > 0xffffffffULL) {
+            if (lba > MAX_MBR_LBA) {
                 Print(L"Warning: Partition %d extends beyond 2 TiB limit\n", i+1);
-                lba = 0xffffffffULL;
+                lba = MAX_MBR_LBA;
             }
             table[i].size         = (UINT32)lba;
         }
@@ -214,7 +215,7 @@ static UINTN check_gpt(VOID)
     }
 
     return 0;
-}
+} // VOID check_gpt()
 
 //
 // compare GPT and MBR tables
@@ -260,14 +261,15 @@ static VOID generate_hybrid_mbr(VOID) {
     UINTN i, k, iter, count_active;
     UINT64 first_used_lba;
 
-    i = 0;
     new_mbr_part_count = 1;
-    first_used_lba = 0xFFFFFFFF;
+    first_used_lba = (UINT64) MAX_MBR_LBA + (UINT64) 1;
 
     // Copy partitions in three passes....
     // First, do FAT and NTFS partitions....
+    i = 0;
     do {
         if ((gpt_parts[i].start_lba > 0) && (gpt_parts[i].end_lba > 0) &&
+            (gpt_parts[i].end_lba <= MAX_MBR_LBA) &&                    /* Within MBR limits */
             (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) && /* MS Basic Data GPT type code */
             (gpt_parts[i].mbr_type != 0x83)) {                          /* Not containing Linux filesystem */
            copy_gpt_to_new_mbr(i, new_mbr_part_count);
@@ -279,10 +281,14 @@ static VOID generate_hybrid_mbr(VOID) {
         i++;
     } while (i < gpt_part_count && new_mbr_part_count <= 3);
 
-    // Second, do Linux partitions....
-    i = 0;
-    while (i < gpt_part_count && new_mbr_part_count <= 3) {
+    // Second, do Linux partitions. Note that we start from the END of the
+    // partition list, so as to maximize the space covered by the 0xEE
+    // partition if there are several Linux partitions before other hybridized
+    // partitions.
+    i = gpt_part_count - 1; // Note that gpt_part_count can't be 0; filtered by check_gpt()
+    while (i < gpt_part_count && new_mbr_part_count <= 3) { // if too few GPT partitions, i loops around to a huge value
         if ((gpt_parts[i].start_lba > 0) && (gpt_parts[i].end_lba > 0) &&
+            (gpt_parts[i].end_lba <= MAX_MBR_LBA) &&
             ((gpt_parts[i].gpt_parttype->kind == GPT_KIND_DATA) || (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA)) &&
             (gpt_parts[i].mbr_type == 0x83)) {
            copy_gpt_to_new_mbr(i, new_mbr_part_count);
@@ -291,7 +297,7 @@ static VOID generate_hybrid_mbr(VOID) {
 
            new_mbr_part_count++;
        }
-       i++;
+       i--;
     } // while
 
     // Third, do anything that's left to cover uncovered spaces; but this requires
@@ -300,10 +306,13 @@ static VOID generate_hybrid_mbr(VOID) {
     new_mbr_parts[0].index     = 0;
     new_mbr_parts[0].start_lba = 1;
     new_mbr_parts[0].end_lba   = (disk_size() > first_used_lba) ? (first_used_lba - 1) : disk_size() - 1;
-    new_mbr_parts[0].mbr_type  = 0xee;
+    if (new_mbr_parts[0].end_lba > MAX_MBR_LBA)
+       new_mbr_parts[0].end_lba = MAX_MBR_LBA;
+    new_mbr_parts[0].mbr_type  = 0xEE;
     i = 0;
     while (i < gpt_part_count && new_mbr_part_count <= 3) {
        if ((gpt_parts[i].start_lba > new_mbr_parts[0].end_lba) && (gpt_parts[i].end_lba > 0) &&
+           (gpt_parts[i].end_lba <= MAX_MBR_LBA) &&
            (gpt_parts[i].gpt_parttype->kind != GPT_KIND_BASIC_DATA) &&
            (gpt_parts[i].mbr_type != 0x83)) {
           copy_gpt_to_new_mbr(i, new_mbr_part_count);
@@ -345,9 +354,9 @@ static VOID generate_hybrid_mbr(VOID) {
         // set active on the first matching partition
         if (count_active == 0) {
             for (i = 0; i < new_mbr_part_count; i++) {
-                if ((iter >= 0 && (new_mbr_parts[i].mbr_type == 0x07 ||    // NTFS
-                                   new_mbr_parts[i].mbr_type == 0x0b ||    // FAT32
-                                   new_mbr_parts[i].mbr_type == 0x0c)) ||  // FAT32 (LBA)
+                if (((new_mbr_parts[i].mbr_type == 0x07 ||    // NTFS
+                      new_mbr_parts[i].mbr_type == 0x0b ||    // FAT32
+                      new_mbr_parts[i].mbr_type == 0x0c)) ||  // FAT32 (LBA)
                     (iter >= 1 && (new_mbr_parts[i].mbr_type == 0x83)) ||  // Linux
                     (iter >= 2 && i > 0)) {
                     new_mbr_parts[i].active = TRUE;
@@ -370,7 +379,7 @@ static VOID generate_hybrid_mbr(VOID) {
                     count_active++;
                 }
         }
-    }
+    } // for
 } // VOID generate_hybrid_mbr()
 
 // Examine partitions and decide whether a rewrite is in order.
@@ -485,7 +494,7 @@ UINTN gptsync(VOID)
     UINTN   status_gpt, status_mbr;
     BOOLEAN proceed = FALSE;
 
-    Print(L"gptsync version %s\ncopyright (c) 2006-2007 Christoph Pfisterer & 2013 Roderick W. Smith\n", VERSION);
+    Print(L"gptsync version %s\ncopyright (c) 2006-2007 Christoph Pfisterer & 2013 Roderick W. Smith\n", REFIND_VERSION);
 
     // get full information from disk
     status_gpt = read_gpt();