1 /*-
2 * Copyright (c) 2017 Netflix, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 /*
27 * Taken from MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
28 */
29
30 /** @file
31 Definition for Device Path library.
32
33 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
34 SPDX-License-Identifier: BSD-2-Clause-Patent
35
36 **/
37
38 #ifndef _UEFI_DEVICE_PATH_LIB_H_
39 #define _UEFI_DEVICE_PATH_LIB_H_
40
41 #include <Uefi.h>
42 #include <Protocol/DevicePathUtilities.h>
43 #include <Protocol/DebugPort.h>
44 #include <Protocol/DevicePathToText.h>
45 #include <Protocol/DevicePathFromText.h>
46 #include <Guid/PcAnsi.h>
47 #include <Library/DebugLib.h>
48 #include <Library/PrintLib.h>
49 #include <Library/BaseLib.h>
50 #include <Library/BaseMemoryLib.h>
51 #include <Library/MemoryAllocationLib.h>
52 #include <Library/UefiBootServicesTableLib.h>
53 #include <Library/DevicePathLib.h>
54 #include <Library/PcdLib.h>
55 #include <IndustryStandard/Bluetooth.h>
56
57 #define IS_COMMA(a) ((a) == ',')
58 #define IS_HYPHEN(a) ((a) == '-')
59 #define IS_DOT(a) ((a) == '.')
60 #define IS_LEFT_PARENTH(a) ((a) == '(')
61 #define IS_RIGHT_PARENTH(a) ((a) == ')')
62 #define IS_SLASH(a) ((a) == '/')
63 #define IS_NULL(a) ((a) == '\0')
64
65 //
66 // Private Data structure
67 //
68 typedef struct {
69 char *Str;
70 UINTN Count;
71 UINTN Capacity;
72 } POOL_PRINT;
73
74 typedef
75 EFI_DEVICE_PATH_PROTOCOL *
76 (*DEVICE_PATH_FROM_TEXT) (
77 IN char *Str
78 );
79
80 typedef
81 VOID
82 (*DEVICE_PATH_TO_TEXT) (
83 IN OUT POOL_PRINT *Str,
84 IN VOID *DevicePath,
85 IN BOOLEAN DisplayOnly,
86 IN BOOLEAN AllowShortcuts
87 );
88
89 typedef struct {
90 UINT8 Type;
91 UINT8 SubType;
92 DEVICE_PATH_TO_TEXT Function;
93 } DEVICE_PATH_TO_TEXT_TABLE;
94
95 typedef struct {
96 UINT8 Type;
97 const char *Text;
98 } DEVICE_PATH_TO_TEXT_GENERIC_TABLE;
99
100 typedef struct {
101 const char *DevicePathNodeText;
102 DEVICE_PATH_FROM_TEXT Function;
103 } DEVICE_PATH_FROM_TEXT_TABLE;
104
105 typedef struct {
106 BOOLEAN ClassExist;
107 UINT8 Class;
108 BOOLEAN SubClassExist;
109 UINT8 SubClass;
110 } USB_CLASS_TEXT;
111
112 #define USB_CLASS_AUDIO 1
113 #define USB_CLASS_CDCCONTROL 2
114 #define USB_CLASS_HID 3
115 #define USB_CLASS_IMAGE 6
116 #define USB_CLASS_PRINTER 7
117 #define USB_CLASS_MASS_STORAGE 8
118 #define USB_CLASS_HUB 9
119 #define USB_CLASS_CDCDATA 10
120 #define USB_CLASS_SMART_CARD 11
121 #define USB_CLASS_VIDEO 14
122 #define USB_CLASS_DIAGNOSTIC 220
123 #define USB_CLASS_WIRELESS 224
124
125 #define USB_CLASS_RESERVE 254
126 #define USB_SUBCLASS_FW_UPDATE 1
127 #define USB_SUBCLASS_IRDA_BRIDGE 2
128 #define USB_SUBCLASS_TEST 3
129
130 #define RFC_1700_UDP_PROTOCOL 17
131 #define RFC_1700_TCP_PROTOCOL 6
132
133 #pragma pack(1)
134
135 typedef struct {
136 EFI_DEVICE_PATH_PROTOCOL Header;
137 EFI_GUID Guid;
138 UINT8 VendorDefinedData[1];
139 } VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
140
141 typedef struct {
142 EFI_DEVICE_PATH_PROTOCOL Header;
143 EFI_GUID Guid;
144 UINT8 VendorDefinedData[1];
145 } VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
146
147 typedef struct {
148 EFI_DEVICE_PATH_PROTOCOL Header;
149 EFI_GUID Guid;
150 UINT8 VendorDefinedData[1];
151 } VENDOR_DEFINED_MEDIA_DEVICE_PATH;
152
153 typedef struct {
154 EFI_DEVICE_PATH_PROTOCOL Header;
155 UINT32 Hid;
156 UINT32 Uid;
157 UINT32 Cid;
158 CHAR8 HidUidCidStr[3];
159 } ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
160
161 typedef struct {
162 EFI_DEVICE_PATH_PROTOCOL Header;
163 UINT16 NetworkProtocol;
164 UINT16 LoginOption;
165 UINT64 Lun;
166 UINT16 TargetPortalGroupTag;
167 CHAR8 TargetName[1];
168 } ISCSI_DEVICE_PATH_WITH_NAME;
169
170 typedef struct {
171 EFI_DEVICE_PATH_PROTOCOL Header;
172 EFI_GUID Guid;
173 UINT8 VendorDefinedData[1];
174 } VENDOR_DEVICE_PATH_WITH_DATA;
175
176 #pragma pack()
177
178 #ifdef FreeBSD /* Remove these on FreeBSD */
179
180 /**
181 Returns the size of a device path in bytes.
182
183 This function returns the size, in bytes, of the device path data structure
184 specified by DevicePath including the end of device path node.
185 If DevicePath is NULL or invalid, then 0 is returned.
186
187 @param DevicePath A pointer to a device path data structure.
188
189 @retval 0 If DevicePath is NULL or invalid.
190 @retval Others The size of a device path in bytes.
191
192 **/
193 UINTN
194 EFIAPI
195 UefiDevicePathLibGetDevicePathSize (
196 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
197 );
198
199 /**
200 Creates a new copy of an existing device path.
201
202 This function allocates space for a new copy of the device path specified by DevicePath.
203 If DevicePath is NULL, then NULL is returned. If the memory is successfully
204 allocated, then the contents of DevicePath are copied to the newly allocated
205 buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
206 The memory for the new device path is allocated from EFI boot services memory.
207 It is the responsibility of the caller to free the memory allocated.
208
209 @param DevicePath A pointer to a device path data structure.
210
211 @retval NULL DevicePath is NULL or invalid.
212 @retval Others A pointer to the duplicated device path.
213
214 **/
215 EFI_DEVICE_PATH_PROTOCOL *
216 EFIAPI
217 UefiDevicePathLibDuplicateDevicePath (
218 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
219 );
220
221 /**
222 Creates a new device path by appending a second device path to a first device path.
223
224 This function creates a new device path by appending a copy of SecondDevicePath
225 to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
226 device node from SecondDevicePath is retained. The newly created device path is
227 returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
228 SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
229 and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
230 SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
231
232 If there is not enough memory for the newly allocated buffer, then NULL is returned.
233 The memory for the new device path is allocated from EFI boot services memory.
234 It is the responsibility of the caller to free the memory allocated.
235
236 @param FirstDevicePath A pointer to a device path data structure.
237 @param SecondDevicePath A pointer to a device path data structure.
238
239 @retval NULL If there is not enough memory for the newly allocated buffer.
240 @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
241 @retval Others A pointer to the new device path if success.
242 Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
243
244 **/
245 EFI_DEVICE_PATH_PROTOCOL *
246 EFIAPI
247 UefiDevicePathLibAppendDevicePath (
248 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL,
249 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
250 );
251
252 /**
253 Creates a new path by appending the device node to the device path.
254
255 This function creates a new device path by appending a copy of the device node
256 specified by DevicePathNode to a copy of the device path specified by DevicePath
257 in an allocated buffer. The end-of-device-path device node is moved after the
258 end of the appended device node.
259 If DevicePathNode is NULL then a copy of DevicePath is returned.
260 If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
261 path device node is returned.
262 If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
263 device node is returned.
264 If there is not enough memory to allocate space for the new device path, then
265 NULL is returned.
266 The memory is allocated from EFI boot services memory. It is the responsibility
267 of the caller to free the memory allocated.
268
269 @param DevicePath A pointer to a device path data structure.
270 @param DevicePathNode A pointer to a single device path node.
271
272 @retval NULL If there is not enough memory for the new device path.
273 @retval Others A pointer to the new device path if success.
274 A copy of DevicePathNode followed by an end-of-device-path node
275 if both FirstDevicePath and SecondDevicePath are NULL.
276 A copy of an end-of-device-path node if both FirstDevicePath
277 and SecondDevicePath are NULL.
278
279 **/
280 EFI_DEVICE_PATH_PROTOCOL *
281 EFIAPI
282 UefiDevicePathLibAppendDevicePathNode (
283 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
284 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
285 );
286
287 /**
288 Creates a new device path by appending the specified device path instance to the specified device
289 path.
290
291 This function creates a new device path by appending a copy of the device path
292 instance specified by DevicePathInstance to a copy of the device path specified
293 by DevicePath in a allocated buffer.
294 The end-of-device-path device node is moved after the end of the appended device
295 path instance and a new end-of-device-path-instance node is inserted between.
296 If DevicePath is NULL, then a copy if DevicePathInstance is returned.
297 If DevicePathInstance is NULL, then NULL is returned.
298 If DevicePath or DevicePathInstance is invalid, then NULL is returned.
299 If there is not enough memory to allocate space for the new device path, then
300 NULL is returned.
301 The memory is allocated from EFI boot services memory. It is the responsibility
302 of the caller to free the memory allocated.
303
304 @param DevicePath A pointer to a device path data structure.
305 @param DevicePathInstance A pointer to a device path instance.
306
307 @return A pointer to the new device path.
308
309 **/
310 EFI_DEVICE_PATH_PROTOCOL *
311 EFIAPI
312 UefiDevicePathLibAppendDevicePathInstance (
313 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
314 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
315 );
316
317 /**
318 Creates a copy of the current device path instance and returns a pointer to the next device path
319 instance.
320
321 This function creates a copy of the current device path instance. It also updates
322 DevicePath to point to the next device path instance in the device path (or NULL
323 if no more) and updates Size to hold the size of the device path instance copy.
324 If DevicePath is NULL, then NULL is returned.
325 If DevicePath points to a invalid device path, then NULL is returned.
326 If there is not enough memory to allocate space for the new device path, then
327 NULL is returned.
328 The memory is allocated from EFI boot services memory. It is the responsibility
329 of the caller to free the memory allocated.
330 If Size is NULL, then ASSERT().
331
332 @param DevicePath On input, this holds the pointer to the current
333 device path instance. On output, this holds
334 the pointer to the next device path instance
335 or NULL if there are no more device path
336 instances in the device path pointer to a
337 device path data structure.
338 @param Size On output, this holds the size of the device
339 path instance, in bytes or zero, if DevicePath
340 is NULL.
341
342 @return A pointer to the current device path instance.
343
344 **/
345 EFI_DEVICE_PATH_PROTOCOL *
346 EFIAPI
347 UefiDevicePathLibGetNextDevicePathInstance (
348 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
349 OUT UINTN *Size
350 );
351
352 /**
353 Creates a device node.
354
355 This function creates a new device node in a newly allocated buffer of size
356 NodeLength and initializes the device path node header with NodeType and NodeSubType.
357 The new device path node is returned.
358 If NodeLength is smaller than a device path header, then NULL is returned.
359 If there is not enough memory to allocate space for the new device path, then
360 NULL is returned.
361 The memory is allocated from EFI boot services memory. It is the responsibility
362 of the caller to free the memory allocated.
363
364 @param NodeType The device node type for the new device node.
365 @param NodeSubType The device node sub-type for the new device node.
366 @param NodeLength The length of the new device node.
367
368 @return The new device path.
369
370 **/
371 EFI_DEVICE_PATH_PROTOCOL *
372 EFIAPI
373 UefiDevicePathLibCreateDeviceNode (
374 IN UINT8 NodeType,
375 IN UINT8 NodeSubType,
376 IN UINT16 NodeLength
377 );
378
379 /**
380 Determines if a device path is single or multi-instance.
381
382 This function returns TRUE if the device path specified by DevicePath is
383 multi-instance.
384 Otherwise, FALSE is returned.
385 If DevicePath is NULL or invalid, then FALSE is returned.
386
387 @param DevicePath A pointer to a device path data structure.
388
389 @retval TRUE DevicePath is multi-instance.
390 @retval FALSE DevicePath is not multi-instance, or DevicePath
391 is NULL or invalid.
392
393 **/
394 BOOLEAN
395 EFIAPI
396 UefiDevicePathLibIsDevicePathMultiInstance (
397 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
398 );
399
400 /**
401 Converts a device path to its text representation.
402
403 @param DevicePath A Pointer to the device to be converted.
404 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
405 of the display node is used, where applicable. If DisplayOnly
406 is FALSE, then the longer text representation of the display node
407 is used.
408 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
409 representation for a device node can be used, where applicable.
410
411 @return A pointer to the allocated text representation of the device path or
412 NULL if DeviceNode is NULL or there was insufficient memory.
413
414 **/
415 CHAR16 *
416 EFIAPI
417 UefiDevicePathLibConvertDevicePathToText (
418 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
419 IN BOOLEAN DisplayOnly,
420 IN BOOLEAN AllowShortcuts
421 );
422
423 /**
424 Converts a device node to its string representation.
425
426 @param DeviceNode A Pointer to the device node to be converted.
427 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
428 of the display node is used, where applicable. If DisplayOnly
429 is FALSE, then the longer text representation of the display node
430 is used.
431 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
432 representation for a device node can be used, where applicable.
433
434 @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
435 is NULL or there was insufficient memory.
436
437 **/
438 CHAR16 *
439 EFIAPI
440 UefiDevicePathLibConvertDeviceNodeToText (
441 IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
442 IN BOOLEAN DisplayOnly,
443 IN BOOLEAN AllowShortcuts
444 );
445
446 /**
447 Convert text to the binary representation of a device node.
448
449 @param TextDeviceNode TextDeviceNode points to the text representation of a device
450 node. Conversion starts with the first character and continues
451 until the first non-device node character.
452
453 @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
454 insufficient memory or text unsupported.
455
456 **/
457 EFI_DEVICE_PATH_PROTOCOL *
458 EFIAPI
459 UefiDevicePathLibConvertTextToDeviceNode (
460 IN CONST CHAR16 *TextDeviceNode
461 );
462
463 /**
464 Convert text to the binary representation of a device path.
465
466
467 @param TextDevicePath TextDevicePath points to the text representation of a device
468 path. Conversion starts with the first character and continues
469 until the first non-device node character.
470
471 @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
472 there was insufficient memory.
473
474 **/
475 EFI_DEVICE_PATH_PROTOCOL *
476 EFIAPI
477 UefiDevicePathLibConvertTextToDevicePath (
478 IN CONST CHAR16 *TextDevicePath
479 );
480 #else
481
482 /*
483 * Small FreeBSD shim layer. Fast and lose hacks to make this code work with FreeBSD.
484 */
485
486 #include <ctype.h>
487
488 #define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount 1000
489 #define MAX_UINTN UINTPTR_MAX
490
491 #define AllocatePool(x) malloc(x)
492 #define AllocateZeroPool(x) calloc(1,x)
493 #define AsciiStrLen(s) strlen(s)
494 #define CopyGuid(dst, src) memcpy(dst, src, sizeof(uuid_t))
495 #define CopyMem(d, s, l) memcpy(d, s, l)
496 #define FreePool(x) free(x)
497 #define LShiftU64(x, s) ((x) << s)
498 #define ReadUnaligned64(x) le64dec(x)
499 #define ReallocatePool(old, new, ptr) realloc(ptr, new)
500 /*
501 * Quirky StrCmp returns 0 if equal, 1 if not. This is what the code
502 * expects, though that expectation is likely a bug (it casts the
503 * return value. EDK2's StrCmp returns values just like C's strcmp,
504 * but the parse code casts this to an UINTN, which is bogus. This
505 * definition papers over that bogusness to do the right thing. If
506 * iSCSI protocol string processing is ever fixed, we can remove this
507 * bletcherous kludge.
508 */
509 #define StrCmp(a, b) (strcmp(a, b) != 0)
510 #define StrCpyS(d, l, s) strcpy(d, s)
511 #define StrHexToUint64(x) strtoll(x, NULL, 16)
512 #define StrHexToUintn(x) strtoll(x, NULL, 16)
513 #define StrLen(x) strlen(x)
514 #define StrSize(x) (strlen(x) + 1)
515 #define StrnCatS(d, l, s, len) strncat(d, s, len)
516 #define StrnCmp(a, b, n) strncmp(a, b, n)
517 #define StrnLenS(str, max) strlen(str)
518 #define Strtoi(x) strtol(x, NULL, 0)
519 #define Strtoi64(x, y) *(long long *)y = strtoll(x, NULL, 0)
520 #define SwapBytes64(u64) bswap64(u64)
521 #define UnicodeStrToAsciiStrS(src, dest, len) strlcpy(dest, src, len)
522 #define ZeroMem(p,l) memset(p, 0, l)
523
524 #undef ASSERT
525 #define ASSERT(x)
526
527 /*
528 * Define AllocateCopyPool and others so that we "forget" about the
529 * previous non-static deifnition since we want these to be static
530 * inlines.
531 */
532 #define AllocateCopyPool AllocateCopyPoolFreeBSD
533 #define CompareGuid CompareGuidFreeBSD
534 #define StrHexToBytes StrHexToBytesFreeBSD
535 #define StrToGuid StrToGuidFreeBSD
536 #define WriteUnaligned64 WriteUnaligned64FreeBSD
537
538 static inline void *
AllocateCopyPool(size_t l,const void * p)539 AllocateCopyPool(size_t l, const void *p)
540 {
541 void *rv;
542
543 rv = malloc(l);
544 if (rv == NULL)
545 return NULL;
546 memcpy(rv, p, l);
547 return (rv);
548 }
549
550 static inline BOOLEAN
CompareGuid(const EFI_GUID * g1,const EFI_GUID * g2)551 CompareGuid (const EFI_GUID *g1, const EFI_GUID *g2)
552 {
553 uint32_t ignored_status;
554
555 return (uuid_compare((const uuid_t *)g1, (const uuid_t *)g2,
556 &ignored_status) == 0);
557 }
558
559 static inline int
StrHexToBytes(const char * str,size_t len,uint8_t * buf,size_t buflen)560 StrHexToBytes(const char *str, size_t len, uint8_t *buf, size_t buflen)
561 {
562 size_t i;
563 char hex[3];
564
565 /*
566 * Sanity check preconditions.
567 */
568 if (buflen != len / 2 || (len % 2) == 1)
569 return 1;
570 for (i = 0; i < len; i += 2) {
571 if (!isxdigit(str[i]) || !isxdigit(str[i + 1]))
572 return 1;
573 hex[0] = str[i];
574 hex[1] = str[i + 1];
575 hex[2] = '\0';
576 buf[i / 2] = strtol(hex, NULL, 16);
577 }
578 return 0;
579 }
580
581 static inline void
StrToGuid(const char * str,EFI_GUID * guid)582 StrToGuid(const char *str, EFI_GUID *guid)
583 {
584 uint32_t status;
585
586 uuid_from_string(str, (uuid_t *)guid, &status);
587 }
588
589 static inline void
WriteUnaligned64(void * ptr,uint64_t val)590 WriteUnaligned64(void *ptr, uint64_t val)
591 {
592 memcpy(ptr, &val, sizeof(val));
593 }
594
595 /*
596 * Hack to allow converting %g to %s in printfs. Hack because
597 * it's single entry, uses a static buffer, etc. Sufficient for
598 * the day for this file though. IF you ever have to convert
599 * two %g's in one format, punt. Did I mention this was super lame.
600 * Not to mention it's name.... Also, the error GUID is horrific.
601 */
602 static inline const char *
guid_str(const EFI_GUID * g)603 guid_str(const EFI_GUID *g)
604 {
605 static char buf[36 + 1];
606 char *str = NULL;
607 int32_t ignored_status;
608
609 uuid_to_string((const uuid_t *)g, &str, &ignored_status);
610 if (str != NULL)
611 strlcpy(buf, str, sizeof(buf));
612 else
613 strlcpy(buf, "groot-cannot-decode-guid-groot-smash",
614 sizeof(buf)); /* ^^^^^^^ 36 characters ^^^^^^^ */
615 free(str);
616 return buf;
617 }
618 #define G(x) guid_str((const EFI_GUID *)(const void *)x)
619 #endif
620
621 #undef GLOBAL_REMOVE_IF_UNREFERENCED
622 #define GLOBAL_REMOVE_IF_UNREFERENCED static
623
624 #endif
625