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