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