memdisk: don't key FAT vs MBR on the type of disk
authorH. Peter Anvin <hpa@zytor.com>
Tue, 17 Mar 2009 01:50:36 +0000 (18:50 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 17 Mar 2009 01:54:47 +0000 (18:54 -0700)
We can't rely on the disk type to say if this is FAT vs MBR, since we
haven't determined that yet.  Thus, move the FAT test up before the
MBR test; both are heuristic, but the FAT test has much less
probability of false positives, and can be further tightened if
needed.

memdisk/setup.c

index c30a11f..e380435 100644 (file)
@@ -533,32 +533,10 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
     
     max_h = max_s = 0;
 
-    if ( hd_geometry.driveno & 0x80 ) {
-      /* Hard disk image, need to examine the partition table for geometry */
-      const struct ptab_entry *ptab = (const struct ptab_entry *)
-       ((char *)where+hd_geometry.offset+(512-2-4*16));
-
-      for ( i = 0 ; i < 4 ; i++ ) {
-       if ( ptab[i].type ) {
-         s = (ptab[i].start_s & 0x3f);
-         h = ptab[i].start_h + 1;
-         
-         if ( max_h < h ) max_h = h;
-         if ( max_s < s ) max_s = s;
-         
-         s = (ptab[i].end_s & 0x3f);
-         h = ptab[i].end_h + 1;
-         
-         if ( max_h < h ) max_h = h;
-         if ( max_s < s ) max_s = s;
-       }
-      }
-    }
-
     if (!max_h && !max_s) {
-      /* Floppy image, or unpartitioned hard disk... look for a FAT
-        superblock and if we find something that looks enough like one,
-        use geometry from that. */
+      /* Look for a FAT superblock and if we find something that looks
+        enough like one, use geometry from that.  This takes care of
+        megafloppy images and unpartitioned hard disks. */
       const struct fat_extra *extra = NULL;
       const struct fat_super *fs = (const struct fat_super *)
        ((char *)where+hd_geometry.offset);
@@ -582,6 +560,32 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
       }
     }
 
+    if (!max_h && !max_s) {
+      /* Not FAT, assume it is a hard disk image and scan for a
+        partition table */
+      const struct ptab_entry *ptab = (const struct ptab_entry *)
+       ((char *)where+hd_geometry.offset+(512-2-4*16));
+
+      if (*(uint16_t *)((char *)where+512) == 0xaa55)
+       for ( i = 0 ; i < 4 ; i++ ) {
+         if ( ptab[i].type && !(ptab[i].active & 0x7f) ) {
+           s = (ptab[i].start_s & 0x3f);
+           h = ptab[i].start_h + 1;
+           
+           if ( max_h < h ) max_h = h;
+           if ( max_s < s ) max_s = s;
+           
+           s = (ptab[i].end_s & 0x3f);
+           h = ptab[i].end_h + 1;
+           
+           if ( max_h < h ) max_h = h;
+           if ( max_s < s ) max_s = s;
+           
+           hd_geometry.driveno = 0x80; /* Assume hard disk */
+         }
+       }
+    }
+
     if (!max_h)
       max_h = sectors > 2097152 ? 255 : 64;
     if (!max_s)