1 /** @file
2   Device Path services. The thing to remember is device paths are built out of
3   nodes. The device path is terminated by an end node that is length
4   sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
5   all over this file.
6 
7   The only place where multi-instance device paths are supported is in
8   environment varibles. Multi-instance device paths should never be placed
9   on a Handle.
10 
11   Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
12   This program and the accompanying materials
13   are licensed and made available under the terms and conditions of the BSD License
14   which accompanies this distribution.  The full text of the license may be found at
15   http://opensource.org/licenses/bsd-license.php.
16 
17   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 **/
21 
22 
23 #include "UefiDevicePathLib.h"
24 
25 /**
26   Returns the size of a device path in bytes.
27 
28   This function returns the size, in bytes, of the device path data structure
29   specified by DevicePath including the end of device path node.
30   If DevicePath is NULL or invalid, then 0 is returned.
31 
32   @param  DevicePath  A pointer to a device path data structure.
33 
34   @retval 0           If DevicePath is NULL or invalid.
35   @retval Others      The size of a device path in bytes.
36 
37 **/
38 UINTN
39 EFIAPI
GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)40 GetDevicePathSize (
41   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
42   )
43 {
44   return UefiDevicePathLibGetDevicePathSize (DevicePath);
45 }
46 
47 /**
48   Creates a new copy of an existing device path.
49 
50   This function allocates space for a new copy of the device path specified by DevicePath.
51   If DevicePath is NULL, then NULL is returned.  If the memory is successfully
52   allocated, then the contents of DevicePath are copied to the newly allocated
53   buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
54   The memory for the new device path is allocated from EFI boot services memory.
55   It is the responsibility of the caller to free the memory allocated.
56 
57   @param  DevicePath    A pointer to a device path data structure.
58 
59   @retval NULL          DevicePath is NULL or invalid.
60   @retval Others        A pointer to the duplicated device path.
61 
62 **/
63 EFI_DEVICE_PATH_PROTOCOL *
64 EFIAPI
DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)65 DuplicateDevicePath (
66   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
67   )
68 {
69   return UefiDevicePathLibDuplicateDevicePath (DevicePath);
70 }
71 
72 /**
73   Creates a new device path by appending a second device path to a first device path.
74 
75   This function creates a new device path by appending a copy of SecondDevicePath
76   to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
77   device node from SecondDevicePath is retained. The newly created device path is
78   returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
79   SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
80   and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
81   SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
82 
83   If there is not enough memory for the newly allocated buffer, then NULL is returned.
84   The memory for the new device path is allocated from EFI boot services memory.
85   It is the responsibility of the caller to free the memory allocated.
86 
87   @param  FirstDevicePath            A pointer to a device path data structure.
88   @param  SecondDevicePath           A pointer to a device path data structure.
89 
90   @retval NULL      If there is not enough memory for the newly allocated buffer.
91   @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
92   @retval Others    A pointer to the new device path if success.
93                     Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
94 
95 **/
96 EFI_DEVICE_PATH_PROTOCOL *
97 EFIAPI
AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL * FirstDevicePath,OPTIONAL IN CONST EFI_DEVICE_PATH_PROTOCOL * SecondDevicePath OPTIONAL)98 AppendDevicePath (
99   IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
100   IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
101   )
102 {
103   return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
104 }
105 
106 /**
107   Creates a new path by appending the device node to the device path.
108 
109   This function creates a new device path by appending a copy of the device node
110   specified by DevicePathNode to a copy of the device path specified by DevicePath
111   in an allocated buffer. The end-of-device-path device node is moved after the
112   end of the appended device node.
113   If DevicePathNode is NULL then a copy of DevicePath is returned.
114   If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
115   path device node is returned.
116   If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
117   device node is returned.
118   If there is not enough memory to allocate space for the new device path, then
119   NULL is returned.
120   The memory is allocated from EFI boot services memory. It is the responsibility
121   of the caller to free the memory allocated.
122 
123   @param  DevicePath                 A pointer to a device path data structure.
124   @param  DevicePathNode             A pointer to a single device path node.
125 
126   @retval NULL      If there is not enough memory for the new device path.
127   @retval Others    A pointer to the new device path if success.
128                     A copy of DevicePathNode followed by an end-of-device-path node
129                     if both FirstDevicePath and SecondDevicePath are NULL.
130                     A copy of an end-of-device-path node if both FirstDevicePath
131                     and SecondDevicePath are NULL.
132 
133 **/
134 EFI_DEVICE_PATH_PROTOCOL *
135 EFIAPI
AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,OPTIONAL IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePathNode OPTIONAL)136 AppendDevicePathNode (
137   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
138   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
139   )
140 {
141   return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
142 }
143 
144 /**
145   Creates a new device path by appending the specified device path instance to the specified device
146   path.
147 
148   This function creates a new device path by appending a copy of the device path
149   instance specified by DevicePathInstance to a copy of the device path specified
150   by DevicePath in a allocated buffer.
151   The end-of-device-path device node is moved after the end of the appended device
152   path instance and a new end-of-device-path-instance node is inserted between.
153   If DevicePath is NULL, then a copy if DevicePathInstance is returned.
154   If DevicePathInstance is NULL, then NULL is returned.
155   If DevicePath or DevicePathInstance is invalid, then NULL is returned.
156   If there is not enough memory to allocate space for the new device path, then
157   NULL is returned.
158   The memory is allocated from EFI boot services memory. It is the responsibility
159   of the caller to free the memory allocated.
160 
161   @param  DevicePath                 A pointer to a device path data structure.
162   @param  DevicePathInstance         A pointer to a device path instance.
163 
164   @return A pointer to the new device path.
165 
166 **/
167 EFI_DEVICE_PATH_PROTOCOL *
168 EFIAPI
AppendDevicePathInstance(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,OPTIONAL IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePathInstance OPTIONAL)169 AppendDevicePathInstance (
170   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL
171   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
172   )
173 {
174   return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
175 }
176 
177 /**
178   Creates a copy of the current device path instance and returns a pointer to the next device path
179   instance.
180 
181   This function creates a copy of the current device path instance. It also updates
182   DevicePath to point to the next device path instance in the device path (or NULL
183   if no more) and updates Size to hold the size of the device path instance copy.
184   If DevicePath is NULL, then NULL is returned.
185   If DevicePath points to a invalid device path, then NULL is returned.
186   If there is not enough memory to allocate space for the new device path, then
187   NULL is returned.
188   The memory is allocated from EFI boot services memory. It is the responsibility
189   of the caller to free the memory allocated.
190   If Size is NULL, then ASSERT().
191 
192   @param  DevicePath                 On input, this holds the pointer to the current
193                                      device path instance. On output, this holds
194                                      the pointer to the next device path instance
195                                      or NULL if there are no more device path
196                                      instances in the device path pointer to a
197                                      device path data structure.
198   @param  Size                       On output, this holds the size of the device
199                                      path instance, in bytes or zero, if DevicePath
200                                      is NULL.
201 
202   @return A pointer to the current device path instance.
203 
204 **/
205 EFI_DEVICE_PATH_PROTOCOL *
206 EFIAPI
GetNextDevicePathInstance(IN OUT EFI_DEVICE_PATH_PROTOCOL ** DevicePath,OUT UINTN * Size)207 GetNextDevicePathInstance (
208   IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
209   OUT UINTN                          *Size
210   )
211 {
212   return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
213 }
214 
215 /**
216   Creates a device node.
217 
218   This function creates a new device node in a newly allocated buffer of size
219   NodeLength and initializes the device path node header with NodeType and NodeSubType.
220   The new device path node is returned.
221   If NodeLength is smaller than a device path header, then NULL is returned.
222   If there is not enough memory to allocate space for the new device path, then
223   NULL is returned.
224   The memory is allocated from EFI boot services memory. It is the responsibility
225   of the caller to free the memory allocated.
226 
227   @param  NodeType                   The device node type for the new device node.
228   @param  NodeSubType                The device node sub-type for the new device node.
229   @param  NodeLength                 The length of the new device node.
230 
231   @return The new device path.
232 
233 **/
234 EFI_DEVICE_PATH_PROTOCOL *
235 EFIAPI
CreateDeviceNode(IN UINT8 NodeType,IN UINT8 NodeSubType,IN UINT16 NodeLength)236 CreateDeviceNode (
237   IN UINT8                           NodeType,
238   IN UINT8                           NodeSubType,
239   IN UINT16                          NodeLength
240   )
241 {
242   return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
243 }
244 
245 /**
246   Determines if a device path is single or multi-instance.
247 
248   This function returns TRUE if the device path specified by DevicePath is
249   multi-instance.
250   Otherwise, FALSE is returned.
251   If DevicePath is NULL or invalid, then FALSE is returned.
252 
253   @param  DevicePath                 A pointer to a device path data structure.
254 
255   @retval  TRUE                      DevicePath is multi-instance.
256   @retval  FALSE                     DevicePath is not multi-instance, or DevicePath
257                                      is NULL or invalid.
258 
259 **/
260 BOOLEAN
261 EFIAPI
IsDevicePathMultiInstance(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)262 IsDevicePathMultiInstance (
263   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
264   )
265 {
266   return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
267 }
268 
269 /**
270   Converts a device node to its string representation.
271 
272   @param DeviceNode        A Pointer to the device node to be converted.
273   @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
274                            of the display node is used, where applicable. If DisplayOnly
275                            is FALSE, then the longer text representation of the display node
276                            is used.
277   @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
278                            representation for a device node can be used, where applicable.
279 
280   @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
281           is NULL or there was insufficient memory.
282 
283 **/
284 CHAR16 *
285 EFIAPI
ConvertDeviceNodeToText(IN CONST EFI_DEVICE_PATH_PROTOCOL * DeviceNode,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)286 ConvertDeviceNodeToText (
287   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
288   IN BOOLEAN                         DisplayOnly,
289   IN BOOLEAN                         AllowShortcuts
290   )
291 {
292   return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
293 }
294 
295 /**
296   Converts a device path to its text representation.
297 
298   @param DevicePath      A Pointer to the device to be converted.
299   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
300                          of the display node is used, where applicable. If DisplayOnly
301                          is FALSE, then the longer text representation of the display node
302                          is used.
303   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
304                          representation for a device node can be used, where applicable.
305 
306   @return A pointer to the allocated text representation of the device path or
307           NULL if DeviceNode is NULL or there was insufficient memory.
308 
309 **/
310 CHAR16 *
311 EFIAPI
ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)312 ConvertDevicePathToText (
313   IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
314   IN BOOLEAN                          DisplayOnly,
315   IN BOOLEAN                          AllowShortcuts
316   )
317 {
318   return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
319 }
320 
321 /**
322   Convert text to the binary representation of a device node.
323 
324   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
325                          node. Conversion starts with the first character and continues
326                          until the first non-device node character.
327 
328   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
329           insufficient memory or text unsupported.
330 
331 **/
332 EFI_DEVICE_PATH_PROTOCOL *
333 EFIAPI
ConvertTextToDeviceNode(IN CONST CHAR16 * TextDeviceNode)334 ConvertTextToDeviceNode (
335   IN CONST CHAR16 *TextDeviceNode
336   )
337 {
338   return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
339 }
340 
341 /**
342   Convert text to the binary representation of a device path.
343 
344 
345   @param TextDevicePath  TextDevicePath points to the text representation of a device
346                          path. Conversion starts with the first character and continues
347                          until the first non-device node character.
348 
349   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
350           there was insufficient memory.
351 
352 **/
353 EFI_DEVICE_PATH_PROTOCOL *
354 EFIAPI
ConvertTextToDevicePath(IN CONST CHAR16 * TextDevicePath)355 ConvertTextToDevicePath (
356   IN CONST CHAR16 *TextDevicePath
357   )
358 {
359   return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
360 }
361