/*
libparted
- Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1998-2000, 2002, 2004, 2007, 2009-2012 Free Software
+ Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <fcntl.h>
#include <errno.h>
+/* Reads in the boot sector (superblock), and does a minimum of sanity
+ * checking. The goals are:
+ * - to detect fat file systems, even if they are damaged [i.e. not
+ * return an error / throw an exception]
+ * - to fail detection if there's not enough information for
+ * fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
+ */
int
-fat_boot_sector_is_sane (const FatBootSector* bs)
+fat_boot_sector_read (FatBootSector* bs, const PedGeometry *geom)
{
- PED_ASSERT (bs != NULL, return 0);
+ PED_ASSERT (bs != NULL);
+ PED_ASSERT (geom != NULL);
+
+ if (!ped_geometry_read (geom, bs, 0, 1))
+ return 0;
if (PED_LE16_TO_CPU (bs->boot_sign) != 0xAA55) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
return 1;
}
-/* Reads in the boot sector (superblock), and does a minimum of sanity
- * checking. The goals are:
- * - to detect fat file systems, even if they are damaged [i.e. not
- * return an error / throw an exception]
- * - to fail detection if there's not enough information for
- * fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
- */
-int
-fat_boot_sector_read (FatBootSector* bs, const PedGeometry *geom)
-{
- PED_ASSERT (bs != NULL, return 0);
- PED_ASSERT (geom != NULL, return 0);
-
- if (!ped_geometry_read (geom, bs, 0, 1))
- return 0;
-
- return fat_boot_sector_is_sane (bs);
-}
-
/*
Don't trust the FAT12, FAT16 or FAT32 label string.
*/
return FAT_TYPE_FAT12;
}
+static int
+_fat_table_entry_size (FatType fat_type)
+{
+ switch (fat_type) {
+ case FAT_TYPE_FAT12:
+ return 2; /* FIXME: how? */
+
+ case FAT_TYPE_FAT16:
+ return 2;
+
+ case FAT_TYPE_FAT32:
+ return 4;
+ }
+
+ return 0;
+}
+
/* Analyses the boot sector, and sticks appropriate numbers in
fs->type_specific.
FatSpecific* fs_info = FAT_SPECIFIC (fs);
int fat_entry_size;
- PED_ASSERT (bs != NULL, return 0);
+ PED_ASSERT (bs != NULL);
if (PED_LE16_TO_CPU (bs->sector_size) != 512) {
if (ped_exception_throw (
switch (ped_exception_throw (
PED_EXCEPTION_ERROR,
- PED_EXCEPTION_FIX + PED_EXCEPTION_IGNORE
- + PED_EXCEPTION_CANCEL,
+ PED_EXCEPTION_IGNORE_CANCEL,
_("The file system's CHS geometry is (%d, %d, %d), "
"which is invalid. The partition table's CHS "
- "geometry is (%d, %d, %d). If you select Ignore, "
- "the file system's CHS geometry will be left "
- "unchanged. If you select Fix, the file system's "
- "CHS geometry will be set to match the partition "
- "table's CHS geometry."),
+ "geometry is (%d, %d, %d)."),
cyl_count, fs_info->heads, fs_info->sectors_per_track,
bios_geom->cylinders, bios_geom->heads,
bios_geom->sectors)) {
- case PED_EXCEPTION_FIX:
- fs_info->sectors_per_track = bios_geom->sectors;
- fs_info->heads = bios_geom->heads;
- bs->secs_track
- = PED_CPU_TO_LE16 (fs_info->sectors_per_track);
- bs->heads = PED_CPU_TO_LE16 (fs_info->heads);
- if (!fat_boot_sector_write (bs, fs))
- return 0;
- break;
-
case PED_EXCEPTION_CANCEL:
return 0;
= (fs_info->sector_count - fs_info->cluster_offset)
/ fs_info->cluster_sectors;
- fat_entry_size = fat_table_entry_size (fs_info->fat_type);
+ fat_entry_size = _fat_table_entry_size (fs_info->fat_type);
if (fs_info->cluster_count + 2
> fs_info->fat_sectors * 512 / fat_entry_size)
fs_info->cluster_count
}
#ifndef DISCOVER_ONLY
-int
-fat_boot_sector_set_boot_code (FatBootSector* bs)
-{
- PED_ASSERT (bs != NULL, return 0);
-
- memset (bs, 0, 512);
- memcpy (bs->boot_jump, FAT_BOOT_JUMP, 3);
- memcpy (bs->u.fat32.boot_code, FAT_BOOT_CODE, FAT_BOOT_CODE_LENGTH);
- return 1;
-}
-
-int
-fat_boot_sector_generate (FatBootSector* bs, const PedFileSystem* fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (bs != NULL, return 0);
-
- memcpy (bs->system_id, "MSWIN4.1", 8);
- bs->sector_size = PED_CPU_TO_LE16 (fs_info->logical_sector_size * 512);
- bs->cluster_size = fs_info->cluster_sectors
- / fs_info->logical_sector_size;
- bs->reserved = PED_CPU_TO_LE16 (fs_info->fat_offset
- / fs_info->logical_sector_size);
- bs->fats = fs_info->fat_table_count;
-
- bs->dir_entries = (fs_info->fat_type == FAT_TYPE_FAT16)
- ? PED_CPU_TO_LE16 (fs_info->root_dir_entry_count)
- : 0;
-
- if (fs_info->sector_count / fs_info->logical_sector_size > 0xffff
- || fs_info->fat_type == FAT_TYPE_FAT32) {
- bs->sectors = 0;
- bs->sector_count = PED_CPU_TO_LE32 (fs_info->sector_count
- / fs_info->logical_sector_size);
- } else {
- bs->sectors = PED_CPU_TO_LE16 (fs_info->sector_count
- / fs_info->logical_sector_size);
- bs->sector_count = 0;
- }
-
- bs->media = 0xf8;
-
- bs->secs_track = PED_CPU_TO_LE16 (fs_info->sectors_per_track);
- bs->heads = PED_CPU_TO_LE16 (fs_info->heads);
- bs->hidden = PED_CPU_TO_LE32 (fs->geom->start);
-
- if (fs_info->fat_type == FAT_TYPE_FAT32) {
- bs->fat_length = 0;
- bs->u.fat32.fat_length = PED_CPU_TO_LE32 (fs_info->fat_sectors
- / fs_info->logical_sector_size);
- bs->u.fat32.flags = 0; /* FIXME: what the hell are these? */
- bs->u.fat32.version = 0; /* must be 0, for Win98 bootstrap */
- bs->u.fat32.root_dir_cluster
- = PED_CPU_TO_LE32 (fs_info->root_cluster);
- bs->u.fat32.info_sector
- = PED_CPU_TO_LE16 (fs_info->info_sector_offset
- / fs_info->logical_sector_size);
- bs->u.fat32.backup_sector
- = PED_CPU_TO_LE16 (fs_info->boot_sector_backup_offset
- / fs_info->logical_sector_size);
-
- bs->u.fat32.drive_num = 0x80; /* _ALWAYS_ 0x80. silly DOS */
-
- memset (bs->u.fat32.empty_1, 0, 12);
-
- bs->u.fat32.ext_signature = 0x29;
- bs->u.fat32.serial_number
- = PED_CPU_TO_LE32 (fs_info->serial_number);
- memcpy (bs->u.fat32.volume_name, "NO NAME ", 11);
- memcpy (bs->u.fat32.fat_name, "FAT32 ", 8);
- } else {
- bs->fat_length
- = PED_CPU_TO_LE16 (fs_info->fat_sectors
- / fs_info->logical_sector_size);
-
- bs->u.fat16.drive_num = 0x80; /* _ALWAYS_ 0x80. silly DOS */
-
- bs->u.fat16.ext_signature = 0x29;
- bs->u.fat16.serial_number
- = PED_CPU_TO_LE32 (fs_info->serial_number);
- memcpy (bs->u.fat16.volume_name, "NO NAME ", 11);
- memcpy (bs->u.fat16.fat_name, "FAT16 ", 8);
- }
-
- bs->boot_sign = PED_CPU_TO_LE16 (0xaa55);
-
- return 1;
-}
-
-int
-fat_boot_sector_write (const FatBootSector* bs, PedFileSystem* fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (bs != NULL, return 0);
-
- /* Allocate a sector-sized buffer and copy bs into it
- at the beginning. Fill any remainder with zeros. */
- size_t buf_len = fs->geom->dev->sector_size;
- char *buf = ped_malloc (buf_len);
- memcpy (buf, bs, sizeof *bs);
- memset (buf + sizeof *bs, 0, buf_len - sizeof *bs);
-
- int write_ok
- = (ped_geometry_write (fs->geom, buf, 0, 1)
- && (fs_info->fat_type != FAT_TYPE_FAT32
- || ped_geometry_write (fs->geom, buf,
- fs_info->boot_sector_backup_offset, 1)));
- free (buf);
- if (write_ok)
- ped_geometry_sync (fs->geom);
- return write_ok;
-}
int
fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs)
FatSpecific* fs_info = FAT_SPECIFIC (fs);
int status;
- PED_ASSERT (is != NULL, return 0);
+ PED_ASSERT (is != NULL);
if (!ped_geometry_read (fs->geom, is, fs_info->info_sector_offset, 1))
return 0;
}
return 1;
}
-
-int
-fat_info_sector_generate (FatInfoSector* is, const PedFileSystem* fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (is != NULL, return 0);
-
- fat_table_count_stats (fs_info->fat);
-
- memset (is, 0, 512);
-
- is->signature_1 = PED_CPU_TO_LE32 (FAT32_INFO_MAGIC1);
- is->signature_2 = PED_CPU_TO_LE32 (FAT32_INFO_MAGIC2);
- is->free_clusters = PED_CPU_TO_LE32 (fs_info->fat->free_cluster_count);
- is->next_cluster = PED_CPU_TO_LE32 (fs_info->fat->last_alloc);
- is->signature_3 = PED_CPU_TO_LE16 (FAT32_INFO_MAGIC3);
-
- return 1;
-}
-
-int
-fat_info_sector_write (const FatInfoSector* is, PedFileSystem *fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (is != NULL, return 0);
-
- if (!ped_geometry_write (fs->geom, is, fs_info->info_sector_offset, 1))
- return 0;
- return ped_geometry_sync (fs->geom);
-}
#endif /* !DISCOVER_ONLY */
-