[parted-devel] [PATCH] Read an msdos partition table from a device with 2K sectors.
Jim Meyering
jim at meyering.net
Wed May 30 21:37:18 UTC 2007
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 <jim at meyering.net>
---
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;
}
More information about the parted-devel
mailing list