zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit c78a108d10838d67064e63bf7cb8b9128239a36c (tree)
parent 73e4571b4c10fdbfe04eb9b339b288b719c3469c
Author: fifty-six <ybham6@gmail.com>
Date:   Tue, 11 Jan 2022 02:51:52 -0500

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.

Diffstat:
Mlib/std/os/uefi/protocols/device_path_protocol.zig | 39++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/lib/std/os/uefi/protocols/device_path_protocol.zig b/lib/std/os/uefi/protocols/device_path_protocol.zig @@ -1,4 +1,7 @@ -const uefi = @import("std").os.uefi; +const std = @import("std"); +const mem = std.mem; +const uefi = std.os.uefi; +const Allocator = mem.Allocator; const Guid = uefi.Guid; pub const DevicePathProtocol = packed struct { @@ -34,6 +37,40 @@ pub const DevicePathProtocol = packed struct { return (@ptrToInt(node) + node.length) - @ptrToInt(self); } + /// Creates a file device path from the existing device path and a file path. + pub fn create_file_device_path(self: *DevicePathProtocol, allocator: Allocator, path: [:0]const u16) !*DevicePathProtocol { + var path_size = self.size(); + + // 2 * (path.len + 1) for the path and its null terminator, which are u16s + // DevicePathProtocol for the extra node before the end + var buf = try allocator.alloc(u8, path_size + 2 * (path.len + 1) + @sizeOf(DevicePathProtocol)); + + mem.copy(u8, buf, @ptrCast([*]const u8, self)[0..path_size]); + + // Pointer to the copy of the end node of the current chain, which is - 4 from the buffer + // as the end node itself is 4 bytes (type: u8 + subtype: u8 + length: u16). + var new = @ptrCast(*MediaDevicePath.FilePathDevicePath, buf.ptr + path_size - 4); + + new.type = .Media; + new.subtype = .FilePath; + new.length = @sizeOf(MediaDevicePath.FilePathDevicePath) + 2 * (@intCast(u16, path.len) + 1); + + // The same as new.getPath(), but not const as we're filling it in. + var ptr = @ptrCast([*:0]u16, @alignCast(2, @ptrCast([*]u8, new)) + @sizeOf(MediaDevicePath.FilePathDevicePath)); + + for (path) |s, i| + ptr[i] = s; + + ptr[path.len] = 0; + + var end = @ptrCast(*EndDevicePath.EndEntireDevicePath, @ptrCast(*DevicePathProtocol, new).next().?); + end.type = .End; + end.subtype = .EndEntire; + end.length = @sizeOf(EndDevicePath.EndEntireDevicePath); + + return @ptrCast(*DevicePathProtocol, buf.ptr); + } + pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { return switch (self.type) { .Hardware => blk: {