aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os/uefi/protocol/service_binding.zig
blob: ddbda29ee638036dc16fe39a6edc549fd3d81d82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
const std = @import("std");
const uefi = std.os.uefi;
const Guid = uefi.Guid;
const Handle = uefi.Handle;
const Status = uefi.Status;
const Error = Status.Error;
const cc = uefi.cc;

pub fn ServiceBinding(service_guid: Guid) type {
    return struct {
        const Self = @This();

        _create_child: *const fn (*Self, *?Handle) callconv(cc) Status,
        _destroy_child: *const fn (*Self, Handle) callconv(cc) Status,

        pub const CreateChildError = uefi.UnexpectedError || error{
            InvalidParameter,
            OutOfResources,
        } || Error;
        pub const DestroyChildError = uefi.UnexpectedError || error{
            Unsupported,
            InvalidParameter,
            AccessDenied,
        } || Error;

        /// To add this protocol to an existing handle, use `addToHandle` instead.
        pub fn createChild(self: *Self) CreateChildError!Handle {
            var handle: ?Handle = null;
            switch (self._create_child(self, &handle)) {
                .success => return handle orelse error.Unexpected,
                else => |status| {
                    try status.err();
                    return uefi.unexpectedStatus(status);
                },
            }
        }

        pub fn addToHandle(self: *Self, handle: Handle) CreateChildError!void {
            switch (self._create_child(self, @ptrCast(@constCast(&handle)))) {
                .success => {},
                else => |status| {
                    try status.err();
                    return uefi.unexpectedStatus(status);
                },
            }
        }

        pub fn destroyChild(self: *Self, handle: Handle) DestroyChildError!void {
            switch (self._destroy_child(self, handle)) {
                .success => {},
                else => |status| {
                    try status.err();
                    return uefi.unexpectedStatus(status);
                },
            }
        }

        pub const guid align(8) = service_guid;
    };
}