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