These are quite a bunch of functions, let's give them their own file.
No code changes, just some trivial refactoring.
#include "devicetree.h"
#include "drivers.h"
#include "efivars-fundamental.h"
+#include "efivars.h"
#include "export-vars.h"
#include "graphics.h"
#include "initrd.h"
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "efi-string.h"
+#include "efivars.h"
+#include "ticks.h"
+#include "util.h"
+
+EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags) {
+ assert(vendor);
+ assert(name);
+ assert(buf || size == 0);
+
+ flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
+}
+
+EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
+ assert(vendor);
+ assert(name);
+
+ return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
+}
+
+EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags) {
+ assert(vendor);
+ assert(name);
+
+ _cleanup_free_ char16_t *str = xasprintf("%zu", i);
+ return efivar_set(vendor, name, str, flags);
+}
+
+EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
+ uint8_t buf[4];
+
+ assert(vendor);
+ assert(name);
+
+ buf[0] = (uint8_t)(value >> 0U & 0xFF);
+ buf[1] = (uint8_t)(value >> 8U & 0xFF);
+ buf[2] = (uint8_t)(value >> 16U & 0xFF);
+ buf[3] = (uint8_t)(value >> 24U & 0xFF);
+
+ return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
+}
+
+EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
+ uint8_t buf[8];
+
+ assert(vendor);
+ assert(name);
+
+ buf[0] = (uint8_t)(value >> 0U & 0xFF);
+ buf[1] = (uint8_t)(value >> 8U & 0xFF);
+ buf[2] = (uint8_t)(value >> 16U & 0xFF);
+ buf[3] = (uint8_t)(value >> 24U & 0xFF);
+ buf[4] = (uint8_t)(value >> 32U & 0xFF);
+ buf[5] = (uint8_t)(value >> 40U & 0xFF);
+ buf[6] = (uint8_t)(value >> 48U & 0xFF);
+ buf[7] = (uint8_t)(value >> 56U & 0xFF);
+
+ return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
+}
+
+EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags) {
+ EFI_STATUS err;
+
+ assert(vendor);
+ assert(name);
+
+ /* We could be wiping a non-volatile variable here and the spec makes no guarantees that won't incur
+ * in an extra write (and thus wear out). So check and clear only if needed. */
+ err = efivar_get_raw(vendor, name, NULL, NULL);
+ if (err == EFI_SUCCESS)
+ return efivar_set_raw(vendor, name, NULL, 0, flags);
+
+ return err;
+}
+
+EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret) {
+ _cleanup_free_ char16_t *buf = NULL;
+ EFI_STATUS err;
+ char16_t *val;
+ size_t size;
+
+ assert(vendor);
+ assert(name);
+
+ err = efivar_get_raw(vendor, name, (char **) &buf, &size);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ /* Make sure there are no incomplete characters in the buffer */
+ if ((size % sizeof(char16_t)) != 0)
+ return EFI_INVALID_PARAMETER;
+
+ if (!ret)
+ return EFI_SUCCESS;
+
+ /* Return buffer directly if it happens to be NUL terminated already */
+ if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
+ *ret = TAKE_PTR(buf);
+ return EFI_SUCCESS;
+ }
+
+ /* Make sure a terminating NUL is available at the end */
+ val = xmalloc(size + sizeof(char16_t));
+
+ memcpy(val, buf, size);
+ val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */
+
+ *ret = val;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret) {
+ _cleanup_free_ char16_t *val = NULL;
+ EFI_STATUS err;
+ uint64_t u;
+
+ assert(vendor);
+ assert(name);
+
+ err = efivar_get(vendor, name, &val);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ if (!parse_number16(val, &u, NULL) || u > SIZE_MAX)
+ return EFI_INVALID_PARAMETER;
+
+ if (ret)
+ *ret = u;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
+ _cleanup_free_ char *buf = NULL;
+ size_t size;
+ EFI_STATUS err;
+
+ assert(vendor);
+ assert(name);
+
+ err = efivar_get_raw(vendor, name, &buf, &size);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ if (size != sizeof(uint32_t))
+ return EFI_BUFFER_TOO_SMALL;
+
+ if (ret)
+ *ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
+ (uint32_t) buf[3] << 24U;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
+ _cleanup_free_ char *buf = NULL;
+ size_t size;
+ EFI_STATUS err;
+
+ assert(vendor);
+ assert(name);
+
+ err = efivar_get_raw(vendor, name, &buf, &size);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ if (size != sizeof(uint64_t))
+ return EFI_BUFFER_TOO_SMALL;
+
+ if (ret)
+ *ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
+ (uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
+ (uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size) {
+ EFI_STATUS err;
+
+ assert(vendor);
+ assert(name);
+
+ size_t size = 0;
+ err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, NULL);
+ if (err != EFI_BUFFER_TOO_SMALL)
+ return err;
+
+ _cleanup_free_ void *buf = xmalloc(size);
+ err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, buf);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ if (ret)
+ *ret = TAKE_PTR(buf);
+ if (ret_size)
+ *ret_size = size;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
+ _cleanup_free_ char *b = NULL;
+ size_t size;
+ EFI_STATUS err;
+
+ assert(vendor);
+ assert(name);
+
+ err = efivar_get_raw(vendor, name, &b, &size);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ if (ret)
+ *ret = *b > 0;
+
+ return EFI_SUCCESS;
+}
+
+void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
+ assert(vendor);
+ assert(name);
+
+ if (usec == 0)
+ usec = time_usec();
+ if (usec == 0)
+ return;
+
+ _cleanup_free_ char16_t *str = xasprintf("%" PRIu64, usec);
+ efivar_set(vendor, name, str, 0);
+}
+
+uint64_t get_os_indications_supported(void) {
+ uint64_t osind;
+ EFI_STATUS err;
+
+ /* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
+ * supported features. */
+
+ err = efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndicationsSupported", &osind);
+ if (err != EFI_SUCCESS)
+ return 0;
+
+ return osind;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+/*
+ * Allocated random UUID, intended to be shared across tools that implement
+ * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
+ * associated EFI variables.
+ */
+#define LOADER_GUID \
+ { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
+
+EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags);
+EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags);
+EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags);
+EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags);
+EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags);
+void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec);
+
+EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags);
+
+EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret);
+EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size);
+EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret);
+EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret);
+EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
+EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret);
+
+uint64_t get_os_indications_supported(void);
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "device-path-util.h"
+#include "efivars.h"
#include "export-vars.h"
#include "part-discovery.h"
#include "util.h"
'devicetree.c',
'drivers.c',
'efi-string.c',
+ 'efivars.c',
'export-vars.c',
'graphics.c',
'initrd.c',
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "efivars.h"
#include "memory-util-fundamental.h"
#include "proto/rng.h"
#include "random-seed.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "console.h"
+#include "efivars.h"
#include "proto/security-arch.h"
#include "secure-boot.h"
#include "util.h"
*/
#include "device-path-util.h"
+#include "efivars.h"
#include "secure-boot.h"
#include "shim.h"
#include "util.h"
#include "cpio.h"
#include "device-path-util.h"
#include "devicetree.h"
+#include "efivars.h"
#include "export-vars.h"
#include "graphics.h"
#include "iovec-util-fundamental.h"
#include "ticks.h"
#include "util.h"
#include "version.h"
-
-EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags) {
- assert(vendor);
- assert(name);
- assert(buf || size == 0);
-
- flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
- return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
-}
-
-EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
- assert(vendor);
- assert(name);
-
- return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
-}
-
-EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags) {
- assert(vendor);
- assert(name);
-
- _cleanup_free_ char16_t *str = xasprintf("%zu", i);
- return efivar_set(vendor, name, str, flags);
-}
-
-EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
- uint8_t buf[4];
-
- assert(vendor);
- assert(name);
-
- buf[0] = (uint8_t)(value >> 0U & 0xFF);
- buf[1] = (uint8_t)(value >> 8U & 0xFF);
- buf[2] = (uint8_t)(value >> 16U & 0xFF);
- buf[3] = (uint8_t)(value >> 24U & 0xFF);
-
- return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
-}
-
-EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
- uint8_t buf[8];
-
- assert(vendor);
- assert(name);
-
- buf[0] = (uint8_t)(value >> 0U & 0xFF);
- buf[1] = (uint8_t)(value >> 8U & 0xFF);
- buf[2] = (uint8_t)(value >> 16U & 0xFF);
- buf[3] = (uint8_t)(value >> 24U & 0xFF);
- buf[4] = (uint8_t)(value >> 32U & 0xFF);
- buf[5] = (uint8_t)(value >> 40U & 0xFF);
- buf[6] = (uint8_t)(value >> 48U & 0xFF);
- buf[7] = (uint8_t)(value >> 56U & 0xFF);
-
- return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
-}
-
-EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags) {
- EFI_STATUS err;
-
- assert(vendor);
- assert(name);
-
- /* We could be wiping a non-volatile variable here and the spec makes no guarantees that won't incur
- * in an extra write (and thus wear out). So check and clear only if needed. */
- err = efivar_get_raw(vendor, name, NULL, NULL);
- if (err == EFI_SUCCESS)
- return efivar_set_raw(vendor, name, NULL, 0, flags);
-
- return err;
-}
-
-EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret) {
- _cleanup_free_ char16_t *buf = NULL;
- EFI_STATUS err;
- char16_t *val;
- size_t size;
-
- assert(vendor);
- assert(name);
-
- err = efivar_get_raw(vendor, name, (char **) &buf, &size);
- if (err != EFI_SUCCESS)
- return err;
-
- /* Make sure there are no incomplete characters in the buffer */
- if ((size % sizeof(char16_t)) != 0)
- return EFI_INVALID_PARAMETER;
-
- if (!ret)
- return EFI_SUCCESS;
-
- /* Return buffer directly if it happens to be NUL terminated already */
- if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
- *ret = TAKE_PTR(buf);
- return EFI_SUCCESS;
- }
-
- /* Make sure a terminating NUL is available at the end */
- val = xmalloc(size + sizeof(char16_t));
-
- memcpy(val, buf, size);
- val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */
-
- *ret = val;
- return EFI_SUCCESS;
-}
-
-EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret) {
- _cleanup_free_ char16_t *val = NULL;
- EFI_STATUS err;
- uint64_t u;
-
- assert(vendor);
- assert(name);
-
- err = efivar_get(vendor, name, &val);
- if (err != EFI_SUCCESS)
- return err;
-
- if (!parse_number16(val, &u, NULL) || u > SIZE_MAX)
- return EFI_INVALID_PARAMETER;
-
- if (ret)
- *ret = u;
- return EFI_SUCCESS;
-}
-
-EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
- _cleanup_free_ char *buf = NULL;
- size_t size;
- EFI_STATUS err;
-
- assert(vendor);
- assert(name);
-
- err = efivar_get_raw(vendor, name, &buf, &size);
- if (err != EFI_SUCCESS)
- return err;
-
- if (size != sizeof(uint32_t))
- return EFI_BUFFER_TOO_SMALL;
-
- if (ret)
- *ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
- (uint32_t) buf[3] << 24U;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
- _cleanup_free_ char *buf = NULL;
- size_t size;
- EFI_STATUS err;
-
- assert(vendor);
- assert(name);
-
- err = efivar_get_raw(vendor, name, &buf, &size);
- if (err != EFI_SUCCESS)
- return err;
-
- if (size != sizeof(uint64_t))
- return EFI_BUFFER_TOO_SMALL;
-
- if (ret)
- *ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
- (uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
- (uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size) {
- EFI_STATUS err;
-
- assert(vendor);
- assert(name);
-
- size_t size = 0;
- err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, NULL);
- if (err != EFI_BUFFER_TOO_SMALL)
- return err;
-
- _cleanup_free_ void *buf = xmalloc(size);
- err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, buf);
- if (err != EFI_SUCCESS)
- return err;
-
- if (ret)
- *ret = TAKE_PTR(buf);
- if (ret_size)
- *ret_size = size;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
- _cleanup_free_ char *b = NULL;
- size_t size;
- EFI_STATUS err;
-
- assert(vendor);
- assert(name);
-
- err = efivar_get_raw(vendor, name, &b, &size);
- if (err != EFI_SUCCESS)
- return err;
-
- if (ret)
- *ret = *b > 0;
-
- return EFI_SUCCESS;
-}
-
-void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
- assert(vendor);
- assert(name);
-
- if (usec == 0)
- usec = time_usec();
- if (usec == 0)
- return;
-
- _cleanup_free_ char16_t *str = xasprintf("%" PRIu64, usec);
- efivar_set(vendor, name, str, 0);
-}
+#include "efivars.h"
void convert_efi_path(char16_t *path) {
assert(path);
return EFI_SUCCESS;
}
-uint64_t get_os_indications_supported(void) {
- uint64_t osind;
- EFI_STATUS err;
-
- /* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
- * supported features. */
-
- err = efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndicationsSupported", &osind);
- if (err != EFI_SUCCESS)
- return 0;
-
- return osind;
-}
-
__attribute__((noinline)) void notify_debugger(const char *identity, volatile bool wait) {
#ifdef EFI_DEBUG
printf("%s@%p %s\n", identity, __executable_start, GIT_VERSION);
};
}
-EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags);
-EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags);
-EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags);
-EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags);
-EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags);
-void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec);
-
-EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags);
-
-EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret);
-EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size);
-EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret);
-EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret);
-EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
-EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret);
-
void convert_efi_path(char16_t *path);
char16_t *xstr8_to_path(const char *stra);
char16_t *mangle_stub_cmdline(char16_t *cmdline);
(void) BS->UnloadImage(*image);
}
-/*
- * Allocated random UUID, intended to be shared across tools that implement
- * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
- * associated EFI variables.
- */
-#define LOADER_GUID \
- { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
-
/* Note that GUID is evaluated multiple times! */
#define GUID_FORMAT_STR "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
#define GUID_FORMAT_VAL(g) (g).Data1, (g).Data2, (g).Data3, (g).Data4[0], (g).Data4[1], \
return (void *) (uintptr_t) addr;
}
-uint64_t get_os_indications_supported(void);
-
/* If EFI_DEBUG, print our name and version and also report the address of the image base so a debugger can
* be attached. See debug-sd-boot.sh for how this can be done. */
void notify_debugger(const char *identity, bool wait);
#include "device-path-util.h"
#include "drivers.h"
#include "efi-string.h"
+#include "efivars.h"
#include "proto/device-path.h"
#include "string-util-fundamental.h"
#include "util.h"