| 1 | const std = @import("std"); |
| 2 | const uefi = std.os.uefi; |
| 3 | const Guid = uefi.Guid; |
| 4 | const Handle = uefi.Handle; |
| 5 | const Status = uefi.Status; |
| 6 | const Error = Status.Error; |
| 7 | const cc = uefi.cc; |
| 8 | |
| 9 | pub fn ServiceBinding(service_guid: Guid) type { |
| 10 | return struct { |
| 11 | const Self = @This(); |
| 12 | |
| 13 | _create_child: *const fn (*Self, *?Handle) callconv(cc) Status, |
| 14 | _destroy_child: *const fn (*Self, Handle) callconv(cc) Status, |
| 15 | |
| 16 | pub const CreateChildError = uefi.UnexpectedError || error{ |
| 17 | InvalidParameter, |
| 18 | OutOfResources, |
| 19 | } || Error; |
| 20 | pub const DestroyChildError = uefi.UnexpectedError || error{ |
| 21 | Unsupported, |
| 22 | InvalidParameter, |
| 23 | AccessDenied, |
| 24 | } || Error; |
| 25 | |
| 26 | /// To add this protocol to an existing handle, use `addToHandle` instead. |
| 27 | pub fn createChild(self: *Self) CreateChildError!Handle { |
| 28 | var handle: ?Handle = null; |
| 29 | switch (self._create_child(self, &handle)) { |
| 30 | .success => return handle orelse error.Unexpected, |
| 31 | else => |status| { |
| 32 | try status.err(); |
| 33 | return uefi.unexpectedStatus(status); |
| 34 | }, |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | pub fn addToHandle(self: *Self, handle: Handle) CreateChildError!void { |
| 39 | switch (self._create_child(self, @ptrCast(@constCast(&handle)))) { |
| 40 | .success => {}, |
| 41 | else => |status| { |
| 42 | try status.err(); |
| 43 | return uefi.unexpectedStatus(status); |
| 44 | }, |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | pub fn destroyChild(self: *Self, handle: Handle) DestroyChildError!void { |
| 49 | switch (self._destroy_child(self, handle)) { |
| 50 | .success => {}, |
| 51 | else => |status| { |
| 52 | try status.err(); |
| 53 | return uefi.unexpectedStatus(status); |
| 54 | }, |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | pub const guid align(8) = service_guid; |
| 59 | }; |
| 60 | } |