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 variables. Multi-instance device paths should never be placed
9   on a Handle.
10 
11   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
12   SPDX-License-Identifier: BSD-2-Clause-Patent
13 
14 **/
15 
16 
17 #include "UefiDevicePathLib.h"
18 
19 /**
20   Returns the size of a device path in bytes.
21 
22   This function returns the size, in bytes, of the device path data structure
23   specified by DevicePath including the end of device path node.
24   If DevicePath is NULL or invalid, then 0 is returned.
25 
26   @param  DevicePath  A pointer to a device path data structure.
27 
28   @retval 0           If DevicePath is NULL or invalid.
29   @retval Others      The size of a device path in bytes.
30 
31 **/
32 UINTN
GetDevicePathSize(CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)33 GetDevicePathSize (
34    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
35   )
36 {
37   return UefiDevicePathLibGetDevicePathSize (DevicePath);
38 }
39 
40 /**
41   Creates a new copy of an existing device path.
42 
43   This function allocates space for a new copy of the device path specified by DevicePath.
44   If DevicePath is NULL, then NULL is returned.  If the memory is successfully
45   allocated, then the contents of DevicePath are copied to the newly allocated
46   buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
47   The memory for the new device path is allocated from EFI boot services memory.
48   It is the responsibility of the caller to free the memory allocated.
49 
50   @param  DevicePath    A pointer to a device path data structure.
51 
52   @retval NULL          DevicePath is NULL or invalid.
53   @retval Others        A pointer to the duplicated device path.
54 
55 **/
56 EFI_DEVICE_PATH_PROTOCOL *
DuplicateDevicePath(CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)57 DuplicateDevicePath (
58    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
59   )
60 {
61   return UefiDevicePathLibDuplicateDevicePath (DevicePath);
62 }
63 
64 /**
65   Creates a new device path by appending a second device path to a first device path.
66 
67   This function creates a new device path by appending a copy of SecondDevicePath
68   to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
69   device node from SecondDevicePath is retained. The newly created device path is
70   returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
71   SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
72   and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
73   SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
74 
75   If there is not enough memory for the newly allocated buffer, then NULL is returned.
76   The memory for the new device path is allocated from EFI boot services memory.
77   It is the responsibility of the caller to free the memory allocated.
78 
79   @param  FirstDevicePath            A pointer to a device path data structure.
80   @param  SecondDevicePath           A pointer to a device path data structure.
81 
82   @retval NULL      If there is not enough memory for the newly allocated buffer.
83   @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
84   @retval Others    A pointer to the new device path if success.
85                     Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
86 
87 **/
88 EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePath(CONST EFI_DEVICE_PATH_PROTOCOL * FirstDevicePath,OPTIONAL CONST EFI_DEVICE_PATH_PROTOCOL * SecondDevicePath OPTIONAL)89 AppendDevicePath (
90    CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
91    CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
92   )
93 {
94   return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
95 }
96 
97 /**
98   Creates a new path by appending the device node to the device path.
99 
100   This function creates a new device path by appending a copy of the device node
101   specified by DevicePathNode to a copy of the device path specified by DevicePath
102   in an allocated buffer. The end-of-device-path device node is moved after the
103   end of the appended device node.
104   If DevicePathNode is NULL then a copy of DevicePath is returned.
105   If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
106   path device node is returned.
107   If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
108   device node is returned.
109   If there is not enough memory to allocate space for the new device path, then
110   NULL is returned.
111   The memory is allocated from EFI boot services memory. It is the responsibility
112   of the caller to free the memory allocated.
113 
114   @param  DevicePath                 A pointer to a device path data structure.
115   @param  DevicePathNode             A pointer to a single device path node.
116 
117   @retval NULL      If there is not enough memory for the new device path.
118   @retval Others    A pointer to the new device path if success.
119                     A copy of DevicePathNode followed by an end-of-device-path node
120                     if both FirstDevicePath and SecondDevicePath are NULL.
121                     A copy of an end-of-device-path node if both FirstDevicePath
122                     and SecondDevicePath are NULL.
123 
124 **/
125 EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePathNode(CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,OPTIONAL CONST EFI_DEVICE_PATH_PROTOCOL * DevicePathNode OPTIONAL)126 AppendDevicePathNode (
127    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
128    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
129   )
130 {
131   return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
132 }
133 
134 /**
135   Creates a new device path by appending the specified device path instance to the specified device
136   path.
137 
138   This function creates a new device path by appending a copy of the device path
139   instance specified by DevicePathInstance to a copy of the device path specified
140   by DevicePath in a allocated buffer.
141   The end-of-device-path device node is moved after the end of the appended device
142   path instance and a new end-of-device-path-instance node is inserted between.
143   If DevicePath is NULL, then a copy if DevicePathInstance is returned.
144   If DevicePathInstance is NULL, then NULL is returned.
145   If DevicePath or DevicePathInstance is invalid, then NULL is returned.
146   If there is not enough memory to allocate space for the new device path, then
147   NULL is returned.
148   The memory is allocated from EFI boot services memory. It is the responsibility
149   of the caller to free the memory allocated.
150 
151   @param  DevicePath                 A pointer to a device path data structure.
152   @param  DevicePathInstance         A pointer to a device path instance.
153 
154   @return A pointer to the new device path.
155 
156 **/
157 EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePathInstance(CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,OPTIONAL CONST EFI_DEVICE_PATH_PROTOCOL * DevicePathInstance OPTIONAL)158 AppendDevicePathInstance (
159    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL
160    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
161   )
162 {
163   return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
164 }
165 
166 /**
167   Creates a copy of the current device path instance and returns a pointer to the next device path
168   instance.
169 
170   This function creates a copy of the current device path instance. It also updates
171   DevicePath to point to the next device path instance in the device path (or NULL
172   if no more) and updates Size to hold the size of the device path instance copy.
173   If DevicePath is NULL, then NULL is returned.
174   If DevicePath points to a invalid device path, then NULL is returned.
175   If there is not enough memory to allocate space for the new device path, then
176   NULL is returned.
177   The memory is allocated from EFI boot services memory. It is the responsibility
178   of the caller to free the memory allocated.
179   If Size is NULL, then ASSERT().
180 
181   @param  DevicePath                 On input, this holds the pointer to the current
182                                      device path instance. On output, this holds
183                                      the pointer to the next device path instance
184                                      or NULL if there are no more device path
185                                      instances in the device path pointer to a
186                                      device path data structure.
187   @param  Size                       On output, this holds the size of the device
188                                      path instance, in bytes or zero, if DevicePath
189                                      is NULL.
190 
191   @return A pointer to the current device path instance.
192 
193 **/
194 EFI_DEVICE_PATH_PROTOCOL *
GetNextDevicePathInstance(EFI_DEVICE_PATH_PROTOCOL ** DevicePath,UINTN * Size)195 GetNextDevicePathInstance (
196     EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
197    UINTN                          *Size
198   )
199 {
200   return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
201 }
202 
203 /**
204   Creates a device node.
205 
206   This function creates a new device node in a newly allocated buffer of size
207   NodeLength and initializes the device path node header with NodeType and NodeSubType.
208   The new device path node is returned.
209   If NodeLength is smaller than a device path header, then NULL is returned.
210   If there is not enough memory to allocate space for the new device path, then
211   NULL is returned.
212   The memory is allocated from EFI boot services memory. It is the responsibility
213   of the caller to free the memory allocated.
214 
215   @param  NodeType                   The device node type for the new device node.
216   @param  NodeSubType                The device node sub-type for the new device node.
217   @param  NodeLength                 The length of the new device node.
218 
219   @return The new device path.
220 
221 **/
222 EFI_DEVICE_PATH_PROTOCOL *
CreateDeviceNode(UINT8 NodeType,UINT8 NodeSubType,UINT16 NodeLength)223 CreateDeviceNode (
224    UINT8                           NodeType,
225    UINT8                           NodeSubType,
226    UINT16                          NodeLength
227   )
228 {
229   return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
230 }
231 
232 /**
233   Determines if a device path is single or multi-instance.
234 
235   This function returns TRUE if the device path specified by DevicePath is
236   multi-instance.
237   Otherwise, FALSE is returned.
238   If DevicePath is NULL or invalid, then FALSE is returned.
239 
240   @param  DevicePath                 A pointer to a device path data structure.
241 
242   @retval  TRUE                      DevicePath is multi-instance.
243   @retval  FALSE                     DevicePath is not multi-instance, or DevicePath
244                                      is NULL or invalid.
245 
246 **/
247 BOOLEAN
IsDevicePathMultiInstance(CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath)248 IsDevicePathMultiInstance (
249    CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
250   )
251 {
252   return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
253 }
254 
255 /**
256   Convert text to the binary representation of a device node.
257 
258   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
259                          node. Conversion starts with the first character and continues
260                          until the first non-device node character.
261 
262   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
263           insufficient memory or text unsupported.
264 
265 **/
266 EFI_DEVICE_PATH_PROTOCOL *
ConvertTextToDeviceNode(CONST CHAR16 * TextDeviceNode)267 ConvertTextToDeviceNode (
268    CONST CHAR16 *TextDeviceNode
269   )
270 {
271   return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
272 }
273 
274 /**
275   Convert text to the binary representation of a device path.
276 
277 
278   @param TextDevicePath  TextDevicePath points to the text representation of a device
279                          path. Conversion starts with the first character and continues
280                          until the first non-device node character.
281 
282   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
283           there was insufficient memory.
284 
285 **/
286 EFI_DEVICE_PATH_PROTOCOL *
ConvertTextToDevicePath(CONST CHAR16 * TextDevicePath)287 ConvertTextToDevicePath (
288    CONST CHAR16 *TextDevicePath
289  )
290 {
291   return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
292 }
293