13eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 23eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 33e99020dbf0a159e34b84e7ae9125f2e368d5390lgaoCopyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> 44ea9375a2d02a43671437e0d3d808d85afb30afahhtianThis program and the accompanying materials 53eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangare licensed and made available under the terms and conditions of the BSD License 63eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangwhich accompanies this distribution. The full text of the license may be found at 73eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwanghttp://opensource.org/licenses/bsd-license.php 83eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 93eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangModule Name: 133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath.c 153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAbstract: 173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Device Path services. The thing to remember is device paths are built out of 193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang nodes. The device path is terminated by an end node that is length 203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) 213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang all over this file. 223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The only place where multi-instance device paths are supported is in 243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang environment varibles. Multi-instance device paths should never be placed 253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang on a Handle. 263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang#include "Tiano.h" 303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang#include "EfiDriverLib.h" 313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang#include EFI_PROTOCOL_DEFINITION (DevicePath) 323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiDevicePathInstance ( 353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, 363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang OUT UINTN *Size 373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Function retrieves the next device path instance from a device path data structure. 423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath - A pointer to a device path data structure. 453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size - A pointer to the size of a device path instance in bytes. 473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function returns a pointer to the current device path instance. 513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang In addition, it returns the size in bytes of the current device path instance in Size, 523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang and a pointer to the next device path instance in DevicePath. 533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If there are no more device path instances in DevicePath, then DevicePath will be set to NULL. 543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *DevPath; 583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *ReturnValue; 593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT8 Temp; 603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (*DevicePath == NULL) { 623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Size != NULL) { 633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *Size = 0; 643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Find the end of the device path instance 713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath = *DevicePath; 733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang while (!IsDevicePathEndType (DevPath)) { 743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath = NextDevicePathNode (DevPath); 753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Compute the size of the device path instance 793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Size != NULL) { 813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL); 823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Make a copy and return the device path instance 863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Temp = DevPath->SubType; 883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; 893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ReturnValue = EfiDuplicateDevicePath (*DevicePath); 903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath->SubType = Temp; 913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // If DevPath is the end of an entire device path, then another instance 943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // does not follow, so *DevicePath is set to NULL. 953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { 973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *DevicePath = NULL; 983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } else { 993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *DevicePath = NextDevicePathNode (DevPath); 1003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return ReturnValue; 1033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 1043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangBOOLEAN 1063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiIsDevicePathMultiInstance ( 1073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 1103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 1123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Return TRUE is this is a multi instance device path. 1133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 1153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath - A pointer to a device path data structure. 1163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 1193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi 1203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang instance. 1213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 1233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 1243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *Node; 1253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (DevicePath == NULL) { 1273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return FALSE; 1283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Node = DevicePath; 1313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang while (!EfiIsDevicePathEnd (Node)) { 1323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (EfiIsDevicePathEndInstance (Node)) { 1333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return TRUE; 1343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Node = EfiNextDevicePathNode (Node); 1373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return FALSE; 1403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 1413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINTN 1433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiDevicePathSize ( 1443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 1473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 1493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Calculate the space size of a device path. 1513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 1533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath - A specified device path 1553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 1573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The size. 1593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 1613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 1623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *Start; 1633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (DevicePath == NULL) { 1653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return 0; 1663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 1693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Search for the end of the device path structure 1703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 1713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Start = DevicePath; 1723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang while (!EfiIsDevicePathEnd (DevicePath)) { 1733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath = EfiNextDevicePathNode (DevicePath); 1743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 1773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Compute the size and add back in the size of the end device path structure 1783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 1793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL); 1803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 1813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 1833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiDevicePathFromHandle ( 1843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_HANDLE Handle 1853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 1873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 1893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Get the device path protocol interface installed on a specified handle. 1913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 1933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Handle - a specified handle 1953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 1973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The device path protocol interface installed on that handle. 1993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 2013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *DevicePath; 2033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath = NULL; 2053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang gBS->HandleProtocol ( 2063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Handle, 2073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang &gEfiDevicePathProtocolGuid, 2083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (VOID *) &DevicePath 2093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 2103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return DevicePath; 2113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 2143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiDuplicateDevicePath ( 2153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 2163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 2173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 2183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 2203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Duplicate a device path structure. 2223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 2243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath - The device path to duplicated. 2263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 2283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The duplicated device path. 2303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 2323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; 2343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN Size; 2353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (DevicePath == NULL) { 2373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 2383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 2393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Compute the size 2423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size = EfiDevicePathSize (DevicePath); 2443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Size == 0) { 2453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 2463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 2473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Allocate space for duplicate device path 2503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NewDevicePath = EfiLibAllocateCopyPool (Size, DevicePath); 2523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NewDevicePath; 2543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 2573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiAppendDevicePath ( 2583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Src1, 2593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Src2 2603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 2613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 2623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 2643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Function is used to append a Src1 and Src2 together. 2653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 2673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Src1 - A pointer to a device path data structure. 2683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Src2 - A pointer to a device path data structure. 2703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 2723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang A pointer to the new device path is returned. 2743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NULL is returned if space for the new device path could not be allocated from pool. 2753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed. 2763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 2783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN Size; 2803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN Size1; 2813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN Size2; 2823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; 2833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath; 2843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // If there's only 1 path, just duplicate it 2873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (!Src1) { 2893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (!IsDevicePathUnpacked (Src2)); 2903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return EfiDuplicateDevicePath (Src2); 2913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 2923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (!Src2) { 2943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (!IsDevicePathUnpacked (Src1)); 2953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return EfiDuplicateDevicePath (Src1); 2963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 2973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 2993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Allocate space for the combined device path. It only has one end node of 3003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // length EFI_DEVICE_PATH_PROTOCOL 3013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size1 = EfiDevicePathSize (Src1); 3033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size2 = EfiDevicePathSize (Src2); 3043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL); 3053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NewDevicePath = EfiLibAllocateCopyPool (Size, Src1); 3073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (NewDevicePath != NULL) { 3093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Over write Src1 EndNode and do the copy 3123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL))); 3143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EfiCopyMem (SecondDevicePath, Src2, Size2); 3153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 3163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NewDevicePath; 3183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 3193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 3213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiAppendDevicePathNode ( 3223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Src1, 3233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Node 3243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 3253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 3263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 3283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Function is used to append a device path node to the end of another device path. 3293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 3313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Src1 - A pointer to a device path data structure. 3323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Node - A pointer to a device path data structure. 3343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 3363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function returns a pointer to the new device path. 3373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If there is not enough temporary pool memory available to complete this function, 3383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang then NULL is returned. 3393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 3423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 3433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *Temp; 3443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *NextNode; 3453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; 3463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN NodeLength; 3473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Build a Node that has a terminator on it 3503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NodeLength = DevicePathNodeLength (Node); 3523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Temp = EfiLibAllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), Node); 3543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Temp == NULL) { 3553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 3563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 3573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Add and end device path node to convert Node to device path 3603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NextNode = NextDevicePathNode (Temp); 3623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SetDevicePathEndNode (NextNode); 3633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Append device paths 3663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 3673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NewDevicePath = EfiAppendDevicePath (Src1, Temp); 3683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang gBS->FreePool (Temp); 3693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NewDevicePath; 3703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 3713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 3733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiFileDevicePath ( 3743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_HANDLE Device OPTIONAL, 3753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN CHAR16 *FileName 3763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 3773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 3783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 3803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function allocates a device path for a file and appends it to an existiong 3823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang device path. 3833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 3853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Device - A pointer to a device handle. 3863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FileName - A pointer to a Null-terminated Unicodestring. 3883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 3903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang A device path contain the file name. 3913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 3933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 3943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN Size; 3953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FILEPATH_DEVICE_PATH *FilePath; 3963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *Eop; 3973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *DevicePath; 3983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang for (Size = 0; FileName[Size] != 0; Size++) 4003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ; 4013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Size = (Size + 1) * 2; 4023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FilePath = EfiLibAllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL)); 4043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath = NULL; 4063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (FilePath != NULL) { 4083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Build a file path 4113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FilePath->Header.Type = MEDIA_DEVICE_PATH; 4133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FilePath->Header.SubType = MEDIA_FILEPATH_DP; 4143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); 4153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EfiCopyMem (FilePath->PathName, FileName, Size); 4163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Eop = NextDevicePathNode (&FilePath->Header); 4173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SetDevicePathEndNode (Eop); 4183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Append file path to device's device path 4213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) FilePath; 4243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Device != NULL) { 4253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath = EfiAppendDevicePath ( 4263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EfiDevicePathFromHandle (Device), 4273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePath 4283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 4293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang gBS->FreePool (FilePath); 4313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 4323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 4333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return DevicePath; 4353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 4363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_DEVICE_PATH_PROTOCOL * 4383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiAppendDevicePathInstance ( 4393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Src, 4403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_DEVICE_PATH_PROTOCOL *Instance 4413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 4423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 4433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 4453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Append a device path instance to another. 4473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 4493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Src - The device path instance to be appended with. 4513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Instance - The device path instance appending the other. 4523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 4543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The contaction of these two. 4563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 4583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 4593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT8 *Ptr; 4603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EFI_DEVICE_PATH_PROTOCOL *DevPath; 4613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN SrcSize; 4623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINTN InstanceSize; 4633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Src == NULL) { 4653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return EfiDuplicateDevicePath (Instance); 4663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 4673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SrcSize = EfiDevicePathSize (Src); 4693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang InstanceSize = EfiDevicePathSize (Instance); 4703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Ptr = EfiLibAllocateCopyPool (SrcSize + InstanceSize, Src); 4723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Ptr != NULL) { 4733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; 4753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang while (!IsDevicePathEnd (DevPath)) { 4773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath = NextDevicePathNode (DevPath); 4783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 4793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // Convert the End to an End Instance, since we are 4813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // appending another instacne after this one its a good 4823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // idea. 4833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // 4843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 4853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevPath = NextDevicePathNode (DevPath); 4873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EfiCopyMem (DevPath, Instance, InstanceSize); 4883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 4893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return (EFI_DEVICE_PATH_PROTOCOL *) Ptr; 4913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 4923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 4933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID 4943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 4953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiInitializeFwVolDevicepathNode ( 4963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode, 4973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN EFI_GUID *NameGuid 4983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 4993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 5003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 5023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Initialize a Firmware Volume (FV) Media Device Path node. 5043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 5063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FvDevicePathNode - Pointer to a FV device path node to initialize 5083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NameGuid - FV file name to use in FvDevicePathNode 5093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 5113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang None 5133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 5153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 5163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FvDevicePathNode->Header.Type = MEDIA_DEVICE_PATH; 5173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FvDevicePathNode->Header.SubType = MEDIA_FV_FILEPATH_DP; 5183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)); 5193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang EfiCopyMem (&FvDevicePathNode->NameGuid, NameGuid, sizeof(EFI_GUID)); 5213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 5223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFI_GUID * 5243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 5253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiGetNameGuidFromFwVolDevicePathNode ( 5263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode 5273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 5283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 5293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangRoutine Description: 5313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Check to see if the Firmware Volume (FV) Media Device Path is valid. 5333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangArguments: 5353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang FvDevicePathNode - Pointer to FV device path to check 5373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReturns: 5393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang NULL - FvDevicePathNode is not valid. 5413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Other - FvDevicePathNode is valid and pointer to NameGuid was returned. 5423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 5443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 5453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH && 5463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_FV_FILEPATH_DP) { 5473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return &FvDevicePathNode->NameGuid; 5483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 5493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 5503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 5513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 552