[PATCH 3/3] uefi: uefidump: add support for Key#### (LP:#1237263)

Ivan Hu ivan.hu at canonical.com
Wed Oct 9 08:48:27 UTC 2013


Add support for Key#### - The Key#### variable associates a key press
with a single boot option. Each Key#### variable is the name "Key"
appended with a unique four digit hexadecimal number. For example,
Key0001, Key0002, Key00A0, etc.

The Key#### variables have the format, EFI_KEY_OPTION.

Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
---
 src/lib/include/fwts_uefi.h  |   26 +++++++++++++
 src/uefi/uefidump/uefidump.c |   85 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/src/lib/include/fwts_uefi.h b/src/lib/include/fwts_uefi.h
index d38903e..bb5d513 100644
--- a/src/lib/include/fwts_uefi.h
+++ b/src/lib/include/fwts_uefi.h
@@ -115,6 +115,32 @@ typedef struct {
         fwts_uefi_dev_path unused_file_path_list[1];
 } __attribute__((packed)) fwts_uefi_load_option;
 
+typedef union {
+	struct {
+		uint32_t revision	: 8;
+		uint32_t shiftpressed	: 1;
+		uint32_t controlpressed	: 1;
+		uint32_t altpressed	: 1;
+		uint32_t logopressed	: 1;
+		uint32_t menupressed	: 1;
+		uint32_t sysreqpressed	: 1;
+		uint32_t reserved	: 16;
+		uint32_t inputkeycount	: 2;
+	} options;
+	uint32_t packedvalue;
+} __attribute__((packed)) fwts_uefi_boot_key_data;
+
+typedef struct {
+        fwts_uefi_boot_key_data keydata;
+        uint32_t bootoptioncrc;
+        uint16_t bootoption;
+} __attribute__((packed)) fwts_uefi_key_option;
+
+typedef struct {
+        uint16_t scancode;
+        uint16_t unicodechar;
+} __attribute__((packed)) fwts_uefi_input_key;
+
 typedef enum {
 	FWTS_UEFI_HARDWARE_DEV_PATH_TYPE =		(0x01),
 	FWTS_UEFI_ACPI_DEVICE_PATH_TYPE =		(0x02),
diff --git a/src/uefi/uefidump/uefidump.c b/src/uefi/uefidump/uefidump.c
index 4a736c9..de2bd4e 100644
--- a/src/uefi/uefidump/uefidump.c
+++ b/src/uefi/uefidump/uefidump.c
@@ -768,6 +768,83 @@ static void uefidump_info_driverdev(fwts_framework *fw, fwts_uefi_var *var)
 	free(path);
 }
 
+static void uefidump_info_keyoption(fwts_framework *fw, fwts_uefi_var *var)
+{
+	fwts_uefi_key_option *key_option = (fwts_uefi_key_option *)var->data;
+  	fwts_uefi_input_key *inputkey = (fwts_uefi_input_key *) (((uint8_t *) var->data) + sizeof (fwts_uefi_key_option));
+	char str[300];
+	uint16_t keyoptionsize;
+	int index = 0;
+
+	*str = 0;
+	keyoptionsize = sizeof (fwts_uefi_key_option) + key_option->keydata.options.inputkeycount * sizeof (fwts_uefi_input_key);
+
+	if (var->datalen != keyoptionsize) {
+		uefidump_var_hexdump(fw, var);
+		return;
+	}
+
+	if (key_option->keydata.options.shiftpressed)
+		strcat(str, "ShiftPressed");
+
+	if (key_option->keydata.options.controlpressed) {
+		if (*str)
+			strcat(str, ",");
+		strcat(str, "ControlPressed");
+	}
+
+	if (key_option->keydata.options.altpressed) {
+		if (*str)
+			strcat(str, ",");
+		strcat(str, "AltPressed");
+	}
+
+	if (key_option->keydata.options.logopressed) {
+		if (*str)
+			strcat(str, ",");
+		strcat(str, "LogoPressed");
+	}
+
+	if (key_option->keydata.options.menupressed) {
+		if (*str)
+			strcat(str, ",");
+		strcat(str, "MenuPressed");
+	}
+
+	if (key_option->keydata.options.sysreqpressed) {
+		if (*str)
+			strcat(str, ",");
+		strcat(str, "SysReqPressed");
+	}
+
+	if (*str != 0)
+		fwts_log_info_verbatum(fw, "  PackedValue: 0x%8.8" PRIx32 " (%s).", key_option->keydata.packedvalue, str);
+	else
+		fwts_log_info_verbatum(fw, "  PackedValue: 0x%8.8" PRIx32 ".", key_option->keydata.packedvalue);
+	
+	fwts_log_info_verbatum(fw, "  BootOptionCrc: 0x%8.8" PRIx32 ".", key_option->bootoptioncrc);
+	fwts_log_info_verbatum(fw, "  BootOption: %4.4" PRIx16 ".", key_option->bootoption);
+
+	do {
+		fwts_log_info_verbatum(fw, "  ScanCode: 0x%4.4" PRIx16 ".", inputkey[index].scancode);
+
+		/*
+		 * The UnicodeChar is the actual printable character or is zero if the key does not represent a 
+		 * printable character (control key, function key, etc.).
+		 */
+		if (inputkey[index].unicodechar == 0)
+			fwts_log_info_verbatum(fw, "  UnicodeChar: 0x%4.4" PRIx16 ".", inputkey[index].unicodechar);
+		else
+			fwts_log_info_verbatum(fw, "  UnicodeChar: 0x%4.4" PRIx16 " (%c).",
+										inputkey[index].unicodechar,
+										(char)inputkey[index].unicodechar);
+
+		index++;
+
+	} while (index < key_option->keydata.options.inputkeycount);
+
+}
+
 static uefidump_info uefidump_info_table[] = {
 	{ "PlatformLangCodes",	uefidump_info_platform_langcodes },
 	{ "PlatformLang",	uefidump_info_platform_lang },
@@ -835,6 +912,14 @@ static void uefidump_var(fwts_framework *fw, fwts_uefi_var *var)
 		return;
 	}
 
+	/* Check the key option key####. #### is a printed hex value */
+	if ((strlen(varname) == 7) && (strncmp(varname, "Key", 3) == 0)
+			&& isxdigit(varname[3]) && isxdigit(varname[4])
+			&& isxdigit(varname[5]) && isxdigit(varname[6])) {
+		uefidump_info_keyoption(fw, var);
+		return;
+	}
+
 	/* otherwise just do a plain old hex dump */
 	uefidump_var_hexdump(fw, var);
 }
-- 
1.7.9.5




More information about the fwts-devel mailing list