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