2008-06-01 Robert Millan <rmh@aybabtu.com>

*  util/biosdisk.c (get_drive): Verify that `map[i].drive' is non-NULL
        before dereferencing it.

        * fs/fat.c (struct grub_fat_bpb): Move fat32-specific fields into a
        union with fat12/fat16-specific ones.  Add some new fields, including
        `num_serial' for both versions.
        (struct grub_fat_data): Add `uuid' member.
        (grub_fat_mount): Refer to fat32-specific fields in `bpb' by their new
        names.  Initialize `data->uuid' using `num_serial'.
        (grub_fat_uuid): New function.
        (grub_fat_fs): Reference grub_fat_uuid() in `uuid' struct member.

        * fs/reiserfs.c (grub_reiserfs_superblock): Add `uuid' field.
        (grub_reiserfs_uuid): New function.
        (grub_reiserfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct
        member.

        * fs/xfs.c (grub_xfs_sblock): Add `uuid' field.
        (grub_xfs_uuid): New function.
        (grub_xfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct member.
This commit is contained in:
robertmh 2008-06-01 13:30:00 +00:00
parent 1385c5bb3d
commit 00c108a446
5 changed files with 169 additions and 19 deletions

View file

@ -1,3 +1,26 @@
2008-06-01 Robert Millan <rmh@aybabtu.com>
* util/biosdisk.c (get_drive): Verify that `map[i].drive' is non-NULL
before dereferencing it.
* fs/fat.c (struct grub_fat_bpb): Move fat32-specific fields into a
union with fat12/fat16-specific ones. Add some new fields, including
`num_serial' for both versions.
(struct grub_fat_data): Add `uuid' member.
(grub_fat_mount): Refer to fat32-specific fields in `bpb' by their new
names. Initialize `data->uuid' using `num_serial'.
(grub_fat_uuid): New function.
(grub_fat_fs): Reference grub_fat_uuid() in `uuid' struct member.
* fs/reiserfs.c (grub_reiserfs_superblock): Add `uuid' field.
(grub_reiserfs_uuid): New function.
(grub_reiserfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct
member.
* fs/xfs.c (grub_xfs_sblock): Add `uuid' field.
(grub_xfs_uuid): New function.
(grub_xfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct member.
2008-06-01 Robert Millan <rmh@aybabtu.com> 2008-06-01 Robert Millan <rmh@aybabtu.com>
* util/update-grub_lib.in (prepare_grub_to_access_device): Generate * util/update-grub_lib.in (prepare_grub_to_access_device): Generate

View file

@ -1,7 +1,7 @@
/* fat.c - FAT filesystem */ /* fat.c - FAT filesystem */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007 Free Software Foundation, Inc. * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -61,14 +61,34 @@ struct grub_fat_bpb
grub_uint16_t num_heads; grub_uint16_t num_heads;
grub_uint32_t num_hidden_sectors; grub_uint32_t num_hidden_sectors;
grub_uint32_t num_total_sectors_32; grub_uint32_t num_total_sectors_32;
union
/* The following fields are only used by FAT32. */ {
struct
{
grub_uint8_t num_ph_drive;
grub_uint8_t reserved;
grub_uint8_t boot_sig;
grub_uint32_t num_serial;
grub_uint8_t label[11];
grub_uint8_t fstype[8];
} __attribute__ ((packed)) fat12_or_fat16;
struct
{
grub_uint32_t sectors_per_fat_32; grub_uint32_t sectors_per_fat_32;
grub_uint16_t extended_flags; grub_uint16_t extended_flags;
grub_uint16_t fs_version; grub_uint16_t fs_version;
grub_uint32_t root_cluster; grub_uint32_t root_cluster;
grub_uint16_t fs_info; grub_uint16_t fs_info;
grub_uint16_t backup_boot_sector; grub_uint16_t backup_boot_sector;
grub_uint8_t reserved[12];
grub_uint8_t num_ph_drive;
grub_uint8_t reserved1;
grub_uint8_t boot_sig;
grub_uint32_t num_serial;
grub_uint8_t label[11];
grub_uint8_t fstype[8];
} __attribute__ ((packed)) fat32;
} __attribute__ ((packed)) version_specific;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_fat_dir_entry struct grub_fat_dir_entry
@ -122,6 +142,8 @@ struct grub_fat_data
grub_uint32_t file_cluster; grub_uint32_t file_cluster;
grub_uint32_t cur_cluster_num; grub_uint32_t cur_cluster_num;
grub_uint32_t cur_cluster; grub_uint32_t cur_cluster;
grub_uint16_t uuid[2];
}; };
#ifndef GRUB_UTIL #ifndef GRUB_UTIL
@ -183,7 +205,7 @@ grub_fat_mount (grub_disk_t disk)
data->sectors_per_fat = ((bpb.sectors_per_fat_16 data->sectors_per_fat = ((bpb.sectors_per_fat_16
? grub_le_to_cpu16 (bpb.sectors_per_fat_16) ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
: grub_le_to_cpu32 (bpb.sectors_per_fat_32)) : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
<< data->logical_sector_bits); << data->logical_sector_bits);
if (data->sectors_per_fat == 0) if (data->sectors_per_fat == 0)
goto fail; goto fail;
@ -219,9 +241,9 @@ grub_fat_mount (grub_disk_t disk)
if (! bpb.sectors_per_fat_16) if (! bpb.sectors_per_fat_16)
{ {
/* FAT32. */ /* FAT32. */
grub_uint16_t flags = grub_le_to_cpu16 (bpb.extended_flags); grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster); data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
data->fat_size = 32; data->fat_size = 32;
data->cluster_eof_mark = 0x0ffffff8; data->cluster_eof_mark = 0x0ffffff8;
@ -236,7 +258,7 @@ grub_fat_mount (grub_disk_t disk)
data->fat_sector += active_fat * data->sectors_per_fat; data->fat_sector += active_fat * data->sectors_per_fat;
} }
if (bpb.num_root_entries != 0 || bpb.fs_version != 0) if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0)
goto fail; goto fail;
} }
else else
@ -287,6 +309,12 @@ grub_fat_mount (grub_disk_t disk)
magic = 0x0f00; magic = 0x0f00;
} }
/* Serial number. */
if (bpb.sectors_per_fat_16)
*((grub_uint32_t *) &data->uuid) = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
else
*((grub_uint32_t *) &data->uuid) = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
/* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
descriptor, even if it is a so-called superfloppy (e.g. an USB key). descriptor, even if it is a so-called superfloppy (e.g. an USB key).
The check may be too strict for this kind of stupid BIOSes, as The check may be too strict for this kind of stupid BIOSes, as
@ -797,6 +825,34 @@ grub_fat_label (grub_device_t device, char **label)
return grub_errno; return grub_errno;
} }
static grub_err_t
grub_fat_uuid (grub_device_t device, char **uuid)
{
struct grub_fat_data *data;
grub_disk_t disk = device->disk;
#ifndef GRUB_UTIL
grub_dl_ref (my_mod);
#endif
data = grub_fat_mount (disk);
if (data)
{
*uuid = grub_malloc (sizeof ("xxxx-xxxx"));
grub_sprintf (*uuid, "%04x-%04x", data->uuid[1], data->uuid[0]);
}
else
*uuid = NULL;
#ifndef GRUB_UTIL
grub_dl_unref (my_mod);
#endif
grub_free (data);
return grub_errno;
}
static struct grub_fs grub_fat_fs = static struct grub_fs grub_fat_fs =
{ {
.name = "fat", .name = "fat",
@ -805,6 +861,7 @@ static struct grub_fs grub_fat_fs =
.read = grub_fat_read, .read = grub_fat_read,
.close = grub_fat_close, .close = grub_fat_close,
.label = grub_fat_label, .label = grub_fat_label,
.uuid = grub_fat_uuid,
.next = 0 .next = 0
}; };

View file

@ -108,6 +108,8 @@ struct grub_reiserfs_superblock
grub_uint16_t version; grub_uint16_t version;
grub_uint16_t reserved; grub_uint16_t reserved;
grub_uint32_t inode_generation; grub_uint32_t inode_generation;
grub_uint8_t unused[4];
grub_uint16_t uuid[8];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_reiserfs_journal_header struct grub_reiserfs_journal_header
@ -1468,6 +1470,38 @@ grub_reiserfs_label (grub_device_t device, char **label)
return grub_errno; return grub_errno;
} }
static grub_err_t
grub_reiserfs_uuid (grub_device_t device, char **uuid)
{
struct grub_reiserfs_data *data;
grub_disk_t disk = device->disk;
#ifndef GRUB_UTIL
grub_dl_ref (my_mod);
#endif
data = grub_reiserfs_mount (disk);
if (data)
{
*uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
grub_be_to_cpu16 (data->superblock.uuid[0]), grub_be_to_cpu16 (data->superblock.uuid[1]),
grub_be_to_cpu16 (data->superblock.uuid[2]), grub_be_to_cpu16 (data->superblock.uuid[3]),
grub_be_to_cpu16 (data->superblock.uuid[4]), grub_be_to_cpu16 (data->superblock.uuid[5]),
grub_be_to_cpu16 (data->superblock.uuid[6]), grub_be_to_cpu16 (data->superblock.uuid[7]));
}
else
*uuid = NULL;
#ifndef GRUB_UTIL
grub_dl_unref (my_mod);
#endif
grub_free (data);
return grub_errno;
}
static struct grub_fs grub_reiserfs_fs = static struct grub_fs grub_reiserfs_fs =
{ {
.name = "reiserfs", .name = "reiserfs",
@ -1476,6 +1510,7 @@ static struct grub_fs grub_reiserfs_fs =
.read = grub_reiserfs_read, .read = grub_reiserfs_read,
.close = grub_reiserfs_close, .close = grub_reiserfs_close,
.label = grub_reiserfs_label, .label = grub_reiserfs_label,
.uuid = grub_reiserfs_uuid,
.next = 0 .next = 0
}; };

View file

@ -37,17 +37,19 @@ struct grub_xfs_sblock
{ {
grub_uint8_t magic[4]; grub_uint8_t magic[4];
grub_uint32_t bsize; grub_uint32_t bsize;
grub_uint8_t unused1[48]; grub_uint8_t unused1[24];
grub_uint16_t uuid[8];
grub_uint8_t unused2[8];
grub_uint64_t rootino; grub_uint64_t rootino;
grub_uint8_t unused2[20];
grub_uint32_t agsize;
grub_uint8_t unused3[20]; grub_uint8_t unused3[20];
grub_uint32_t agsize;
grub_uint8_t unused4[20];
grub_uint8_t label[12]; grub_uint8_t label[12];
grub_uint8_t log2_bsize; grub_uint8_t log2_bsize;
grub_uint8_t unused4[2]; grub_uint8_t unused5[2];
grub_uint8_t log2_inop; grub_uint8_t log2_inop;
grub_uint8_t log2_agblk; grub_uint8_t log2_agblk;
grub_uint8_t unused5[67]; grub_uint8_t unused6[67];
grub_uint8_t log2_dirblk; grub_uint8_t log2_dirblk;
} __attribute__ ((packed)); } __attribute__ ((packed));
@ -763,6 +765,38 @@ grub_xfs_label (grub_device_t device, char **label)
return grub_errno; return grub_errno;
} }
static grub_err_t
grub_xfs_uuid (grub_device_t device, char **uuid)
{
struct grub_xfs_data *data;
grub_disk_t disk = device->disk;
#ifndef GRUB_UTIL
grub_dl_ref (my_mod);
#endif
data = grub_xfs_mount (disk);
if (data)
{
*uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]),
grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]),
grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]),
grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7]));
}
else
*uuid = NULL;
#ifndef GRUB_UTIL
grub_dl_unref (my_mod);
#endif
grub_free (data);
return grub_errno;
}
static struct grub_fs grub_xfs_fs = static struct grub_fs grub_xfs_fs =
@ -773,6 +807,7 @@ static struct grub_fs grub_xfs_fs =
.read = grub_xfs_read, .read = grub_xfs_read,
.close = grub_xfs_close, .close = grub_xfs_close,
.label = grub_xfs_label, .label = grub_xfs_label,
.uuid = grub_xfs_uuid,
.next = 0 .next = 0
}; };

View file

@ -117,7 +117,7 @@ get_drive (const char *name)
if (name) if (name)
{ {
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
if (! strcmp (map[i].drive, name)) if (map[i].drive && ! strcmp (map[i].drive, name))
return i; return i;
} }
else else