Signed-off-by: Laszlo Ersek lersek@redhat.com --- src/smbios.h | 1 + src/smbios.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/src/smbios.h b/src/smbios.h index 9d54e80..c1fe7f6 100644 --- a/src/smbios.h +++ b/src/smbios.h @@ -165,4 +165,5 @@ struct smbios_type_127 { struct smbios_structure_header header; } PACKED;
+const u8 *smbios_locate_uuid(const struct smbios_entry_point *ep); #endif // smbios.h diff --git a/src/smbios.c b/src/smbios.c index fc84aad..5874bec 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -521,3 +521,50 @@ smbios_init(void) smbios_entry_point_init(max_struct_size, p - start, start, nr_structs); free(start); } + +const u8 * +smbios_locate_uuid(const struct smbios_entry_point *ep) +{ + u32 addr, end; + + if (ep == NULL) + return NULL; + + addr = ep->structure_table_address; + end = addr + ep->structure_table_length; + + /* the following takes care of any initial wraparound too */ + while (addr < end) { + const struct smbios_structure_header *hdr; + + /* partial structure header */ + if (end - addr < sizeof(struct smbios_structure_header)) + return NULL; + + hdr = (struct smbios_structure_header *)addr; + + /* partial structure */ + if (end - addr < hdr->length) + return NULL; + + /* any Type 1 structure version will do that has the UUID */ + if (hdr->type == 1 && + hdr->length >= offsetof(struct smbios_type_1, uuid) + 16) + return (u8 *)(addr + offsetof(struct smbios_type_1, uuid)); + + /* done with formatted area, skip string-set */ + addr += hdr->length; + + while (end - addr >= 2 && + (*(u8 *)addr != '\0' || + *(u8 *)(addr+1) != '\0')) + ++addr; + + /* structure terminator not found */ + if (end - addr < 2) + return NULL; + + addr += 2; + } + return NULL; +}