]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / UefiDevicePathLibDevicePathProtocol / UefiDevicePathLib.c
CommitLineData
e386b444 1/** @file\r
f008fc32 2 Library instance that implement UEFI Device Path Library class based on protocol\r
3 gEfiDevicePathUtilitiesProtocolGuid.\r
e386b444 4\r
9095d37b 5 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9344f092 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e386b444 7\r
e386b444 8**/\r
9\r
c7d265a9 10#include <Uefi.h>\r
c892d846 11\r
c7d265a9 12#include <Protocol/DevicePathUtilities.h>\r
4d0a30a4
RN
13#include <Protocol/DevicePathToText.h>\r
14#include <Protocol/DevicePathFromText.h>\r
c892d846 15\r
c7d265a9 16#include <Library/DevicePathLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
771729c7 22#include <Library/PcdLib.h>\r
e386b444 23\r
2f88bd3a
MK
24GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;\r
25GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathLibDevicePathToText = NULL;\r
26GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText = NULL;\r
e386b444 27\r
3dc728fb 28//\r
29// Template for an end-of-device path node.\r
30//\r
31GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {\r
32 END_DEVICE_PATH_TYPE,\r
33 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
34 {\r
35 END_DEVICE_PATH_LENGTH,\r
36 0\r
37 }\r
38};\r
39\r
e386b444 40/**\r
41 The constructor function caches the pointer to DevicePathUtilites protocol.\r
9095d37b 42\r
e386b444 43 The constructor function locates DevicePathUtilities protocol from protocol database.\r
9095d37b 44 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
e386b444 45\r
46 @param ImageHandle The firmware allocated handle for the EFI image.\r
47 @param SystemTable A pointer to the EFI System Table.\r
9095d37b 48\r
e386b444 49 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
50\r
51**/\r
52EFI_STATUS\r
53EFIAPI\r
54DevicePathLibConstructor (\r
2f88bd3a
MK
55 IN EFI_HANDLE ImageHandle,\r
56 IN EFI_SYSTEM_TABLE *SystemTable\r
e386b444 57 )\r
58{\r
2f88bd3a 59 EFI_STATUS Status;\r
e386b444 60\r
61 Status = gBS->LocateProtocol (\r
62 &gEfiDevicePathUtilitiesProtocolGuid,\r
63 NULL,\r
2f88bd3a 64 (VOID **)&mDevicePathLibDevicePathUtilities\r
e386b444 65 );\r
66 ASSERT_EFI_ERROR (Status);\r
4d0a30a4 67 ASSERT (mDevicePathLibDevicePathUtilities != NULL);\r
e386b444 68 return Status;\r
69}\r
70\r
771729c7
RN
71/**\r
72 Determine whether a given device path is valid.\r
73 If DevicePath is NULL, then ASSERT().\r
74\r
75 @param DevicePath A pointer to a device path data structure.\r
76 @param MaxSize The maximum size of the device path data structure.\r
77\r
78 @retval TRUE DevicePath is valid.\r
79 @retval FALSE The length of any node node in the DevicePath is less\r
80 than sizeof (EFI_DEVICE_PATH_PROTOCOL).\r
81 @retval FALSE If MaxSize is not zero, the size of the DevicePath\r
82 exceeds MaxSize.\r
83 @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node\r
84 count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.\r
85**/\r
86BOOLEAN\r
87EFIAPI\r
88IsDevicePathValid (\r
2f88bd3a
MK
89 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
90 IN UINTN MaxSize\r
771729c7
RN
91 )\r
92{\r
2f88bd3a
MK
93 UINTN Count;\r
94 UINTN Size;\r
95 UINTN NodeLength;\r
771729c7
RN
96\r
97 ASSERT (DevicePath != NULL);\r
98\r
c0cba3d5
ED
99 if (MaxSize == 0) {\r
100 MaxSize = MAX_UINTN;\r
101 }\r
102\r
103 //\r
104 // Validate the input size big enough to touch the first node.\r
105 //\r
106 if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
107 return FALSE;\r
108 }\r
109\r
1420143f 110 for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {\r
771729c7
RN
111 NodeLength = DevicePathNodeLength (DevicePath);\r
112 if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
113 return FALSE;\r
114 }\r
115\r
c0cba3d5
ED
116 if (NodeLength > MAX_UINTN - Size) {\r
117 return FALSE;\r
118 }\r
2f88bd3a 119\r
c0cba3d5
ED
120 Size += NodeLength;\r
121\r
122 //\r
123 // Validate next node before touch it.\r
124 //\r
125 if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {\r
126 return FALSE;\r
771729c7
RN
127 }\r
128\r
129 if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {\r
130 Count++;\r
131 if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {\r
132 return FALSE;\r
133 }\r
134 }\r
7c0e8053
JW
135\r
136 //\r
137 // FilePath must be a NULL-terminated string.\r
138 //\r
2f88bd3a
MK
139 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&\r
140 (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP) &&\r
141 (*(CHAR16 *)((UINT8 *)DevicePath + NodeLength - 2) != 0))\r
142 {\r
7c0e8053
JW
143 return FALSE;\r
144 }\r
771729c7
RN
145 }\r
146\r
147 //\r
148 // Only return TRUE when the End Device Path node is valid.\r
149 //\r
2f88bd3a 150 return (BOOLEAN)(DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);\r
771729c7
RN
151}\r
152\r
3dc728fb 153/**\r
154 Returns the Type field of a device path node.\r
155\r
156 Returns the Type field of the device path node specified by Node.\r
157\r
158 If Node is NULL, then ASSERT().\r
159\r
160 @param Node A pointer to a device path node data structure.\r
161\r
162 @return The Type field of the device path node specified by Node.\r
163\r
164**/\r
165UINT8\r
5cba121d 166EFIAPI\r
3dc728fb 167DevicePathType (\r
168 IN CONST VOID *Node\r
169 )\r
170{\r
171 ASSERT (Node != NULL);\r
172 return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;\r
173}\r
174\r
175/**\r
176 Returns the SubType field of a device path node.\r
177\r
178 Returns the SubType field of the device path node specified by Node.\r
179\r
180 If Node is NULL, then ASSERT().\r
181\r
182 @param Node A pointer to a device path node data structure.\r
183\r
184 @return The SubType field of the device path node specified by Node.\r
185\r
186**/\r
187UINT8\r
5cba121d 188EFIAPI\r
3dc728fb 189DevicePathSubType (\r
190 IN CONST VOID *Node\r
191 )\r
192{\r
193 ASSERT (Node != NULL);\r
194 return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;\r
195}\r
196\r
197/**\r
198 Returns the 16-bit Length field of a device path node.\r
199\r
9095d37b 200 Returns the 16-bit Length field of the device path node specified by Node.\r
3dc728fb 201 Node is not required to be aligned on a 16-bit boundary, so it is recommended\r
9095d37b 202 that a function such as ReadUnaligned16() be used to extract the contents of\r
3dc728fb 203 the Length field.\r
204\r
205 If Node is NULL, then ASSERT().\r
206\r
207 @param Node A pointer to a device path node data structure.\r
208\r
209 @return The 16-bit Length field of the device path node specified by Node.\r
210\r
211**/\r
212UINTN\r
5cba121d 213EFIAPI\r
3dc728fb 214DevicePathNodeLength (\r
215 IN CONST VOID *Node\r
216 )\r
217{\r
218 ASSERT (Node != NULL);\r
0b13fe74 219 return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);\r
3dc728fb 220}\r
221\r
222/**\r
223 Returns a pointer to the next node in a device path.\r
224\r
9095d37b 225 Returns a pointer to the device path node that follows the device path node\r
58380e9c 226 specified by Node.\r
3dc728fb 227\r
228 If Node is NULL, then ASSERT().\r
229\r
230 @param Node A pointer to a device path node data structure.\r
231\r
9095d37b 232 @return a pointer to the device path node that follows the device path node\r
58380e9c 233 specified by Node.\r
3dc728fb 234\r
235**/\r
236EFI_DEVICE_PATH_PROTOCOL *\r
5cba121d 237EFIAPI\r
3dc728fb 238NextDevicePathNode (\r
239 IN CONST VOID *Node\r
240 )\r
241{\r
242 ASSERT (Node != NULL);\r
2f88bd3a 243 return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength (Node));\r
3dc728fb 244}\r
245\r
246/**\r
247 Determines if a device path node is an end node of a device path.\r
9095d37b 248 This includes nodes that are the end of a device path instance and nodes that\r
58380e9c 249 are the end of an entire device path.\r
3dc728fb 250\r
9095d37b
LG
251 Determines if the device path node specified by Node is an end node of a device path.\r
252 This includes nodes that are the end of a device path instance and nodes that are the\r
253 end of an entire device path. If Node represents an end node of a device path,\r
3dc728fb 254 then TRUE is returned. Otherwise, FALSE is returned.\r
255\r
256 If Node is NULL, then ASSERT().\r
257\r
258 @param Node A pointer to a device path node data structure.\r
259\r
260 @retval TRUE The device path node specified by Node is an end node of a device path.\r
9095d37b 261 @retval FALSE The device path node specified by Node is not an end node of\r
58380e9c 262 a device path.\r
9095d37b 263\r
3dc728fb 264**/\r
265BOOLEAN\r
5cba121d 266EFIAPI\r
3dc728fb 267IsDevicePathEndType (\r
268 IN CONST VOID *Node\r
269 )\r
270{\r
271 ASSERT (Node != NULL);\r
2f88bd3a 272 return (BOOLEAN)(DevicePathType (Node) == END_DEVICE_PATH_TYPE);\r
3dc728fb 273}\r
274\r
275/**\r
276 Determines if a device path node is an end node of an entire device path.\r
277\r
9095d37b 278 Determines if a device path node specified by Node is an end node of an entire\r
58380e9c 279 device path.\r
9095d37b 280 If Node represents the end of an entire device path, then TRUE is returned.\r
58380e9c 281 Otherwise, FALSE is returned.\r
3dc728fb 282\r
283 If Node is NULL, then ASSERT().\r
284\r
285 @param Node A pointer to a device path node data structure.\r
286\r
287 @retval TRUE The device path node specified by Node is the end of an entire device path.\r
288 @retval FALSE The device path node specified by Node is not the end of an entire device path.\r
289\r
290**/\r
291BOOLEAN\r
5cba121d 292EFIAPI\r
3dc728fb 293IsDevicePathEnd (\r
294 IN CONST VOID *Node\r
295 )\r
296{\r
297 ASSERT (Node != NULL);\r
2f88bd3a 298 return (BOOLEAN)(IsDevicePathEndType (Node) && DevicePathSubType (Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);\r
3dc728fb 299}\r
300\r
301/**\r
302 Determines if a device path node is an end node of a device path instance.\r
303\r
9095d37b 304 Determines if a device path node specified by Node is an end node of a device\r
58380e9c 305 path instance.\r
9095d37b 306 If Node represents the end of a device path instance, then TRUE is returned.\r
58380e9c 307 Otherwise, FALSE is returned.\r
3dc728fb 308\r
309 If Node is NULL, then ASSERT().\r
310\r
311 @param Node A pointer to a device path node data structure.\r
312\r
9095d37b 313 @retval TRUE The device path node specified by Node is the end of a device\r
58380e9c 314 path instance.\r
9095d37b 315 @retval FALSE The device path node specified by Node is not the end of a\r
58380e9c 316 device path instance.\r
3dc728fb 317\r
318**/\r
319BOOLEAN\r
5cba121d 320EFIAPI\r
3dc728fb 321IsDevicePathEndInstance (\r
322 IN CONST VOID *Node\r
323 )\r
324{\r
325 ASSERT (Node != NULL);\r
2f88bd3a 326 return (BOOLEAN)(IsDevicePathEndType (Node) && DevicePathSubType (Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);\r
3dc728fb 327}\r
328\r
329/**\r
330 Sets the length, in bytes, of a device path node.\r
331\r
9095d37b
LG
332 Sets the length of the device path node specified by Node to the value specified\r
333 by NodeLength. NodeLength is returned. Node is not required to be aligned on\r
3dc728fb 334 a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()\r
335 be used to set the contents of the Length field.\r
336\r
337 If Node is NULL, then ASSERT().\r
771729c7
RN
338 If NodeLength >= SIZE_64KB, then ASSERT().\r
339 If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().\r
3dc728fb 340\r
341 @param Node A pointer to a device path node data structure.\r
342 @param Length The length, in bytes, of the device path node.\r
343\r
344 @return Length\r
345\r
346**/\r
347UINT16\r
5cba121d 348EFIAPI\r
3dc728fb 349SetDevicePathNodeLength (\r
9bb407c6 350 IN OUT VOID *Node,\r
8f0dd97e 351 IN UINTN Length\r
3dc728fb 352 )\r
353{\r
354 ASSERT (Node != NULL);\r
771729c7 355 ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));\r
8f0dd97e 356 return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));\r
3dc728fb 357}\r
358\r
359/**\r
360 Fills in all the fields of a device path node that is the end of an entire device path.\r
361\r
9095d37b
LG
362 Fills in all the fields of a device path node specified by Node so Node represents\r
363 the end of an entire device path. The Type field of Node is set to\r
364 END_DEVICE_PATH_TYPE, the SubType field of Node is set to\r
365 END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to\r
366 END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,\r
367 so it is recommended that a function such as WriteUnaligned16() be used to set\r
368 the contents of the Length field.\r
3dc728fb 369\r
9095d37b 370 If Node is NULL, then ASSERT().\r
3dc728fb 371\r
372 @param Node A pointer to a device path node data structure.\r
373\r
374**/\r
375VOID\r
5cba121d 376EFIAPI\r
3dc728fb 377SetDevicePathEndNode (\r
9bb407c6 378 OUT VOID *Node\r
3dc728fb 379 )\r
380{\r
381 ASSERT (Node != NULL);\r
382 CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));\r
383}\r
384\r
e386b444 385/**\r
386 Returns the size of a device path in bytes.\r
387\r
9095d37b 388 This function returns the size, in bytes, of the device path data structure\r
771729c7
RN
389 specified by DevicePath including the end of device path node.\r
390 If DevicePath is NULL or invalid, then 0 is returned.\r
e386b444 391\r
771729c7
RN
392 @param DevicePath A pointer to a device path data structure.\r
393\r
394 @retval 0 If DevicePath is NULL or invalid.\r
395 @retval Others The size of a device path in bytes.\r
e386b444 396\r
397**/\r
398UINTN\r
399EFIAPI\r
400GetDevicePathSize (\r
401 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
402 )\r
403{\r
4d0a30a4 404 return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);\r
e386b444 405}\r
406\r
407/**\r
6a3f4ef9 408 Creates a new copy of an existing device path.\r
e386b444 409\r
9095d37b
LG
410 This function allocates space for a new copy of the device path specified by\r
411 DevicePath. If DevicePath is NULL, then NULL is returned.\r
58380e9c 412 If the memory is successfully allocated, then the\r
e386b444 413 contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer\r
9095d37b
LG
414 is returned. Otherwise, NULL is returned.\r
415 The memory for the new device path is allocated from EFI boot services memory.\r
416 It is the responsibility of the caller to free the memory allocated.\r
417\r
e386b444 418 @param DevicePath A pointer to a device path data structure.\r
419\r
771729c7 420 @retval NULL If DevicePath is NULL or invalid.\r
3e5c3238 421 @retval Others A pointer to the duplicated device path.\r
9095d37b 422\r
e386b444 423**/\r
424EFI_DEVICE_PATH_PROTOCOL *\r
425EFIAPI\r
426DuplicateDevicePath (\r
427 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
428 )\r
429{\r
4d0a30a4 430 return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);\r
e386b444 431}\r
432\r
433/**\r
434 Creates a new device path by appending a second device path to a first device path.\r
435\r
436 This function creates a new device path by appending a copy of SecondDevicePath to a copy of\r
437 FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from\r
9095d37b
LG
438 SecondDevicePath is retained. The newly created device path is returned.\r
439 If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.\r
440 If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.\r
98a14db6 441 If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is\r
9095d37b 442 returned.\r
e386b444 443 If there is not enough memory for the newly allocated buffer, then NULL is returned.\r
444 The memory for the new device path is allocated from EFI boot services memory. It is the\r
445 responsibility of the caller to free the memory allocated.\r
446\r
447 @param FirstDevicePath A pointer to a device path data structure.\r
448 @param SecondDevicePath A pointer to a device path data structure.\r
9095d37b 449\r
3e5c3238 450 @retval NULL If there is not enough memory for the newly allocated buffer.\r
771729c7 451 @retval NULL If FirstDevicePath or SecondDevicePath is invalid.\r
3e5c3238 452 @retval Others A pointer to the new device path if success.\r
9095d37b 453 Or a copy an end-of-device-path if both FirstDevicePath and\r
58380e9c 454 SecondDevicePath are NULL.\r
e386b444 455\r
456**/\r
457EFI_DEVICE_PATH_PROTOCOL *\r
458EFIAPI\r
459AppendDevicePath (\r
d0e2f823 460 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL,\r
e386b444 461 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL\r
462 )\r
463{\r
4d0a30a4 464 return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);\r
e386b444 465}\r
466\r
467/**\r
468 Creates a new path by appending the device node to the device path.\r
469\r
9095d37b
LG
470 This function creates a new device path by appending a copy of the device node\r
471 specified by DevicePathNode to a copy of the device path specified by DevicePath\r
58380e9c 472 in an allocated buffer.\r
e386b444 473 The end-of-device-path device node is moved after the end of the appended device node.\r
98a14db6 474 If DevicePathNode is NULL then a copy of DevicePath is returned.\r
9095d37b 475 If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device\r
58380e9c 476 path device node is returned.\r
9095d37b 477 If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path\r
58380e9c 478 device node is returned.\r
9095d37b
LG
479 If there is not enough memory to allocate space for the new device path, then\r
480 NULL is returned.\r
481 The memory is allocated from EFI boot services memory. It is the responsibility\r
58380e9c 482 of the caller to free the memory allocated.\r
e386b444 483\r
484 @param DevicePath A pointer to a device path data structure.\r
485 @param DevicePathNode A pointer to a single device path node.\r
486\r
3e5c3238 487 @retval NULL If there is not enough memory for the new device path.\r
488 @retval Others A pointer to the new device path if success.\r
9095d37b 489 A copy of DevicePathNode followed by an end-of-device-path node\r
3e5c3238 490 if both FirstDevicePath and SecondDevicePath are NULL.\r
9095d37b 491 A copy of an end-of-device-path node if both FirstDevicePath\r
58380e9c 492 and SecondDevicePath are NULL.\r
e386b444 493\r
494**/\r
495EFI_DEVICE_PATH_PROTOCOL *\r
496EFIAPI\r
497AppendDevicePathNode (\r
d0e2f823 498 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,\r
e386b444 499 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL\r
500 )\r
501{\r
4d0a30a4 502 return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);\r
e386b444 503}\r
504\r
505/**\r
9095d37b 506 Creates a new device path by appending the specified device path instance to\r
58380e9c 507 the specified device path.\r
9095d37b
LG
508\r
509 This function creates a new device path by appending a copy of the device path\r
510 instance specified by DevicePathInstance to a copy of the device path specified\r
58380e9c 511 by DevicePath in a allocated buffer.\r
9095d37b
LG
512 The end-of-device-path device node is moved after the end of the appended device\r
513 path instance and a new end-of-device-path-instance node is inserted between.\r
e386b444 514 If DevicePath is NULL, then a copy if DevicePathInstance is returned.\r
515 If DevicePathInstance is NULL, then NULL is returned.\r
771729c7 516 If DevicePath or DevicePathInstance is invalid, then NULL is returned.\r
9095d37b
LG
517 If there is not enough memory to allocate space for the new device path, then\r
518 NULL is returned.\r
519 The memory is allocated from EFI boot services memory. It is the responsibility\r
58380e9c 520 of the caller to free the memory allocated.\r
9095d37b 521\r
e386b444 522 @param DevicePath A pointer to a device path data structure.\r
523 @param DevicePathInstance A pointer to a device path instance.\r
524\r
525 @return A pointer to the new device path.\r
526\r
527**/\r
528EFI_DEVICE_PATH_PROTOCOL *\r
529EFIAPI\r
530AppendDevicePathInstance (\r
d0e2f823 531 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,\r
e386b444 532 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL\r
533 )\r
534{\r
4d0a30a4 535 return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);\r
e386b444 536}\r
537\r
538/**\r
9095d37b 539 Creates a copy of the current device path instance and returns a pointer to the\r
58380e9c 540 next device path instance.\r
e386b444 541\r
9095d37b
LG
542 This function creates a copy of the current device path instance. It also updates\r
543 DevicePath to point to the next device path instance in the device path (or NULL\r
58380e9c 544 if no more) and updates Size to hold the size of the device path instance copy.\r
e386b444 545 If DevicePath is NULL, then NULL is returned.\r
9095d37b
LG
546 If there is not enough memory to allocate space for the new device path, then\r
547 NULL is returned.\r
548 The memory is allocated from EFI boot services memory. It is the responsibility\r
58380e9c 549 of the caller to free the memory allocated.\r
e386b444 550 If Size is NULL, then ASSERT().\r
9095d37b
LG
551\r
552 @param DevicePath On input, this holds the pointer to the current\r
553 device path instance. On output, this holds\r
554 the pointer to the next device path instance\r
58380e9c 555 or NULL if there are no more device path\r
9095d37b 556 instances in the device path pointer to a\r
58380e9c 557 device path data structure.\r
9095d37b
LG
558 @param Size On output, this holds the size of the device\r
559 path instance, in bytes or zero, if DevicePath\r
58380e9c 560 is NULL.\r
e386b444 561\r
562 @return A pointer to the current device path instance.\r
563\r
564**/\r
565EFI_DEVICE_PATH_PROTOCOL *\r
566EFIAPI\r
567GetNextDevicePathInstance (\r
2f88bd3a
MK
568 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
569 OUT UINTN *Size\r
e386b444 570 )\r
571{\r
572 ASSERT (Size != NULL);\r
4d0a30a4 573 return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);\r
e386b444 574}\r
575\r
576/**\r
3e5c3238 577 Creates a device node.\r
e386b444 578\r
9095d37b
LG
579 This function creates a new device node in a newly allocated buffer of size\r
580 NodeLength and initializes the device path node header with NodeType and NodeSubType.\r
58380e9c 581 The new device path node is returned.\r
9095d37b
LG
582 If NodeLength is smaller than a device path header, then NULL is returned.\r
583 If there is not enough memory to allocate space for the new device path, then\r
584 NULL is returned.\r
585 The memory is allocated from EFI boot services memory. It is the responsibility\r
0b13fe74 586 of the caller to free the memory allocated.\r
e386b444 587\r
588 @param NodeType The device node type for the new device node.\r
589 @param NodeSubType The device node sub-type for the new device node.\r
590 @param NodeLength The length of the new device node.\r
591\r
3e5c3238 592 @return The new device path.\r
e386b444 593\r
594**/\r
595EFI_DEVICE_PATH_PROTOCOL *\r
596EFIAPI\r
597CreateDeviceNode (\r
2f88bd3a
MK
598 IN UINT8 NodeType,\r
599 IN UINT8 NodeSubType,\r
600 IN UINT16 NodeLength\r
e386b444 601 )\r
602{\r
4d0a30a4 603 return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);\r
e386b444 604}\r
605\r
606/**\r
607 Determines if a device path is single or multi-instance.\r
608\r
771729c7 609 This function returns TRUE if the device path specified by DevicePath is\r
58380e9c 610 multi-instance.\r
771729c7
RN
611 Otherwise, FALSE is returned.\r
612 If DevicePath is NULL or invalid, then FALSE is returned.\r
e386b444 613\r
614 @param DevicePath A pointer to a device path data structure.\r
615\r
616 @retval TRUE DevicePath is multi-instance.\r
9095d37b 617 @retval FALSE DevicePath is not multi-instance, or DevicePath\r
771729c7 618 is NULL or invalid.\r
e386b444 619\r
620**/\r
621BOOLEAN\r
622EFIAPI\r
623IsDevicePathMultiInstance (\r
624 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
625 )\r
626{\r
4d0a30a4 627 return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);\r
e386b444 628}\r
629\r
630/**\r
631 Retrieves the device path protocol from a handle.\r
632\r
9095d37b
LG
633 This function returns the device path protocol from the handle specified by Handle.\r
634 If Handle is NULL or Handle does not contain a device path protocol, then NULL\r
58380e9c 635 is returned.\r
9095d37b
LG
636\r
637 @param Handle The handle from which to retrieve the device\r
58380e9c 638 path protocol.\r
e386b444 639\r
640 @return The device path protocol from the handle specified by Handle.\r
641\r
642**/\r
643EFI_DEVICE_PATH_PROTOCOL *\r
644EFIAPI\r
645DevicePathFromHandle (\r
2f88bd3a 646 IN EFI_HANDLE Handle\r
e386b444 647 )\r
648{\r
649 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
650 EFI_STATUS Status;\r
651\r
652 Status = gBS->HandleProtocol (\r
653 Handle,\r
654 &gEfiDevicePathProtocolGuid,\r
2f88bd3a 655 (VOID *)&DevicePath\r
e386b444 656 );\r
657 if (EFI_ERROR (Status)) {\r
658 DevicePath = NULL;\r
659 }\r
2f88bd3a 660\r
e386b444 661 return DevicePath;\r
662}\r
663\r
664/**\r
665 Allocates a device path for a file and appends it to an existing device path.\r
666\r
9095d37b
LG
667 If Device is a valid device handle that contains a device path protocol, then\r
668 a device path for the file specified by FileName is allocated and appended to\r
669 the device path associated with the handle Device. The allocated device path\r
670 is returned. If Device is NULL or Device is a handle that does not support the\r
671 device path protocol, then a device path containing a single device path node\r
58380e9c 672 for the file specified by FileName is allocated and returned.\r
9095d37b 673 The memory for the new device path is allocated from EFI boot services memory.\r
58380e9c 674 It is the responsibility of the caller to free the memory allocated.\r
9095d37b 675\r
e386b444 676 If FileName is NULL, then ASSERT().\r
3e5c3238 677 If FileName is not aligned on a 16-bit boundary, then ASSERT().\r
e386b444 678\r
9095d37b 679 @param Device A pointer to a device handle. This parameter\r
58380e9c 680 is optional and may be NULL.\r
e386b444 681 @param FileName A pointer to a Null-terminated Unicode string.\r
682\r
3e5c3238 683 @return The allocated device path.\r
e386b444 684\r
685**/\r
686EFI_DEVICE_PATH_PROTOCOL *\r
687EFIAPI\r
688FileDevicePath (\r
2f88bd3a
MK
689 IN EFI_HANDLE Device OPTIONAL,\r
690 IN CONST CHAR16 *FileName\r
e386b444 691 )\r
692{\r
693 UINTN Size;\r
694 FILEPATH_DEVICE_PATH *FilePath;\r
695 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
696 EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;\r
697\r
698 DevicePath = NULL;\r
699\r
2f88bd3a 700 Size = StrSize (FileName);\r
e5dab016 701 FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);\r
e386b444 702 if (FileDevicePath != NULL) {\r
2f88bd3a 703 FilePath = (FILEPATH_DEVICE_PATH *)FileDevicePath;\r
e386b444 704 FilePath->Header.Type = MEDIA_DEVICE_PATH;\r
705 FilePath->Header.SubType = MEDIA_FILEPATH_DP;\r
706 CopyMem (&FilePath->PathName, FileName, Size);\r
707 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);\r
708 SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));\r
709\r
710 if (Device != NULL) {\r
711 DevicePath = DevicePathFromHandle (Device);\r
712 }\r
713\r
714 DevicePath = AppendDevicePath (DevicePath, FileDevicePath);\r
715 FreePool (FileDevicePath);\r
716 }\r
717\r
718 return DevicePath;\r
719}\r
4d0a30a4
RN
720\r
721/**\r
722 Locate and return the protocol instance identified by the ProtocolGuid.\r
723\r
724 @param ProtocolGuid The GUID of the protocol.\r
725\r
726 @return A pointer to the protocol instance or NULL when absent.\r
727**/\r
728VOID *\r
729UefiDevicePathLibLocateProtocol (\r
2f88bd3a 730 EFI_GUID *ProtocolGuid\r
4d0a30a4
RN
731 )\r
732{\r
2f88bd3a
MK
733 EFI_STATUS Status;\r
734 VOID *Protocol;\r
735\r
4d0a30a4
RN
736 Status = gBS->LocateProtocol (\r
737 ProtocolGuid,\r
738 NULL,\r
2f88bd3a 739 (VOID **)&Protocol\r
4d0a30a4
RN
740 );\r
741 if (EFI_ERROR (Status)) {\r
742 return NULL;\r
743 } else {\r
744 return Protocol;\r
745 }\r
746}\r
747\r
748/**\r
749 Converts a device node to its string representation.\r
750\r
751 @param DeviceNode A Pointer to the device node to be converted.\r
752 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation\r
753 of the display node is used, where applicable. If DisplayOnly\r
754 is FALSE, then the longer text representation of the display node\r
755 is used.\r
756 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text\r
757 representation for a device node can be used, where applicable.\r
758\r
759 @return A pointer to the allocated text representation of the device node or NULL if DeviceNode\r
760 is NULL or there was insufficient memory.\r
761\r
762**/\r
763CHAR16 *\r
764EFIAPI\r
765ConvertDeviceNodeToText (\r
766 IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,\r
767 IN BOOLEAN DisplayOnly,\r
768 IN BOOLEAN AllowShortcuts\r
769 )\r
770{\r
771 if (mDevicePathLibDevicePathToText == NULL) {\r
772 mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);\r
773 }\r
2f88bd3a 774\r
4d0a30a4
RN
775 if (mDevicePathLibDevicePathToText != NULL) {\r
776 return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);\r
777 } else {\r
778 return NULL;\r
779 }\r
780}\r
781\r
782/**\r
783 Converts a device path to its text representation.\r
784\r
785 @param DevicePath A Pointer to the device to be converted.\r
786 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation\r
787 of the display node is used, where applicable. If DisplayOnly\r
788 is FALSE, then the longer text representation of the display node\r
789 is used.\r
790 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text\r
791 representation for a device node can be used, where applicable.\r
792\r
793 @return A pointer to the allocated text representation of the device path or\r
794 NULL if DeviceNode is NULL or there was insufficient memory.\r
795\r
796**/\r
797CHAR16 *\r
798EFIAPI\r
799ConvertDevicePathToText (\r
2f88bd3a
MK
800 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
801 IN BOOLEAN DisplayOnly,\r
802 IN BOOLEAN AllowShortcuts\r
4d0a30a4
RN
803 )\r
804{\r
805 if (mDevicePathLibDevicePathToText == NULL) {\r
806 mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);\r
807 }\r
2f88bd3a 808\r
4d0a30a4
RN
809 if (mDevicePathLibDevicePathToText != NULL) {\r
810 return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);\r
811 } else {\r
812 return NULL;\r
813 }\r
814}\r
815\r
816/**\r
817 Convert text to the binary representation of a device node.\r
818\r
819 @param TextDeviceNode TextDeviceNode points to the text representation of a device\r
820 node. Conversion starts with the first character and continues\r
821 until the first non-device node character.\r
822\r
823 @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was\r
824 insufficient memory or text unsupported.\r
825\r
826**/\r
827EFI_DEVICE_PATH_PROTOCOL *\r
828EFIAPI\r
829ConvertTextToDeviceNode (\r
2f88bd3a 830 IN CONST CHAR16 *TextDeviceNode\r
4d0a30a4
RN
831 )\r
832{\r
833 if (mDevicePathLibDevicePathFromText == NULL) {\r
834 mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);\r
835 }\r
2f88bd3a 836\r
4d0a30a4
RN
837 if (mDevicePathLibDevicePathFromText != NULL) {\r
838 return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);\r
839 } else {\r
840 return NULL;\r
841 }\r
842}\r
843\r
844/**\r
845 Convert text to the binary representation of a device path.\r
846\r
847\r
848 @param TextDevicePath TextDevicePath points to the text representation of a device\r
849 path. Conversion starts with the first character and continues\r
850 until the first non-device node character.\r
851\r
852 @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or\r
853 there was insufficient memory.\r
854\r
855**/\r
856EFI_DEVICE_PATH_PROTOCOL *\r
857EFIAPI\r
858ConvertTextToDevicePath (\r
2f88bd3a 859 IN CONST CHAR16 *TextDevicePath\r
4d0a30a4
RN
860 )\r
861{\r
862 if (mDevicePathLibDevicePathFromText == NULL) {\r
863 mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);\r
864 }\r
2f88bd3a 865\r
4d0a30a4
RN
866 if (mDevicePathLibDevicePathFromText != NULL) {\r
867 return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);\r
868 } else {\r
869 return NULL;\r
870 }\r
871}\r