grub_err_t grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, void *data, grub_size_t datasize) { grub_efi_status_t status; grub_efi_runtime_services_t *r; grub_efi_char16_t *var16; grub_size_t len, len16; len = grub_strlen (var); len16 = len * GRUB_MAX_UTF16_PER_UTF8; var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); if (!var16) return grub_errno; len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); var16[len16] = 0; r = grub_efi_system_table->runtime_services; status = efi_call_5 (r->set_variable, var16, guid, (GRUB_EFI_VARIABLE_NON_VOLATILE | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), datasize, data); if (status == GRUB_EFI_SUCCESS) return GRUB_ERR_NONE; return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); }
void * grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, grub_size_t *datasize_out) { grub_efi_status_t status; grub_efi_uintn_t datasize = 0; grub_efi_runtime_services_t *r; grub_efi_char16_t *var16; void *data; grub_size_t len, len16; *datasize_out = 0; len = grub_strlen (var); len16 = len * GRUB_MAX_UTF16_PER_UTF8; var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); if (!var16) return NULL; len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); var16[len16] = 0; r = grub_efi_system_table->runtime_services; status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL); if (!datasize) return NULL; data = grub_malloc (datasize); if (!data) { grub_free (var16); return NULL; } status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data); grub_free (var16); if (status == GRUB_EFI_SUCCESS) { *datasize_out = datasize; return data; } grub_free (data); return NULL; }
int iterate_env (struct grub_env_var *var) { char *guid, *attr, *name, *varname; struct efi_variable *efivar; int len = 0; int i; grub_uint64_t guidcomp; if (grub_memcmp (var->name, "EfiEmu.pnvram.", sizeof ("EfiEmu.pnvram.") - 1) != 0) return 0; guid = var->name + sizeof ("EfiEmu.pnvram.") - 1; attr = grub_strchr (guid, '.'); if (!attr) return 0; attr++; name = grub_strchr (attr, '.'); if (!name) return 0; name++; efivar = (struct efi_variable *) nvramptr; if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "too many NVRAM variables for reserved variable space." " Try increasing EfiEmu.pnvram.size"); return 1; } nvramptr += sizeof (struct efi_variable); efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16)); if (*guid != '-') return 0; guid++; efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); if (*guid != '-') return 0; guid++; efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); if (*guid != '-') return 0; guid++; guidcomp = grub_strtoull (guid, 0, 16); for (i = 0; i < 8; i++) efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff; efivar->attributes = grub_strtoull (attr, 0, 16); varname = grub_malloc (grub_strlen (name) + 1); if (! varname) return 1; if (unescape (name, varname, varname + grub_strlen (name) + 1, &len)) return 1; len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr, (nvramsize - (nvramptr - nvram)) / 2, (grub_uint8_t *) varname, len, NULL); nvramptr += 2 * len; *((grub_uint16_t *) nvramptr) = 0; nvramptr += 2; efivar->namelen = 2 * len + 2; if (unescape (var->value, nvramptr, nvram + nvramsize, &len)) { efivar->namelen = 0; return 1; } nvramptr += len; efivar->size = len; return 0; }