| ... | @@ -1,4 +1,7 @@ | ... | @@ -1,4 +1,7 @@ |
| 1 | const uefi = @import("std").os.uefi; | 1 | const std = @import("std"); |
| | 2 | const mem = std.mem; |
| | 3 | const uefi = std.os.uefi; |
| | 4 | const Allocator = mem.Allocator; |
| 2 | const Guid = uefi.Guid; | 5 | const Guid = uefi.Guid; |
| 3 | | 6 | |
| 4 | pub const DevicePathProtocol = packed struct { | 7 | pub const DevicePathProtocol = packed struct { |
| ... | @@ -34,6 +37,40 @@ pub const DevicePathProtocol = packed struct { | ... | @@ -34,6 +37,40 @@ pub const DevicePathProtocol = packed struct { |
| 34 | return (@ptrToInt(node) + node.length) - @ptrToInt(self); | 37 | return (@ptrToInt(node) + node.length) - @ptrToInt(self); |
| 35 | } | 38 | } |
| 36 | | 39 | |
| | 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 | |
| 37 | pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { | 74 | pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { |
| 38 | return switch (self.type) { | 75 | return switch (self.type) { |
| 39 | .Hardware => blk: { | 76 | .Hardware => blk: { |