1 /** @file
2   Definition for Device Path library.
3 
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef _UEFI_DEVICE_PATH_LIB_H_
10 #define _UEFI_DEVICE_PATH_LIB_H_
11 #include <Uefi.h>
12 #include <Protocol/DevicePathUtilities.h>
13 #include <Protocol/DebugPort.h>
14 #include <Protocol/DevicePathToText.h>
15 #include <Protocol/DevicePathFromText.h>
16 #include <Guid/PcAnsi.h>
17 #include <Library/DebugLib.h>
18 #include <Library/PrintLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/DevicePathLib.h>
24 #include <Library/PcdLib.h>
25 #include <IndustryStandard/Bluetooth.h>
26 
27 #define IS_COMMA(a)                ((a) == L',')
28 #define IS_HYPHEN(a)               ((a) == L'-')
29 #define IS_DOT(a)                  ((a) == L'.')
30 #define IS_LEFT_PARENTH(a)         ((a) == L'(')
31 #define IS_RIGHT_PARENTH(a)        ((a) == L')')
32 #define IS_SLASH(a)                ((a) == L'/')
33 #define IS_NULL(a)                 ((a) == L'\0')
34 
35 
36 //
37 // Private Data structure
38 //
39 typedef struct {
40   CHAR16  *Str;
41   UINTN   Count;
42   UINTN   Capacity;
43 } POOL_PRINT;
44 
45 typedef
46 EFI_DEVICE_PATH_PROTOCOL  *
47 (*DEVICE_PATH_FROM_TEXT) (
48   IN  CHAR16 *Str
49   );
50 
51 typedef
52 VOID
53 (*DEVICE_PATH_TO_TEXT) (
54   IN OUT POOL_PRINT  *Str,
55   IN VOID            *DevicePath,
56   IN BOOLEAN         DisplayOnly,
57   IN BOOLEAN         AllowShortcuts
58   );
59 
60 typedef struct {
61   UINT8                Type;
62   UINT8                SubType;
63   DEVICE_PATH_TO_TEXT  Function;
64 } DEVICE_PATH_TO_TEXT_TABLE;
65 
66 typedef struct {
67   UINT8                Type;
68   CHAR16               *Text;
69 } DEVICE_PATH_TO_TEXT_GENERIC_TABLE;
70 
71 typedef struct {
72   CHAR16                    *DevicePathNodeText;
73   DEVICE_PATH_FROM_TEXT     Function;
74 } DEVICE_PATH_FROM_TEXT_TABLE;
75 
76 typedef struct {
77   BOOLEAN ClassExist;
78   UINT8   Class;
79   BOOLEAN SubClassExist;
80   UINT8   SubClass;
81 } USB_CLASS_TEXT;
82 
83 #define USB_CLASS_AUDIO            1
84 #define USB_CLASS_CDCCONTROL       2
85 #define USB_CLASS_HID              3
86 #define USB_CLASS_IMAGE            6
87 #define USB_CLASS_PRINTER          7
88 #define USB_CLASS_MASS_STORAGE     8
89 #define USB_CLASS_HUB              9
90 #define USB_CLASS_CDCDATA          10
91 #define USB_CLASS_SMART_CARD       11
92 #define USB_CLASS_VIDEO            14
93 #define USB_CLASS_DIAGNOSTIC       220
94 #define USB_CLASS_WIRELESS         224
95 
96 #define USB_CLASS_RESERVE          254
97 #define USB_SUBCLASS_FW_UPDATE     1
98 #define USB_SUBCLASS_IRDA_BRIDGE   2
99 #define USB_SUBCLASS_TEST          3
100 
101 #define RFC_1700_UDP_PROTOCOL      17
102 #define RFC_1700_TCP_PROTOCOL      6
103 
104 #pragma pack(1)
105 
106 typedef struct {
107   EFI_DEVICE_PATH_PROTOCOL  Header;
108   EFI_GUID                  Guid;
109   UINT8                     VendorDefinedData[1];
110 } VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
111 
112 typedef struct {
113   EFI_DEVICE_PATH_PROTOCOL  Header;
114   EFI_GUID                  Guid;
115   UINT8                     VendorDefinedData[1];
116 } VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
117 
118 typedef struct {
119   EFI_DEVICE_PATH_PROTOCOL  Header;
120   EFI_GUID                  Guid;
121   UINT8                     VendorDefinedData[1];
122 } VENDOR_DEFINED_MEDIA_DEVICE_PATH;
123 
124 typedef struct {
125   EFI_DEVICE_PATH_PROTOCOL  Header;
126   UINT32                    Hid;
127   UINT32                    Uid;
128   UINT32                    Cid;
129   CHAR8                     HidUidCidStr[3];
130 } ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
131 
132 typedef struct {
133   EFI_DEVICE_PATH_PROTOCOL  Header;
134   UINT16                    NetworkProtocol;
135   UINT16                    LoginOption;
136   UINT64                    Lun;
137   UINT16                    TargetPortalGroupTag;
138   CHAR8                     TargetName[1];
139 } ISCSI_DEVICE_PATH_WITH_NAME;
140 
141 typedef struct {
142   EFI_DEVICE_PATH_PROTOCOL  Header;
143   EFI_GUID                  Guid;
144   UINT8                     VendorDefinedData[1];
145 } VENDOR_DEVICE_PATH_WITH_DATA;
146 
147 #pragma pack()
148 
149 /**
150   Returns the size of a device path in bytes.
151 
152   This function returns the size, in bytes, of the device path data structure
153   specified by DevicePath including the end of device path node.
154   If DevicePath is NULL or invalid, then 0 is returned.
155 
156   @param  DevicePath  A pointer to a device path data structure.
157 
158   @retval 0           If DevicePath is NULL or invalid.
159   @retval Others      The size of a device path in bytes.
160 
161 **/
162 UINTN
163 EFIAPI
164 UefiDevicePathLibGetDevicePathSize (
165   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
166   );
167 
168 /**
169   Creates a new copy of an existing device path.
170 
171   This function allocates space for a new copy of the device path specified by DevicePath.
172   If DevicePath is NULL, then NULL is returned.  If the memory is successfully
173   allocated, then the contents of DevicePath are copied to the newly allocated
174   buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
175   The memory for the new device path is allocated from EFI boot services memory.
176   It is the responsibility of the caller to free the memory allocated.
177 
178   @param  DevicePath    A pointer to a device path data structure.
179 
180   @retval NULL          DevicePath is NULL or invalid.
181   @retval Others        A pointer to the duplicated device path.
182 
183 **/
184 EFI_DEVICE_PATH_PROTOCOL *
185 EFIAPI
186 UefiDevicePathLibDuplicateDevicePath (
187   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
188   );
189 
190 /**
191   Creates a new device path by appending a second device path to a first device path.
192 
193   This function creates a new device path by appending a copy of SecondDevicePath
194   to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
195   device node from SecondDevicePath is retained. The newly created device path is
196   returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
197   SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
198   and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
199   SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
200 
201   If there is not enough memory for the newly allocated buffer, then NULL is returned.
202   The memory for the new device path is allocated from EFI boot services memory.
203   It is the responsibility of the caller to free the memory allocated.
204 
205   @param  FirstDevicePath            A pointer to a device path data structure.
206   @param  SecondDevicePath           A pointer to a device path data structure.
207 
208   @retval NULL      If there is not enough memory for the newly allocated buffer.
209   @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
210   @retval Others    A pointer to the new device path if success.
211                     Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
212 
213 **/
214 EFI_DEVICE_PATH_PROTOCOL *
215 EFIAPI
216 UefiDevicePathLibAppendDevicePath (
217   IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
218   IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
219   );
220 
221 /**
222   Creates a new path by appending the device node to the device path.
223 
224   This function creates a new device path by appending a copy of the device node
225   specified by DevicePathNode to a copy of the device path specified by DevicePath
226   in an allocated buffer. The end-of-device-path device node is moved after the
227   end of the appended device node.
228   If DevicePathNode is NULL then a copy of DevicePath is returned.
229   If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
230   path device node is returned.
231   If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
232   device node is returned.
233   If there is not enough memory to allocate space for the new device path, then
234   NULL is returned.
235   The memory is allocated from EFI boot services memory. It is the responsibility
236   of the caller to free the memory allocated.
237 
238   @param  DevicePath                 A pointer to a device path data structure.
239   @param  DevicePathNode             A pointer to a single device path node.
240 
241   @retval NULL      If there is not enough memory for the new device path.
242   @retval Others    A pointer to the new device path if success.
243                     A copy of DevicePathNode followed by an end-of-device-path node
244                     if both FirstDevicePath and SecondDevicePath are NULL.
245                     A copy of an end-of-device-path node if both FirstDevicePath
246                     and SecondDevicePath are NULL.
247 
248 **/
249 EFI_DEVICE_PATH_PROTOCOL *
250 EFIAPI
251 UefiDevicePathLibAppendDevicePathNode (
252   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
253   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
254   );
255 
256 /**
257   Creates a new device path by appending the specified device path instance to the specified device
258   path.
259 
260   This function creates a new device path by appending a copy of the device path
261   instance specified by DevicePathInstance to a copy of the device path specified
262   by DevicePath in a allocated buffer.
263   The end-of-device-path device node is moved after the end of the appended device
264   path instance and a new end-of-device-path-instance node is inserted between.
265   If DevicePath is NULL, then a copy if DevicePathInstance is returned.
266   If DevicePathInstance is NULL, then NULL is returned.
267   If DevicePath or DevicePathInstance is invalid, then NULL is returned.
268   If there is not enough memory to allocate space for the new device path, then
269   NULL is returned.
270   The memory is allocated from EFI boot services memory. It is the responsibility
271   of the caller to free the memory allocated.
272 
273   @param  DevicePath                 A pointer to a device path data structure.
274   @param  DevicePathInstance         A pointer to a device path instance.
275 
276   @return A pointer to the new device path.
277 
278 **/
279 EFI_DEVICE_PATH_PROTOCOL *
280 EFIAPI
281 UefiDevicePathLibAppendDevicePathInstance (
282   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL
283   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
284   );
285 
286 /**
287   Creates a copy of the current device path instance and returns a pointer to the next device path
288   instance.
289 
290   This function creates a copy of the current device path instance. It also updates
291   DevicePath to point to the next device path instance in the device path (or NULL
292   if no more) and updates Size to hold the size of the device path instance copy.
293   If DevicePath is NULL, then NULL is returned.
294   If DevicePath points to a invalid device path, then NULL is returned.
295   If there is not enough memory to allocate space for the new device path, then
296   NULL is returned.
297   The memory is allocated from EFI boot services memory. It is the responsibility
298   of the caller to free the memory allocated.
299   If Size is NULL, then ASSERT().
300 
301   @param  DevicePath                 On input, this holds the pointer to the current
302                                      device path instance. On output, this holds
303                                      the pointer to the next device path instance
304                                      or NULL if there are no more device path
305                                      instances in the device path pointer to a
306                                      device path data structure.
307   @param  Size                       On output, this holds the size of the device
308                                      path instance, in bytes or zero, if DevicePath
309                                      is NULL.
310 
311   @return A pointer to the current device path instance.
312 
313 **/
314 EFI_DEVICE_PATH_PROTOCOL *
315 EFIAPI
316 UefiDevicePathLibGetNextDevicePathInstance (
317   IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
318   OUT UINTN                          *Size
319   );
320 
321 /**
322   Creates a device node.
323 
324   This function creates a new device node in a newly allocated buffer of size
325   NodeLength and initializes the device path node header with NodeType and NodeSubType.
326   The new device path node is returned.
327   If NodeLength is smaller than a device path header, then NULL is returned.
328   If there is not enough memory to allocate space for the new device path, then
329   NULL is returned.
330   The memory is allocated from EFI boot services memory. It is the responsibility
331   of the caller to free the memory allocated.
332 
333   @param  NodeType                   The device node type for the new device node.
334   @param  NodeSubType                The device node sub-type for the new device node.
335   @param  NodeLength                 The length of the new device node.
336 
337   @return The new device path.
338 
339 **/
340 EFI_DEVICE_PATH_PROTOCOL *
341 EFIAPI
342 UefiDevicePathLibCreateDeviceNode (
343   IN UINT8                           NodeType,
344   IN UINT8                           NodeSubType,
345   IN UINT16                          NodeLength
346   );
347 
348 /**
349   Determines if a device path is single or multi-instance.
350 
351   This function returns TRUE if the device path specified by DevicePath is
352   multi-instance.
353   Otherwise, FALSE is returned.
354   If DevicePath is NULL or invalid, then FALSE is returned.
355 
356   @param  DevicePath                 A pointer to a device path data structure.
357 
358   @retval  TRUE                      DevicePath is multi-instance.
359   @retval  FALSE                     DevicePath is not multi-instance, or DevicePath
360                                      is NULL or invalid.
361 
362 **/
363 BOOLEAN
364 EFIAPI
365 UefiDevicePathLibIsDevicePathMultiInstance (
366   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
367   );
368 
369 
370 /**
371   Converts a device path to its text representation.
372 
373   @param DevicePath      A Pointer to the device to be converted.
374   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
375                          of the display node is used, where applicable. If DisplayOnly
376                          is FALSE, then the longer text representation of the display node
377                          is used.
378   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
379                          representation for a device node can be used, where applicable.
380 
381   @return A pointer to the allocated text representation of the device path or
382           NULL if DeviceNode is NULL or there was insufficient memory.
383 
384 **/
385 CHAR16 *
386 EFIAPI
387 UefiDevicePathLibConvertDevicePathToText (
388   IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
389   IN BOOLEAN                          DisplayOnly,
390   IN BOOLEAN                          AllowShortcuts
391   );
392 
393 /**
394   Converts a device node to its string representation.
395 
396   @param DeviceNode        A Pointer to the device node to be converted.
397   @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
398                            of the display node is used, where applicable. If DisplayOnly
399                            is FALSE, then the longer text representation of the display node
400                            is used.
401   @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
402                            representation for a device node can be used, where applicable.
403 
404   @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
405           is NULL or there was insufficient memory.
406 
407 **/
408 CHAR16 *
409 EFIAPI
410 UefiDevicePathLibConvertDeviceNodeToText (
411   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
412   IN BOOLEAN                         DisplayOnly,
413   IN BOOLEAN                         AllowShortcuts
414   );
415 
416 /**
417   Convert text to the binary representation of a device node.
418 
419   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
420                          node. Conversion starts with the first character and continues
421                          until the first non-device node character.
422 
423   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
424           insufficient memory or text unsupported.
425 
426 **/
427 EFI_DEVICE_PATH_PROTOCOL *
428 EFIAPI
429 UefiDevicePathLibConvertTextToDeviceNode (
430   IN CONST CHAR16 *TextDeviceNode
431   );
432 
433 /**
434   Convert text to the binary representation of a device path.
435 
436 
437   @param TextDevicePath  TextDevicePath points to the text representation of a device
438                          path. Conversion starts with the first character and continues
439                          until the first non-device node character.
440 
441   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
442           there was insufficient memory.
443 
444 **/
445 EFI_DEVICE_PATH_PROTOCOL *
446 EFIAPI
447 UefiDevicePathLibConvertTextToDevicePath (
448   IN CONST CHAR16 *TextDevicePath
449   );
450 
451 #endif
452