showvar.c revision 1.3 1 1.3 christos /* $NetBSD: showvar.c,v 1.3 2025/02/27 17:26:56 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Redistribution and use in source and binary forms, with or without
5 1.1 christos * modification, are permitted provided that the following conditions
6 1.1 christos * are met:
7 1.1 christos * 1. Redistributions of source code must retain the above copyright
8 1.1 christos * notice, this list of conditions and the following disclaimer.
9 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
10 1.1 christos * notice, this list of conditions and the following disclaimer in the
11 1.1 christos * documentation and/or other materials provided with the distribution.
12 1.1 christos *
13 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
14 1.1 christos * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 1.1 christos * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 1.1 christos * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 1.1 christos * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 1.1 christos * SUCH DAMAGE.
24 1.1 christos */
25 1.1 christos
26 1.1 christos #include <sys/cdefs.h>
27 1.1 christos #ifndef lint
28 1.3 christos __RCSID("$NetBSD: showvar.c,v 1.3 2025/02/27 17:26:56 christos Exp $");
29 1.1 christos #endif /* not lint */
30 1.1 christos
31 1.1 christos #include <sys/efiio.h>
32 1.1 christos #include <sys/ioctl.h>
33 1.1 christos #include <sys/uuid.h>
34 1.1 christos
35 1.1 christos #include <assert.h>
36 1.1 christos #include <ctype.h>
37 1.1 christos #include <err.h>
38 1.1 christos #include <errno.h>
39 1.1 christos #include <fcntl.h>
40 1.1 christos #include <getopt.h>
41 1.1 christos #include <limits.h>
42 1.1 christos #include <regex.h>
43 1.1 christos #include <stdarg.h>
44 1.1 christos #include <stdbool.h>
45 1.1 christos #include <stddef.h>
46 1.1 christos #include <stdio.h>
47 1.1 christos #include <stdlib.h>
48 1.1 christos #include <string.h>
49 1.1 christos #include <unistd.h>
50 1.1 christos #include <util.h>
51 1.1 christos
52 1.1 christos #include "efiio.h"
53 1.1 christos #include "defs.h"
54 1.1 christos #include "bootvar.h"
55 1.1 christos #include "certs.h"
56 1.1 christos #include "devpath.h"
57 1.1 christos #include "getvars.h"
58 1.1 christos #include "showvar.h"
59 1.1 christos #include "utils.h"
60 1.1 christos
61 1.1 christos #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI __BIT(0)
62 1.1 christos #define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION __BIT(1)
63 1.1 christos #define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED __BIT(2)
64 1.1 christos #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED __BIT(3)
65 1.1 christos #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED __BIT(4)
66 1.1 christos #define EFI_OS_INDICATIONS_START_OS_RECOVERY __BIT(5)
67 1.1 christos #define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY __BIT(6)
68 1.1 christos #define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH __BIT(7)
69 1.1 christos #define OS_INDICATIONS_BITS \
70 1.1 christos "\177\020" \
71 1.1 christos "b\x0""BootFWui\0" \
72 1.1 christos "b\x1""TimeStamp\0" \
73 1.1 christos "b\x2""FileCap\0" \
74 1.1 christos "b\x3""FMPCap\0" \
75 1.1 christos "b\x4""CapResVar\0" \
76 1.1 christos "b\x5""StartOsRecovery\0" \
77 1.1 christos "b\x6""StartPltformRec\0" \
78 1.1 christos "b\x7""JSONConfig\0" \
79 1.1 christos
80 1.1 christos //********************************************************
81 1.1 christos // Boot Option Attributes
82 1.1 christos //********************************************************
83 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_KEY __BIT(0) // 0x00000001
84 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_APP __BIT(1) // 0x00000002
85 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_SYSPREP __BIT(4) // 0x00000010
86 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_COUNT __BITS(8,9) // 0x00000300
87 1.1 christos // All values 0x00000200-0x00001F00 are reserved
88 1.1 christos #define BOOT_OPTION_SUPPORT_BITS \
89 1.1 christos "\177\020" \
90 1.1 christos "b\x0""Key\0" \
91 1.1 christos "b\x1""App\0" \
92 1.1 christos "b\x4""SysPrep\0" \
93 1.1 christos "f\x8\x2""Count\0"
94 1.1 christos
95 1.1 christos /************************************************************************/
96 1.1 christos
97 1.1 christos static int
98 1.1 christos show_filelist_data(efi_var_t *v, bool dbg)
99 1.1 christos {
100 1.1 christos char *dmsg, *path;
101 1.1 christos
102 1.1 christos path = devpath_parse(v->ev.data, v->ev.datasize, dbg ? &dmsg : NULL);
103 1.1 christos printf("%s: %s\n", v->name, path);
104 1.1 christos free(path);
105 1.1 christos if (dbg) {
106 1.1 christos printf("%s", dmsg);
107 1.1 christos free(dmsg);
108 1.1 christos }
109 1.1 christos return 0;
110 1.1 christos }
111 1.1 christos
112 1.1 christos static int
113 1.2 christos show_asciiz_data(efi_var_t *v, bool dbg __unused)
114 1.1 christos {
115 1.1 christos char *cp, *ep;
116 1.1 christos
117 1.1 christos printf("%s: ", v->name);
118 1.1 christos
119 1.1 christos cp = v->ev.data;
120 1.1 christos ep = cp + v->ev.datasize;
121 1.1 christos for (/*EMPTY*/; cp < ep; cp += strlen(cp) + 1) {
122 1.1 christos printf("%s\n", cp);
123 1.1 christos }
124 1.1 christos if (cp != ep)
125 1.1 christos warnx("short asciiz data\n");
126 1.1 christos return 0;
127 1.1 christos }
128 1.1 christos
129 1.1 christos static int
130 1.2 christos show_array8_data(efi_var_t *v, bool dbg __unused)
131 1.1 christos {
132 1.1 christos size_t cnt, i;
133 1.1 christos uint8_t *array = v->ev.data;
134 1.1 christos
135 1.1 christos printf("%s: ", v->name);
136 1.1 christos
137 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
138 1.1 christos i = 0;
139 1.1 christos for (;;) {
140 1.1 christos printf("%02x", array[i]);
141 1.1 christos if (++i == cnt) {
142 1.1 christos printf("\n");
143 1.1 christos break;
144 1.1 christos }
145 1.1 christos printf(",");
146 1.1 christos }
147 1.1 christos return 0;
148 1.1 christos }
149 1.1 christos
150 1.1 christos static int
151 1.2 christos show_array16_data(efi_var_t *v, bool dbg __unused)
152 1.1 christos {
153 1.1 christos size_t cnt, i;
154 1.1 christos uint16_t *array = v->ev.data;
155 1.1 christos
156 1.1 christos printf("%s: ", v->name);
157 1.1 christos
158 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
159 1.1 christos i = 0;
160 1.1 christos for (;;) {
161 1.1 christos printf("%04X", array[i]);
162 1.1 christos if (++i == cnt) {
163 1.1 christos printf("\n");
164 1.1 christos break;
165 1.1 christos }
166 1.1 christos printf(",");
167 1.1 christos }
168 1.1 christos return 0;
169 1.1 christos }
170 1.1 christos
171 1.1 christos static int
172 1.1 christos show_uuid_array_data(efi_var_t *v, bool dbg)
173 1.1 christos {
174 1.1 christos size_t cnt, i;
175 1.1 christos uuid_t *array = v->ev.data;
176 1.1 christos const char *name;
177 1.1 christos
178 1.1 christos printf("%s: ", v->name);
179 1.1 christos
180 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
181 1.1 christos
182 1.1 christos for (i = 0; i < cnt; i++) {
183 1.1 christos name = get_cert_name(&array[i]);
184 1.1 christos printf("%s%c", name, i + 1 < cnt ? ' ' : '\n');
185 1.1 christos }
186 1.1 christos
187 1.1 christos if (dbg) {
188 1.1 christos for (i = 0; i < cnt; i++) {
189 1.1 christos printf(" ");
190 1.1 christos uuid_printf(&array[i]);
191 1.1 christos name = get_cert_name(&array[i]);
192 1.1 christos printf(" %s\n", name ? name : "unknown");
193 1.1 christos }
194 1.1 christos }
195 1.1 christos return 0;
196 1.1 christos }
197 1.1 christos
198 1.1 christos /************************************************************************/
199 1.1 christos
200 1.1 christos static int
201 1.1 christos show_key_data(efi_var_t *v, bool dbg)
202 1.1 christos {
203 1.1 christos typedef union {
204 1.1 christos struct {
205 1.1 christos uint32_t Revision : 8;
206 1.1 christos uint32_t ShiftPressed : 1;
207 1.1 christos uint32_t ControlPressed : 1;
208 1.1 christos uint32_t AltPressed : 1;
209 1.1 christos uint32_t LogoPressed : 1;
210 1.1 christos uint32_t MenuPressed : 1;
211 1.1 christos uint32_t SysReqPressed : 1;
212 1.1 christos uint32_t Reserved : 16;
213 1.1 christos uint32_t InputKeyCount : 2;
214 1.1 christos #define BOOT_KEY_OPTION_BITS \
215 1.1 christos "\177\020" \
216 1.1 christos "f\x00\x08""Rev\0" \
217 1.1 christos "b\x08""SHFT\0" \
218 1.1 christos "b\x09""CTRL\0" \
219 1.1 christos "b\x0a""ALT\0" \
220 1.1 christos "b\x0b""LOGO\0" \
221 1.1 christos "b\x0c""MENU\0" \
222 1.1 christos "b\x0d""SysReq\0" \
223 1.1 christos /* "f\x0e\x10""Rsvd\0" */ \
224 1.1 christos "f\x1e\x02""KeyCnt\0"
225 1.1 christos } Options;
226 1.1 christos uint32_t PackedValue;
227 1.1 christos } __packed EFI_BOOT_KEY_DATA;
228 1.1 christos typedef struct {
229 1.1 christos uint16_t ScanCode;
230 1.1 christos uint16_t UnicodeChar;
231 1.1 christos } __packed EFI_INPUT_KEY;
232 1.1 christos typedef struct _EFI_KEY_OPTION {
233 1.1 christos EFI_BOOT_KEY_DATA KeyData;
234 1.1 christos uint32_t BootOptionCrc;
235 1.1 christos uint16_t BootOption;
236 1.1 christos EFI_INPUT_KEY Keys[3];
237 1.1 christos uint16_t DescLocation; /* XXX: a guess! Not documented */
238 1.1 christos uint8_t UndocData[];
239 1.1 christos } __packed EFI_KEY_OPTION;
240 1.1 christos union {
241 1.1 christos EFI_KEY_OPTION *ko;
242 1.1 christos uint8_t *bp;
243 1.1 christos } u = { .bp = v->ev.data, };
244 1.1 christos char buf[256], c, *cp, *desc;
245 1.1 christos
246 1.1 christos printf("%s:", v->name);
247 1.1 christos
248 1.1 christos /*
249 1.1 christos * Note: DescLocation is not documented in the UEFI spec, so
250 1.1 christos * do some sanity checking before using it.
251 1.1 christos */
252 1.1 christos desc = NULL;
253 1.1 christos if (offsetof(EFI_KEY_OPTION, UndocData) < v->ev.datasize &&
254 1.1 christos u.ko->DescLocation + sizeof(uint16_t) < v->ev.datasize) {
255 1.1 christos size_t sz = v->ev.datasize - u.ko->DescLocation;
256 1.1 christos desc = ucs2_to_utf8((uint16_t *)&u.bp[u.ko->DescLocation],
257 1.1 christos sz, NULL, NULL);
258 1.1 christos printf(" %s", desc);
259 1.1 christos }
260 1.1 christos
261 1.1 christos /*
262 1.1 christos * Parse the KeyData
263 1.1 christos */
264 1.1 christos snprintb(buf, sizeof(buf), BOOT_KEY_OPTION_BITS,
265 1.1 christos u.ko->KeyData.PackedValue);
266 1.1 christos
267 1.1 christos /*
268 1.1 christos * Skip over the raw value
269 1.1 christos */
270 1.1 christos c = '\0';
271 1.1 christos if ((cp = strchr(buf, ',')) || (cp = strchr(buf, '<'))) {
272 1.1 christos c = *cp;
273 1.1 christos *cp = '<';
274 1.1 christos }
275 1.1 christos else
276 1.1 christos cp = buf;
277 1.1 christos
278 1.1 christos printf("\tBoot%04X \t%s", u.ko->BootOption, cp);
279 1.1 christos
280 1.1 christos if (c != '\0')
281 1.1 christos *cp = c; /* restore the buffer */
282 1.1 christos
283 1.1 christos for (uint i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++)
284 1.1 christos printf(" {%04x, %04x}", u.ko->Keys[i].ScanCode,
285 1.1 christos u.ko->Keys[i].UnicodeChar);
286 1.1 christos printf("\n");
287 1.1 christos
288 1.1 christos if (dbg) {
289 1.1 christos printf(" KeyData: %s\n", buf);
290 1.1 christos printf(" BootOptionCrc: 0x%08x\n", u.ko->BootOptionCrc);
291 1.1 christos printf(" BootOption: Boot%04X\n", u.ko->BootOption);
292 1.1 christos for (uint i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++) {
293 1.1 christos printf(" Keys[%u].ScanCode: 0x%04x\n", i,
294 1.1 christos u.ko->Keys[i].ScanCode);
295 1.1 christos printf(" Keys[%u].UnicodeChar: 0x%04x\n", i,
296 1.1 christos u.ko->Keys[i].UnicodeChar);
297 1.1 christos }
298 1.1 christos if (desc)
299 1.1 christos printf(" Desc: %s\n", desc);
300 1.1 christos }
301 1.1 christos free(desc);
302 1.1 christos return 0;
303 1.1 christos }
304 1.1 christos
305 1.1 christos /************************************************************************/
306 1.1 christos
307 1.1 christos static char *
308 1.1 christos format_optional_data(char *od, size_t sz)
309 1.1 christos {
310 1.1 christos char *bp;
311 1.1 christos size_t i;
312 1.1 christos
313 1.1 christos bp = emalloc(sz + 1);
314 1.1 christos
315 1.1 christos for (i = 0; i < sz; i++) {
316 1.1 christos char c = od[i];
317 1.2 christos bp[i] = isprint((unsigned char)c) ? c : '.';
318 1.1 christos }
319 1.1 christos bp[i] = '\0';
320 1.1 christos return bp;
321 1.1 christos }
322 1.1 christos
323 1.1 christos static int
324 1.3 christos show_boot_data(efi_var_t *v, uint debug, uint max_namelen)
325 1.1 christos {
326 1.1 christos struct {
327 1.1 christos char *name;
328 1.1 christos uint32_t Attributes;
329 1.1 christos char *Description;
330 1.1 christos devpath_t *devpath;
331 1.1 christos char *OptionalData;
332 1.1 christos size_t OptionalDataSize;
333 1.1 christos } info;
334 1.1 christos union {
335 1.1 christos char *cp;
336 1.1 christos boot_var_t *bb;
337 1.1 christos } u = { .cp = v->ev.data, };
338 1.1 christos char *args, *dmsg, *path;
339 1.1 christos size_t sz;
340 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT;
341 1.1 christos bool verbose = debug & (DEBUG_MASK | DEBUG_VERBOSE_BIT);
342 1.1 christos
343 1.1 christos memset(&info, 0, sizeof(info));
344 1.1 christos info.name = v->name;
345 1.1 christos info.Attributes = u.bb->Attributes;
346 1.1 christos sz = (v->ev.datasize - sizeof(*u.bb)) / sizeof(uint16_t);
347 1.1 christos sz = (ucs2nlen(u.bb->Description, sz) + 1) * sizeof(uint16_t);
348 1.1 christos info.Description = ucs2_to_utf8(u.bb->Description, sz, NULL, NULL);
349 1.1 christos info.devpath = (devpath_t *)((uint8_t *)u.bb->Description + sz);
350 1.1 christos info.OptionalData = (char *)info.devpath + u.bb->FilePathListLength;
351 1.1 christos
352 1.1 christos char *ep = u.cp + v->ev.datasize;
353 1.1 christos
354 1.1 christos assert(info.OptionalData <= u.cp + v->ev.datasize);
355 1.1 christos
356 1.1 christos if (info.OptionalData <= u.cp + v->ev.datasize) {
357 1.1 christos info.OptionalDataSize = (size_t)(ep - info.OptionalData);
358 1.1 christos }
359 1.1 christos else {
360 1.1 christos printf("ARG!!! "
361 1.1 christos "FilePahList[] extends past end of data by %zd bytes\n",
362 1.1 christos info.OptionalData - ep);
363 1.1 christos info.OptionalDataSize = 0;
364 1.1 christos }
365 1.1 christos printf("%s%c %-*s", v->name,
366 1.1 christos IS_ACTIVE(info.Attributes) ? '*' : ' ',
367 1.1 christos max_namelen, info.Description);
368 1.1 christos
369 1.1 christos dmsg = NULL;
370 1.1 christos if (verbose) {
371 1.1 christos path = devpath_parse(info.devpath, u.bb->FilePathListLength,
372 1.1 christos dbg ? &dmsg : NULL);
373 1.1 christos
374 1.1 christos args = format_optional_data(info.OptionalData,
375 1.1 christos info.OptionalDataSize);
376 1.1 christos
377 1.1 christos printf("\t%s%s", path, args);/* XXX: make this conditional on verbose? */
378 1.1 christos free(args);
379 1.1 christos free(path);
380 1.1 christos }
381 1.1 christos
382 1.1 christos printf("\n");
383 1.1 christos
384 1.1 christos if (dbg) {
385 1.1 christos char attr_str[256];
386 1.1 christos
387 1.1 christos snprintb(attr_str, sizeof(attr_str),
388 1.1 christos LOAD_OPTION_BITS, info.Attributes);
389 1.1 christos printf(" Attr: %s\n", attr_str);
390 1.1 christos printf(" Description: %s\n", info.Description);
391 1.1 christos assert(dmsg != NULL);
392 1.1 christos printf("%s", dmsg);
393 1.1 christos if (info.OptionalDataSize > 0) {
394 1.1 christos show_data((void *)info.OptionalData,
395 1.1 christos info.OptionalDataSize, " ExtraData: ");
396 1.1 christos }
397 1.1 christos free(dmsg);
398 1.1 christos }
399 1.1 christos
400 1.1 christos free(info.Description);
401 1.1 christos return 0;
402 1.1 christos }
403 1.1 christos
404 1.1 christos /************************************************************************/
405 1.1 christos
406 1.1 christos static int
407 1.2 christos show_OsIndications_data(efi_var_t *e, bool dbg __unused)
408 1.1 christos {
409 1.1 christos uint64_t OsIndications;
410 1.1 christos char buf[256];
411 1.1 christos
412 1.1 christos assert(e->ev.datasize == 8);
413 1.1 christos OsIndications = *(uint64_t *)e->ev.data;
414 1.1 christos snprintb(buf, sizeof(buf), OS_INDICATIONS_BITS, OsIndications);
415 1.1 christos printf("%s:\t%s\n", e->name, buf);
416 1.1 christos return 0;
417 1.1 christos }
418 1.1 christos
419 1.1 christos static int
420 1.2 christos show_BootOptionSupport_data(efi_var_t *e, bool dbg __unused)
421 1.1 christos {
422 1.1 christos uint32_t boot_option_support;
423 1.1 christos char buf[256];
424 1.1 christos
425 1.1 christos assert(e->ev.datasize == 4);
426 1.1 christos boot_option_support = *(uint32_t *)e->ev.data;
427 1.1 christos snprintb(buf, sizeof(buf), BOOT_OPTION_SUPPORT_BITS,
428 1.1 christos boot_option_support);
429 1.1 christos printf("%s:\t%s\n", e->name, buf);
430 1.1 christos return 0;
431 1.1 christos }
432 1.1 christos
433 1.1 christos static int
434 1.2 christos show_Timeout_data(efi_var_t *e, bool dbg __unused)
435 1.1 christos {
436 1.1 christos uint16_t *timeout = e->ev.data;
437 1.1 christos
438 1.1 christos if (e->ev.datasize != 2)
439 1.1 christos printf("bad timeout datasize: %zu\n", e->ev.datasize);
440 1.1 christos else
441 1.1 christos printf("Timeout: %u seconds\n", *timeout);
442 1.1 christos return 0;
443 1.1 christos }
444 1.1 christos
445 1.1 christos PUBLIC int
446 1.1 christos show_generic_data(efi_var_t *e, uint var_width)
447 1.1 christos {
448 1.1 christos char uuid_str[UUID_STR_LEN];
449 1.1 christos char attr_str[256];
450 1.1 christos
451 1.1 christos uuid_snprintf(uuid_str, sizeof(uuid_str), &e->ev.vendor);
452 1.1 christos snprintb(attr_str, sizeof(attr_str), EFI_VAR_ATTR_BITS, e->ev.attrib);
453 1.1 christos printf("%-*s %s %5zu %s\n", var_width, e->name, uuid_str,
454 1.1 christos e->ev.datasize, attr_str);
455 1.1 christos
456 1.1 christos return 0;
457 1.1 christos }
458 1.1 christos
459 1.1 christos /************************************************************************/
460 1.1 christos
461 1.1 christos struct vartbl {
462 1.1 christos const char *name;
463 1.1 christos int (*fn)(efi_var_t *, bool);
464 1.1 christos };
465 1.1 christos
466 1.1 christos static int
467 1.1 christos varcmpsortfn(const void *a, const void *b)
468 1.1 christos {
469 1.1 christos const struct vartbl *p = a;
470 1.1 christos const struct vartbl *q = b;
471 1.1 christos
472 1.1 christos return strcmp(p->name, q->name);
473 1.1 christos }
474 1.1 christos
475 1.1 christos static int
476 1.1 christos varcmpsrchfn(const void *a, const void *b)
477 1.1 christos {
478 1.1 christos const struct vartbl *q = b;
479 1.1 christos
480 1.1 christos return strcmp(a, q->name);
481 1.1 christos }
482 1.1 christos
483 1.1 christos PUBLIC int
484 1.3 christos show_variable(efi_var_t *v, uint debug, uint max_namelen)
485 1.1 christos {
486 1.1 christos #define REGEXP_BOOTXXXX "^((Key)|(Boot)|(lBoot)|(Driver)|(SysPrep)|(OsRecovery))[0-9,A-F]{4}$"
487 1.1 christos static regex_t preg = { .re_magic = 0, };
488 1.1 christos static struct vartbl *tp, tbl[] = {
489 1.1 christos { "AuditMode", show_array8_data, },
490 1.1 christos { "BootCurrent", show_array16_data, },
491 1.1 christos { "BootNext", show_array16_data, },
492 1.1 christos { "BootOptionSupport", show_BootOptionSupport_data, },
493 1.1 christos { "BootOrder", show_array16_data, },
494 1.1 christos { "BootOrderDefault", show_array16_data, },
495 1.1 christos { "db", show_cert_data, },
496 1.1 christos { "dbDefault", show_cert_data, },
497 1.1 christos { "dbr", show_cert_data, },
498 1.1 christos { "dbrDefault", show_cert_data, },
499 1.1 christos { "dbt", show_cert_data, },
500 1.1 christos { "dbtDefault", show_cert_data, },
501 1.1 christos { "dbx", show_cert_data, },
502 1.1 christos { "dbxDefault", show_cert_data, },
503 1.1 christos { "devdbDefault", show_cert_data, },
504 1.1 christos { "ConIn", show_filelist_data, },
505 1.1 christos { "ConInDev", show_filelist_data, },
506 1.1 christos { "ConOut", show_filelist_data, },
507 1.1 christos { "ConOutDev", show_filelist_data, },
508 1.1 christos { "DriverOrder", show_array16_data, },
509 1.1 christos { "ErrOut", show_filelist_data, },
510 1.1 christos { "ErrOutDev", show_filelist_data, },
511 1.1 christos { "KEK", show_cert_data, },
512 1.1 christos { "KEKDefault", show_cert_data, },
513 1.1 christos { "OsIndications", show_OsIndications_data, },
514 1.1 christos { "OsIndicationsSupported", show_OsIndications_data, },
515 1.1 christos { "PK", show_cert_data, },
516 1.1 christos { "PKDefault", show_cert_data, },
517 1.1 christos { "PlatformLang", show_asciiz_data, },
518 1.1 christos { "PlatformLangCodes", show_asciiz_data, },
519 1.1 christos { "ProtectedBootOptions", show_array16_data, },
520 1.1 christos { "SecureBoot", show_array8_data, },
521 1.1 christos { "SetupMode", show_array8_data, },
522 1.1 christos { "SignatureSupport", show_uuid_array_data, },
523 1.1 christos { "SysPrepOrder", show_array16_data, },
524 1.1 christos { "Timeout", show_Timeout_data, },
525 1.1 christos { "VendorKeys", show_array8_data, },
526 1.1 christos };
527 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT;
528 1.1 christos int rv;
529 1.1 christos
530 1.1 christos if (preg.re_magic == 0) {
531 1.1 christos const char *regexp = REGEXP_BOOTXXXX;
532 1.1 christos if (regcomp(&preg, regexp, REG_EXTENDED) != 0)
533 1.1 christos err(EXIT_FAILURE, "regcomp: %s", regexp);
534 1.1 christos
535 1.1 christos qsort(tbl, __arraycount(tbl), sizeof(*tbl), varcmpsortfn);
536 1.1 christos }
537 1.1 christos
538 1.1 christos if (debug & DEBUG_EFI_IOC_BIT) {
539 1.1 christos rv = show_generic_data(v, max_namelen);
540 1.1 christos if (debug & DEBUG_VERBOSE_BIT)
541 1.1 christos return rv;
542 1.1 christos }
543 1.1 christos
544 1.1 christos if (regexec(&preg, v->name, 0, NULL, 0) == 0) { /* matched */
545 1.1 christos if (v->name[0] == 'K')
546 1.1 christos rv = show_key_data(v, dbg);
547 1.1 christos else
548 1.1 christos rv = show_boot_data(v, debug, max_namelen);
549 1.1 christos }
550 1.1 christos else {
551 1.1 christos tp = bsearch(v->name, tbl, __arraycount(tbl), sizeof(*tbl),
552 1.1 christos varcmpsrchfn);
553 1.1 christos
554 1.1 christos if (tp != NULL)
555 1.1 christos rv = tp->fn(v, dbg);
556 1.1 christos else if(!(debug & DEBUG_EFI_IOC_BIT))
557 1.1 christos rv = show_generic_data(v, max_namelen);
558 1.1 christos }
559 1.1 christos if (debug & DEBUG_DATA_BIT)
560 1.1 christos show_data(v->ev.data, v->ev.datasize, " ");
561 1.1 christos
562 1.1 christos return rv;
563 1.1 christos }
564