authorgravatar for ybham6@gmail.comfifty-six <ybham6@gmail.com> 2022-01-11 02:51:52-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-11 10:49:40-07:00
logc78a108d10838d67064e63bf7cb8b9128239a36c
tree76cb07801c4a27547b4d74d6726a311a60bea9ad
parent73e4571b4c10fdbfe04eb9b339b288b719c3469c

std/os/uefi: Add create_file_device_path

This allows users to add file paths to device paths, which is often used in methods like `boot_services.loadImage` and `boot_services.startImage`, which take a device path with an additional file path appended to locate the image.

1 files changed, 38 insertions(+), 1 deletions(-)

lib/std/os/uefi/protocols/device_path_protocol.zig+38-1
......@@ -1,4 +1,7 @@
1const uefi = @import("std").os.uefi;
1const std = @import("std");
2const mem = std.mem;
3const uefi = std.os.uefi;
4const Allocator = mem.Allocator;
25const Guid = uefi.Guid;
36
47pub const DevicePathProtocol = packed struct {
......@@ -34,6 +37,40 @@ pub const DevicePathProtocol = packed struct {
3437 return (@ptrToInt(node) + node.length) - @ptrToInt(self);
3538 }
3639
40 /// Creates a file device path from the existing device path and a file path.
41 pub fn create_file_device_path(self: *DevicePathProtocol, allocator: Allocator, path: [:0]const u16) !*DevicePathProtocol {
42 var path_size = self.size();
43
44 // 2 * (path.len + 1) for the path and its null terminator, which are u16s
45 // DevicePathProtocol for the extra node before the end
46 var buf = try allocator.alloc(u8, path_size + 2 * (path.len + 1) + @sizeOf(DevicePathProtocol));
47
48 mem.copy(u8, buf, @ptrCast([*]const u8, self)[0..path_size]);
49
50 // Pointer to the copy of the end node of the current chain, which is - 4 from the buffer
51 // as the end node itself is 4 bytes (type: u8 + subtype: u8 + length: u16).
52 var new = @ptrCast(*MediaDevicePath.FilePathDevicePath, buf.ptr + path_size - 4);
53
54 new.type = .Media;
55 new.subtype = .FilePath;
56 new.length = @sizeOf(MediaDevicePath.FilePathDevicePath) + 2 * (@intCast(u16, path.len) + 1);
57
58 // The same as new.getPath(), but not const as we're filling it in.
59 var ptr = @ptrCast([*:0]u16, @alignCast(2, @ptrCast([*]u8, new)) + @sizeOf(MediaDevicePath.FilePathDevicePath));
60
61 for (path) |s, i|
62 ptr[i] = s;
63
64 ptr[path.len] = 0;
65
66 var end = @ptrCast(*EndDevicePath.EndEntireDevicePath, @ptrCast(*DevicePathProtocol, new).next().?);
67 end.type = .End;
68 end.subtype = .EndEntire;
69 end.length = @sizeOf(EndDevicePath.EndEntireDevicePath);
70
71 return @ptrCast(*DevicePathProtocol, buf.ptr);
72 }
73
3774 pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {
3875 return switch (self.type) {
3976 .Hardware => blk: {