authorgravatar for carmen@dotcarmen.devCarmen <carmen@dotcarmen.dev> 2025-04-02 21:17:11+02:00
committergravatar for mail@linusgroh.deLinus Groh <mail@linusgroh.de> 2025-04-04 12:42:28+01:00
log2112167f8c194271eac8536843d68c8aa72b487f
treedbd0739a12e1b5265008f9a789606817b1c245c5
parent8a83fc7eba630458262148547c134821024b5142

std.os.uefi.protocol.File: fix some typed definitions


1 files changed, 47 insertions(+), 18 deletions(-)

lib/std/os/uefi/protocol/file.zig+47-18
......@@ -9,14 +9,14 @@ const Error = Status.Error;
99
1010pub const File = extern struct {
1111 revision: u64,
12 _open: *const fn (*const File, **File, [*:0]const u16, u64, u64) callconv(cc) Status,
12 _open: *const fn (*const File, **File, [*:0]const u16, OpenMode, Attributes) callconv(cc) Status,
1313 _close: *const fn (*File) callconv(cc) Status,
1414 _delete: *const fn (*File) callconv(cc) Status,
1515 _read: *const fn (*File, *usize, [*]u8) callconv(cc) Status,
1616 _write: *const fn (*File, *usize, [*]const u8) callconv(cc) Status,
1717 _get_position: *const fn (*const File, *u64) callconv(cc) Status,
1818 _set_position: *const fn (*File, u64) callconv(cc) Status,
19 _get_info: *const fn (*const File, *align(8) const Guid, *const usize, [*]u8) callconv(cc) Status,
19 _get_info: *const fn (*const File, *align(8) const Guid, *usize, ?[*]u8) callconv(cc) Status,
2020 _set_info: *const fn (*File, *align(8) const Guid, usize, [*]const u8) callconv(cc) Status,
2121 _flush: *const fn (*File) callconv(cc) Status,
2222
......@@ -57,7 +57,6 @@ pub const File = extern struct {
5757 NoMedia,
5858 DeviceError,
5959 VolumeCorrupted,
60 BufferTooSmall,
6160 };
6261 pub const SetInfoError = uefi.UnexpectedError || error{
6362 Unsupported,
......@@ -112,8 +111,8 @@ pub const File = extern struct {
112111 self,
113112 &new,
114113 file_name,
115 @intFromEnum(mode),
116 @bitCast(create_attributes),
114 mode,
115 create_attributes,
117116 )) {
118117 .success => return new,
119118 .not_found => return Error.NotFound,
......@@ -216,21 +215,29 @@ pub const File = extern struct {
216215 try self.setPosition(pos);
217216 }
218217
218 /// If the underlying function returns `.buffer_too_small`, then this function
219 /// returns `.{ len, null }`. Otherwise, the 2nd value of the tuple contains
220 /// the casted reference from the buffer.
219221 pub fn getInfo(
220222 self: *const File,
221223 comptime info: std.meta.Tag(Info),
222 ) GetInfoError!std.meta.TagPayload(Info, info) {
224 buffer: ?[]u8,
225 ) GetInfoError!struct { usize, ?*std.meta.TagPayload(Info, info) } {
223226 const InfoType = std.meta.TagPayload(Info, info);
224227
225 var val: InfoType = undefined;
226 var len: usize = @sizeOf(InfoType);
227 switch (self._get_info(self, &InfoType.guid, &len, @ptrCast(&val))) {
228 .success => return val,
228 var len = if (buffer) |b| b.len else 0;
229 switch (self._get_info(
230 self,
231 &InfoType.guid,
232 &len,
233 if (buffer) |b| b else null,
234 )) {
235 .success => return .{ len, @as(*InfoType, @ptrCast(buffer.ptr)) },
236 .buffer_too_small => return .{ len, null },
229237 .unsupported => return Error.Unsupported,
230238 .no_media => return Error.NoMedia,
231239 .device_error => return Error.DeviceError,
232240 .volume_corrupted => return Error.VolumeCorrupted,
233 .buffer_too_small => return Error.BufferTooSmall,
234241 else => |status| return uefi.unexpectedStatus(status),
235242 }
236243 }
......@@ -240,8 +247,21 @@ pub const File = extern struct {
240247 comptime info: std.meta.Tag(Info),
241248 data: *const std.meta.TagPayload(Info, info),
242249 ) SetInfoError!void {
243 const InfoType = @TypeOf(data);
244 switch (self._set_info(self, &InfoType.guid, @sizeOf(InfoType), @ptrCast(data))) {
250 const InfoType = std.meta.TagPayload(Info, info);
251
252 var attached_str_len: usize = 0;
253 const attached_str: [*:0]const u16 = switch (info) {
254 .file => data.getFileName(),
255 inline .file_system, .volume_label => data.getVolumeLabel(),
256 };
257
258 while (attached_str[attached_str_len] != 0) : (attached_str_len += 1) {}
259
260 // add the length (not +1 for sentinel) because `@sizeOf(InfoType)`
261 // already contains the first utf16 char
262 const len = @sizeOf(InfoType) + (attached_str_len * 2);
263
264 switch (self._set_info(self, &InfoType.guid, len, @ptrCast(data))) {
245265 .success => {},
246266 .unsupported => return Error.Unsupported,
247267 .no_media => return Error.NoMedia,
......@@ -268,11 +288,20 @@ pub const File = extern struct {
268288 }
269289
270290 pub const OpenMode = enum(u64) {
271 read = 0x0000000000000001,
272 // implies read
273 write = 0x0000000000000002,
274 // implies read+write
275 create = 0x8000000000000000,
291 pub const Bits = packed struct(u64) {
292 // 0x0000000000000001
293 read: bool = false,
294 // 0x0000000000000002
295 write: bool = false,
296 _pad: u61 = 0,
297 // 0x8000000000000000
298 create: bool = false,
299 };
300
301 read = @bitCast(Bits{ .read = true }),
302 read_write = @bitCast(Bits{ .read = true, .write = true }),
303 read_write_create = @bitCast(Bits{ .read = true, .write = true, .create = true }),
304 _,
276305 };
277306
278307 pub const Attributes = packed struct(u64) {