From: Steve Kenton <address@hidden> --- grub-core/commands/probe.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index cf2793e1d..5dd1a6bc5 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -16,6 +16,7 @@ * along with GRUB. If not, see <http://www.gnu.org/licenses/>. */ +#include <stddef.h> #include <grub/types.h> #include <grub/misc.h> #include <grub/mm.h> @@ -24,6 +25,8 @@ #include <grub/device.h> #include <grub/disk.h> #include <grub/partition.h> +#include <grub/gpt_partition.h> +#include <grub/i386/pc/boot.h> #include <grub/net.h> #include <grub/fs.h> #include <grub/file.h> @@ -45,6 +48,7 @@ static const struct grub_arg_option options[] = {"fs", 'f', 0, N_("Determine filesystem type."), 0, 0}, {"fs-uuid", 'u', 0, N_("Determine filesystem UUID."), 0, 0}, {"label", 'l', 0, N_("Determine filesystem label."), 0, 0}, + {"partuuid", 'g', 0, N_("Determine partition GUID/UUID."), 0, 0}, /* GUID but Linux kernel calls it "PARTUUID" */ {0, 0, 0, 0, 0, 0} }; @@ -154,6 +158,61 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) grub_device_close (dev); return GRUB_ERR_NONE; } + if (state[6].set) + { + char *partuuid = NULL; /* NULL to silence a spurious GCC warning */ + /* Nested partitions are not supported for now. */ + /* Non-nested partitions must have dev->disk->partition->parent == NULL */ + if (dev->disk && dev->disk->partition && dev->disk->partition->parent == NULL) + { + grub_partition_t p = dev->disk->partition; + if (grub_strcmp (p->partmap->name, "msdos") == 0) + { + /* little-endian 4-byte NT disk id "GUID" in the MBR */ + grub_uint8_t diskid[4]; + dev->disk->partition = p->parent; + grub_uint32_t nt_disk_sig; + err = grub_disk_read (dev->disk, 0, GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, sizeof(diskid), diskid); + dev->disk->partition = p; + if (err) + return grub_errno; + /* partition numbers are one-based */ + partuuid = grub_xasprintf ("%02x%02x%02x%02x-%02x", + diskid[3], diskid[2], diskid[1], disk[0], + p->number + 1); + } + else if (grub_strcmp (p->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry e; + dev->disk->partition = p->parent; + err = grub_disk_read (dev->disk, p->offset, p->index, sizeof e, &e); + dev->disk->partition = p; + if (err) + return grub_errno; + + partuuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + e.guid[3], e.guid[2], e.guid[1], e.guid[0], + e.guid[5], e.guid[4], + e.guid[7], e.guid[6], + e.guid[8], e.guid[9], + e.guid[10], e.guid[11], e.guid[12], e.guid[13], e.guid[14], e.guid[15]); + } + else + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("partition map %s does not support partition UUIDs"), + dev->disk->partition->partmap->name); + } + else + partuuid = grub_strdup (""); /* a freeable empty string */ + + if (state[0].set) + grub_env_set (state[0].arg, partuuid); + else + grub_printf ("%s", partuuid); + grub_free (partuuid); + grub_device_close (dev); + return GRUB_ERR_NONE; + } grub_device_close (dev); return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised target"); } -- 2.12.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel