]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Drop use of FileDevicePath
authorJan Janssen <medhefgo@web.de>
Sun, 29 May 2022 08:26:18 +0000 (10:26 +0200)
committerJan Janssen <medhefgo@web.de>
Thu, 9 Jun 2022 10:50:13 +0000 (12:50 +0200)
src/boot/efi/boot.c
src/boot/efi/drivers.c
src/boot/efi/util.c
src/boot/efi/util.h

index f00f004eaa82eae8bc690ecc9136b0b4fd6c03c2..5287eabd6c712b05a201a709358b0d05eebeb7ad 100644 (file)
@@ -2349,9 +2349,9 @@ static EFI_STATUS image_start(
         if (err != EFI_SUCCESS)
                 return log_error_status_stall(err, L"Error opening root path: %r", err);
 
-        path = FileDevicePath(entry->device, entry->loader);
-        if (!path)
-                return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
+        err = make_file_device_path(entry->device, entry->loader, &path);
+        if (err != EFI_SUCCESS)
+                return log_error_status_stall(err, L"Error making file device path: %r", err);
 
         UINTN initrd_size = 0;
         _cleanup_freepool_ void *initrd = NULL;
index 65c74c461d52c8c454f2a271e1c08b7e9004cf9a..615c4ca1f3b8cae43a93b506c798f73b7eab4e80 100644 (file)
@@ -21,9 +21,9 @@ static EFI_STATUS load_one_driver(
         assert(fname);
 
         spath = xpool_print(L"\\EFI\\systemd\\drivers\\%s", fname);
-        path = FileDevicePath(loaded_image->DeviceHandle, spath);
-        if (!path)
-                return log_oom();
+        err = make_file_device_path(loaded_image->DeviceHandle, spath, &path);
+        if (err != EFI_SUCCESS)
+                return log_error_status_stall(err, L"Error making file device path: %r", err);
 
         err = BS->LoadImage(FALSE, parent_image, path, NULL, 0, &image);
         if (EFI_ERROR(err))
index 69bca420aeb54cd9aafe12047533c8dc854527f2..c6324035ad59d7e1161329f7eeeaf815c848a31b 100644 (file)
@@ -701,3 +701,40 @@ EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file) {
         *ret_file = file;
         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;
+
+        assert(file);
+        assert(ret_dp);
+
+        err = BS->HandleProtocol(device, &DevicePathProtocol, (void **) &dp);
+        if (err != EFI_SUCCESS)
+                return err;
+
+        EFI_DEVICE_PATH *end_node = dp;
+        while (!IsDevicePathEnd(end_node))
+                end_node = NextDevicePathNode(end_node);
+
+        size_t file_size = strsize16(file);
+        size_t dp_size = ((uint8_t *) end_node - (uint8_t *) dp) + END_DEVICE_PATH_LENGTH;
+
+        /* Make a copy that can also hold a file media device path. */
+        *ret_dp = xmalloc(dp_size + file_size + SIZE_OF_FILEPATH_DEVICE_PATH);
+        memcpy(*ret_dp, dp, dp_size);
+
+        /* Point dp to the end node of the copied device path. */
+        dp = (EFI_DEVICE_PATH *) ((uint8_t *) *ret_dp + dp_size - END_DEVICE_PATH_LENGTH);
+
+        /* Replace end node with file media device path. */
+        FILEPATH_DEVICE_PATH *file_dp = (FILEPATH_DEVICE_PATH *) dp;
+        file_dp->Header.Type = MEDIA_DEVICE_PATH;
+        file_dp->Header.SubType = MEDIA_FILEPATH_DP;
+        memcpy(&file_dp->PathName, file, file_size);
+        SetDevicePathNodeLength(&file_dp->Header, SIZE_OF_FILEPATH_DEVICE_PATH + file_size);
+
+        dp = NextDevicePathNode(dp);
+        SetDevicePathEndNode(dp);
+        return EFI_SUCCESS;
+}
index 8e28f5b1bea0a2b9a531165a304476855800947c..e191fe58664ebd7a695bd57640f8ace958aa1e2f 100644 (file)
@@ -187,3 +187,4 @@ static inline void beep(UINTN beep_count) {}
 #endif
 
 EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file);
+EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp);