-
Notifications
You must be signed in to change notification settings - Fork 7
/
uefi_support.h
164 lines (138 loc) · 4.96 KB
/
uefi_support.h
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* uefi_support.h - UEFI support declarations */
/*
* Copyright © 2014-2021 Pete Batard <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <time.h>
#include "uefi_driver.h"
#ifndef _MSC_VER
#if !defined(__GNUC__) || (__GNUC__ < 5)
#error gcc 5.0 or later is required for the compilation of this driver.
#endif /* _MSC_VER */
/* Having GNU_EFI_USE_MS_ABI avoids the need for uefi_call_wrapper() */
#if defined(_GNU_EFI) & !defined(GNU_EFI_USE_MS_ABI)
#error gnu-efi, with option GNU_EFI_USE_MS_ABI, is required for the compilation of this driver.
#endif
#endif /* _GNU_EFI & !GNU_EFI_USE_MS_ABI */
/* Some compilers complain when using %llx to print a pointer on 32-bit */
#if defined(_M_ARM64) || defined(__aarch64__) || defined (_M_X64) || defined(__x86_64__)
#define PERCENT_P L"%llx"
#else
#define PERCENT_P L"%x"
#endif
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifndef PATH_CHAR
#define PATH_CHAR L'/'
#endif
#ifndef DOS_PATH_CHAR
#define DOS_PATH_CHAR L'\\'
#endif
#define IS_PATH_DELIMITER(x) ((x) == PATH_CHAR || (x) == DOS_PATH_CHAR)
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
#define _WIDEN(s) L ## s
#define WIDEN(s) _WIDEN(s)
/* For safety, we set a a maximum size that strings shall not outgrow */
#define STRING_MAX (PATH_MAX + 2)
/* Convenience assertion macros */
#define FL_ASSERT(f, l, a) if(!(a)) do { Print(L"*** ASSERT FAILED: %a(%d): %a ***\n", f, l, #a); while(1); } while(0)
#define FS_ASSERT(a) FL_ASSERT(__FILE__, __LINE__, a)
/*
* Secure string copy, that either uses the already secure version from
* EDK2, or duplicates it for gnu-efi and asserts on any error.
*/
static __inline VOID _SafeStrCpy(CHAR16* Destination, UINTN DestMax,
CONST CHAR16* Source, CONST CHAR8* File, CONST UINTN Line) {
#ifdef _GNU_EFI
FL_ASSERT(File, Line, Destination != NULL);
FL_ASSERT(File, Line, Source != NULL);
FL_ASSERT(File, Line, DestMax != 0);
/*
* EDK2 would use RSIZE_MAX, but we use the smaller PATH_MAX for
* gnu-efi as it can help detect path overflows while debugging.
*/
FL_ASSERT(File, Line, DestMax <= PATH_MAX);
FL_ASSERT(File, Line, DestMax > StrLen(Source));
while (*Source != 0)
*(Destination++) = *(Source++);
*Destination = 0;
#else
FL_ASSERT(File, Line, StrCpyS(Destination, DestMax, Source) == 0);
#endif
}
#define SafeStrCpy(d, l, s) _SafeStrCpy(d, l, s, __FILE__, __LINE__)
/*
* Secure string length, that asserts if the string is NULL or if
* the length is larger than a predetermined value (STRING_MAX)
*/
static __inline UINTN _SafeStrLen(CONST CHAR16* String, CONST CHAR8* File,
CONST UINTN Line) {
UINTN Len = 0;
FL_ASSERT(File, Line, String != NULL);
Len = StrLen(String);
FL_ASSERT(File, Line, Len < STRING_MAX);
return Len;
}
#define SafeStrLen(s) _SafeStrLen(s, __FILE__, __LINE__)
/*
* Secure string size, that asserts if the string is NULL or if the size
* is larger than a predetermined value (STRING_MAX * sizeof(CHAR16)) or
* if the size is smaller than sizeof(CHAR16).
*/
static __inline UINTN _SafeStrSize(CONST CHAR16* String, CONST CHAR8* File,
CONST UINTN Line) {
UINTN Size = 0;
FL_ASSERT(File, Line, String != NULL);
Size = StrSize(String);
FL_ASSERT(File, Line, (Size >= sizeof(CHAR16)) &&
(Size < STRING_MAX * sizeof(CHAR16)));
return Size;
}
#define SafeStrSize(s) _SafeStrSize(s, __FILE__, __LINE__)
/*
* EDK2 does not provide a StrDup call, so we define one.
*/
static __inline CHAR16* StrDup(CONST CHAR16* Src)
{
UINTN Len;
CHAR16* Dst;
/* Prefer SafeStrLen() over StrSize() for the checks */
Len = (SafeStrLen(Src) + 1) * sizeof(CHAR16);
Dst = AllocatePool(Len);
if (Dst != NULL)
CopyMem(Dst, Src, Len);
return Dst;
}
/*
* Prototypes for the function calls provided in uefi_support.c
*/
CHAR16* GuidToStr(EFI_GUID* Guid);
VOID UnixTimeToEfiTime(time_t t, EFI_TIME* Time);
time_t EfiTimeToUnixTime(EFI_TIME* Time);
INTN CompareDevicePaths(CONST EFI_DEVICE_PATH* dp1, CONST EFI_DEVICE_PATH* dp2);
VOID CleanPath(CHAR16* Path);
CHAR16* DevicePathToString(CONST EFI_DEVICE_PATH* DevicePath);