2#ifndef PEDIGREE_UEFI_LOAD_OPTIONS_H
3#define PEDIGREE_UEFI_LOAD_OPTIONS_H
7#define UEFI_LOAD_OPTIONS_CAPACITY 1024U
8#define UEFI_COMMAND_LINE_CAPACITY 4096U
10enum uefi_boot_directory {
11 UEFI_BOOT_DIRECTORY_DEFAULT,
12 UEFI_BOOT_DIRECTORY_CURRENT,
13 UEFI_BOOT_DIRECTORY_KNOWN_GOOD,
14 UEFI_BOOT_DIRECTORY_DEBUG
18 enum uefi_boot_directory directory;
19 uint32_t arguments_offset;
20 uint32_t arguments_length;
21 char text[UEFI_LOAD_OPTIONS_CAPACITY];
27 options->directory = UEFI_BOOT_DIRECTORY_DEFAULT;
32 if (!raw || size > UEFI_LOAD_OPTIONS_CAPACITY * 2)
35 const uint8_t* bytes = (
const uint8_t*)raw;
36 const uint32_t stride = size >= 2 && !bytes[1] ? 2 : 1;
41 for (uint32_t offset = 0; offset < size; offset += stride) {
42 if (stride == 2 && bytes[offset + 1])
44 const uint8_t value = bytes[offset];
49 if (terminated || (value !=
'\t' && (value <
' ' || value >
'~')) ||
50 length + 1 >= UEFI_LOAD_OPTIONS_CAPACITY)
53 options->text[length++] = value ==
'\t' ?
' ' : (char)value;
55 while (length &&
options->text[length - 1] ==
' ')
59 while (start < length && options->text[start] ==
' ')
62 while (end < length && options->text[end] !=
' ')
64 static const char* selectors[] = {
"current",
"known-good",
"debug"};
65 static const enum uefi_boot_directory directories[] = {
66 UEFI_BOOT_DIRECTORY_CURRENT, UEFI_BOOT_DIRECTORY_KNOWN_GOOD, UEFI_BOOT_DIRECTORY_DEBUG};
67 for (uint32_t selector = 0; selector < 3; ++selector) {
69 while (start + matched < end && selectors[selector][matched] &&
70 options->text[start + matched] == selectors[selector][matched])
72 if (start + matched == end && !selectors[selector][matched]) {
73 options->directory = directories[selector];
75 while (start < length && options->text[start] ==
' ')
80 options->arguments_offset = start;
81 options->arguments_length = length - start;
85static int append_load_options(
const uint8_t* command_line, uint64_t length,
88 if (!
options || !output || (!command_line && length) || !capacity ||
89 length > UEFI_COMMAND_LINE_CAPACITY)
91 if (
options->arguments_length) {
92 while (length && (!command_line[length - 1] || command_line[length - 1] ==
'\r' ||
93 command_line[length - 1] ==
'\n'))
95 for (uint64_t i = 0; i < length; ++i) {
100 const uint64_t separator = length &&
options->arguments_length ? 1 : 0;
101 if (length >= capacity ||
options->arguments_length > capacity - length - 1 ||
102 separator > capacity - length -
options->arguments_length - 1)
104 for (uint64_t i = 0; i < length; ++i)
105 output[i] = (
char)command_line[i];
107 output[length++] =
' ';
108 for (uint32_t i = 0; i <
options->arguments_length; ++i)