I happened to poke at a CD with an empty msdos partition, and tried
running parted on it.  It wasn't recognized, because read support for
2KB-sectors is still incomplete.  So I taught dos.c about 2KB sectors,
and now parted can print my empty partition table.

I can test with this particular CD, but an automated test would require
a writable device with 2KB sectors, and I don't have one of those.

        Read an msdos partition table from a device with 2K sectors.
        * libparted/labels/dos.c: Include <stdbool.h>.
        (msdos_probe): Don't hard-code 512.
        Use read_sector, not ped_device_read.
        Adapt to changed type of "part_table".
        Now that "label" is malloc'd, be sure to free it before returning.
        (read_table): Likewise.

Signed-off-by: Jim Meyering <[EMAIL PROTECTED]>
---
 libparted/labels/dos.c |   85 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
index 50fadfd..76abe35 100644
--- a/libparted/labels/dos.c
+++ b/libparted/labels/dos.c
@@ -21,6 +21,7 @@
 #include <config.h>

 #include <sys/time.h>
+#include <stdbool.h>
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
@@ -150,46 +151,67 @@ typedef struct {

 static PedDiskType msdos_disk_type;

+/* FIXME: factor out this function: copied from aix.c, with changes to
+   the description, and an added sector number argument.
+   Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
+   storage.  If the read fails, free the memory and return zero without
+   modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
+static int
+read_sector (const PedDevice *dev, PedSector sector_num, char **buf)
+{
+       char *b = ped_malloc (dev->sector_size);
+       PED_ASSERT (b != NULL, return 0);
+       if (!ped_device_read (dev, b, sector_num, 1)) {
+               ped_free (b);
+               return 0;
+       }
+       *buf = b;
+       return 1;
+}
+
 static int
 msdos_probe (const PedDevice *dev)
 {
        PedDiskType*    disk_type;
-       DosRawTable     part_table;
+       DosRawTable*    part_table;
        int             i;

        PED_ASSERT (dev != NULL, return 0);

-        if (dev->sector_size != 512)
+        if (dev->sector_size < sizeof *part_table)
                 return 0;

-       if (!ped_device_read (dev, &part_table, 0, 1))
+       char *label;
+       if (!read_sector (dev, 0, &label))
                return 0;

+        part_table = (DosRawTable *) label;
+
        /* check magic */
-       if (PED_LE16_TO_CPU (part_table.magic) != MSDOS_MAGIC)
-               return 0;
+       if (PED_LE16_TO_CPU (part_table->magic) != MSDOS_MAGIC)
+               goto probe_fail;

        /* if this is a FAT fs, fail here.  Note that the Smart Boot Manager
         * Loader (SBML) signature indicates a partition table, not a file
         * system.
         */
-       if ((!strncmp (part_table.boot_code + 0x36, "FAT", 3)
-           && strncmp (part_table.boot_code + 0x40, "SBML", 4) != 0)
-           || !strncmp (part_table.boot_code + 0x52, "FAT", 3))
-               return 0;
+       if ((!strncmp (part_table->boot_code + 0x36, "FAT", 3)
+           && strncmp (part_table->boot_code + 0x40, "SBML", 4) != 0)
+           || !strncmp (part_table->boot_code + 0x52, "FAT", 3))
+               goto probe_fail;

        /* If this is a GPT disk, fail here */
        for (i = 0; i < 4; i++) {
-               if (part_table.partitions[i].type == PARTITION_GPT)
-                       return 0;
+               if (part_table->partitions[i].type == PARTITION_GPT)
+                       goto probe_fail;
        }

        /* If this is an AIX Physical Volume, fail here.  IBMA in EBCDIC */
-       if (part_table.boot_code[0] == (char) 0xc9 && 
-           part_table.boot_code[1] == (char) 0xc2 &&
-           part_table.boot_code[2] == (char) 0xd4 && 
-           part_table.boot_code[3] == (char) 0xc1)
-               return 0;
+       if (part_table->boot_code[0] == (char) 0xc9 &&
+           part_table->boot_code[1] == (char) 0xc2 &&
+           part_table->boot_code[2] == (char) 0xd4 &&
+           part_table->boot_code[3] == (char) 0xc1)
+               goto probe_fail;

 #ifdef ENABLE_PC98
        /* HACK: it's impossible to tell PC98 and msdos disk labels apart.
@@ -198,10 +220,15 @@ msdos_probe (const PedDevice *dev)
         * is more reliable */
        disk_type = ped_disk_type_get ("pc98");
        if (disk_type && disk_type->ops->probe (dev))
-               return 0;
+               goto probe_fail;
 #endif /* ENABLE_PC98 */

+       free (label);
        return 1;
+
+ probe_fail:
+       free (label);
+       return 0;
 }

 static PedDisk*
@@ -802,7 +829,7 @@ static int
 read_table (PedDisk* disk, PedSector sector, int is_extended_table)
 {
        int                     i;
-       DosRawTable             table;
+       DosRawTable*            table;
        DosRawPartition*        raw_part;
        PedPartition*           part;
        PedPartitionType        type;
@@ -812,31 +839,34 @@ read_table (PedDisk* disk, PedSector sector, int 
is_extended_table)
        PED_ASSERT (disk != NULL, return 0);
        PED_ASSERT (disk->dev != NULL, return 0);

-       if (!ped_device_read (disk->dev, (void*) &table, sector, 1))
+       char *label = NULL;
+       if (!read_sector (disk->dev, sector, &label))
                goto error;

+        table = (DosRawTable *) label;
+
        /* weird: empty extended partitions are filled with 0xf6 by PM */
        if (is_extended_table
-           && PED_LE16_TO_CPU (table.magic) == PARTITION_MAGIC_MAGIC)
-               return 1;
+           && PED_LE16_TO_CPU (table->magic) == PARTITION_MAGIC_MAGIC)
+               goto read_ok;

 #ifndef DISCOVER_ONLY
-       if (PED_LE16_TO_CPU (table.magic) != MSDOS_MAGIC) {
+       if (PED_LE16_TO_CPU (table->magic) != MSDOS_MAGIC) {
                if (ped_exception_throw (
                        PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL,
                        _("Invalid partition table on %s "
                          "-- wrong signature %x."),
                        disk->dev->path,
-                       PED_LE16_TO_CPU (table.magic))
+                       PED_LE16_TO_CPU (table->magic))
                                != PED_EXCEPTION_IGNORE)
                        goto error;
-               return 1;
+               goto read_ok;
        }
 #endif

        /* parse the partitions from this table */
        for (i = 0; i < 4; i++) {
-               raw_part = &table.partitions [i];
+               raw_part = &table->partitions [i];
                if (raw_part->type == PARTITION_EMPTY || !raw_part->length)
                        continue;

@@ -892,7 +922,7 @@ read_table (PedDisk* disk, PedSector sector, int 
is_extended_table)
                for (i = 0; i < 4; i++) {
                        PedSector part_start;

-                       raw_part = &table.partitions [i];
+                       raw_part = &table->partitions [i];
                        if (!raw_part_is_extended (raw_part))
                                continue;

@@ -910,9 +940,12 @@ read_table (PedDisk* disk, PedSector sector, int 
is_extended_table)
                }
        }

+read_ok:
+       free (label);
        return 1;

 error:
+       free (label);
        ped_disk_delete_all (disk);
        return 0;
 }

_______________________________________________
parted-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/parted-devel

Reply via email to