File 2000-libefi-device-path-introduce-make_multiple_file_devi.patch of Package systemd
From 3d0f798c21c36aa4810913315c127dcd5a087d0a Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Sat, 17 Jun 2023 19:42:43 +0200
Subject: [PATCH 2000/2007] libefi(device-path): introduce
`make_multiple_file_device_path`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This build an `EfiDevicePath**` of the form:
`FilePath(\files[0])\EndNode()FilePath(\files[1])\EndNode()…\FilePath(\files[n])\EndNode()`
which should really be read as a list:
[ FilePath(\files[0])\EndNode() ; FilePath(\files(1))\EndNode() ; … ;
FilePath(\files[n])\EndNode() ]
---
src/boot/device-path-util.c | 63 +++++++++++++++++++++++++++++++++++++
src/boot/device-path-util.h | 14 +++++++++
2 files changed, 77 insertions(+)
diff --git a/src/boot/device-path-util.c b/src/boot/device-path-util.c
index 2a85e8bbfc..e7a067ea01 100644
--- a/src/boot/device-path-util.c
+++ b/src/boot/device-path-util.c
@@ -3,6 +3,69 @@
#include "device-path-util.h"
#include "util.h"
+EFI_STATUS make_multiple_file_device_path(
+ EFI_HANDLE device, const char16_t **files, EFI_DEVICE_PATH ***ret_dp) {
+ EFI_STATUS err;
+ EFI_DEVICE_PATH *cur_dp = NULL, **iterator_dp = NULL;
+ EFI_DEVICE_PATH *original_device_path = NULL;
+ size_t n_files = strv_length((const void**)files);
+
+ assert(files);
+ assert(ret_dp);
+
+ if (n_files == 0) {
+ *ret_dp = NULL;
+ return EFI_SUCCESS;
+ };
+
+ err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL),
+ (void **) &original_device_path);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ EFI_DEVICE_PATH *end_node = original_device_path;
+ while (!device_path_is_end(end_node))
+ end_node = device_path_next_node(end_node);
+
+ size_t o_dp_size = (uint8_t *) end_node - (uint8_t *) original_device_path;
+
+
+ *ret_dp = xnew(EFI_DEVICE_PATH*, n_files + 1);
+
+ iterator_dp = ret_dp[0];
+
+ STRV_FOREACH(file, files) {
+ size_t file_size = strsize16(*file);
+
+ /* 1st element: FILEPATH_DEVICE_PATH + path name payload */
+ /* 2nd element: DEVICE_PATH_END_NODE */
+ *iterator_dp = xnew(EFI_DEVICE_PATH, o_dp_size +
+ sizeof(FILEPATH_DEVICE_PATH)
+ + file_size
+ + sizeof(EFI_DEVICE_PATH));
+ cur_dp = *iterator_dp;
+
+ /* Prepend the original device path */
+ cur_dp = mempcpy(cur_dp, original_device_path, o_dp_size);
+
+ FILEPATH_DEVICE_PATH *file_dp = (FILEPATH_DEVICE_PATH *) cur_dp;
+ file_dp->Header = (EFI_DEVICE_PATH) {
+ .Type = MEDIA_DEVICE_PATH,
+ .SubType = MEDIA_FILEPATH_DP,
+ .Length = sizeof(FILEPATH_DEVICE_PATH) + file_size,
+ };
+ memcpy(file_dp->PathName, *file, file_size);
+
+ cur_dp = device_path_next_node(cur_dp);
+ *cur_dp = DEVICE_PATH_END_NODE;
+
+ iterator_dp++;
+ }
+ *iterator_dp = NULL;
+
+ return EFI_SUCCESS;
+}
+
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp) {
EFI_STATUS err;
EFI_DEVICE_PATH *dp;
diff --git a/src/boot/device-path-util.h b/src/boot/device-path-util.h
index 08f1a9c216..5071b44016 100644
--- a/src/boot/device-path-util.h
+++ b/src/boot/device-path-util.h
@@ -3,6 +3,8 @@
#include "proto/device-path.h"
+EFI_STATUS make_multiple_file_device_path(EFI_HANDLE device, const char16_t **files, EFI_DEVICE_PATH
+ ***ret_dp);
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp);
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret);
bool device_path_startswith(const EFI_DEVICE_PATH *dp, const EFI_DEVICE_PATH *start);
@@ -19,9 +21,21 @@ static inline bool device_path_is_end(const EFI_DEVICE_PATH *dp) {
return dp->Type == END_DEVICE_PATH_TYPE && dp->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE;
}
+static inline bool device_path_is_end_instance(const EFI_DEVICE_PATH *dp) {
+ assert(dp);
+ return dp->Type == END_DEVICE_PATH_TYPE && dp->SubType == END_INSTANCE_DEVICE_PATH_SUBTYPE;
+}
+
#define DEVICE_PATH_END_NODE \
(EFI_DEVICE_PATH) { \
.Type = END_DEVICE_PATH_TYPE, \
.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE, \
.Length = sizeof(EFI_DEVICE_PATH) \
}
+
+#define DEVICE_PATH_END_INSTANCE \
+ (EFI_DEVICE_PATH) { \
+ .Type = END_DEVICE_PATH_TYPE, \
+ .SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE, \
+ .Length = sizeof(EFI_DEVICE_PATH) \
+ }
--
2.49.0