+
+static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, UINTN *size, VOID **buffer)
+{
+ EFI_STATUS efi_status;
+ char allocate = !(*size);
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, buffer);
+
+ if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) {
+ return efi_status;
+ }
+
+ *buffer = AllocatePool(*size);
+
+ if (!*buffer) {
+ Print(L"Unable to allocate variable buffer\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, *buffer);
+
+ return efi_status;
+} // get_variable()
+
+/*
+ * Check whether we're in Secure Boot and user mode
+ */
+BOOLEAN secure_mode (VOID)
+{
+ EFI_STATUS status;
+ EFI_GUID global_var = EFI_GLOBAL_VARIABLE;
+ UINTN charsize = sizeof(char);
+ UINT8 sb, setupmode;
+ UINT32 attributes;
+
+ status = get_variable(L"SecureBoot", global_var, &attributes, &charsize, (VOID *)&sb);
+
+ /* FIXME - more paranoia here? */
+ if (status != EFI_SUCCESS || sb != 1) {
+ return FALSE;
+ }
+
+ status = get_variable(L"SetupMode", global_var, &attributes, &charsize, (VOID *)&setupmode);
+
+ if (status == EFI_SUCCESS && setupmode == 1) {
+ return FALSE;
+ }
+
+ return TRUE;
+} // secure_mode()
+
+/*
+ * Currently, shim/MOK only works on x86-64 (X64) systems, and some of this code
+ * generates warnings on x86 (IA32) builds, so don't bother compiling it at all
+ * on such systems.
+ *
+ */
+
+#if defined(EFIX64)
+