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