X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FLibrary%2FUefiDevicePathLib%2FUefiDevicePathLib.c;h=f3e04e03193cec1ec34431ec1d16f06ff2a8e0e4;hb=ebca8169891c61ff3bfe9cc226a65a137e32c1ab;hp=1b1376e2cf29b287310b0d61516118b3e67d1644;hpb=5f10fa0140f7100aa04c12f87d63a66755d20d58;p=mirror_edk2.git diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c index 1b1376e2cf..f3e04e0319 100644 --- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c +++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c @@ -22,11 +22,12 @@ **/ /** - This function returns the size, in bytes, - of the device path data structure specified by DevicePath. - If DevicePath is NULL, then 0 is returned. + Returns the size of a device path in bytes. - @param DevicePath A pointer to a device path data structure. + This function returns the size, in bytes, of the device path data structure specified by + DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned. + + @param DevicePath A pointer to a device path data structure. @return The size of a device path in bytes. @@ -58,18 +59,22 @@ GetDevicePathSize ( } /** - This function allocates space for a new copy of the device path - specified by DevicePath. + Creates a new device path by appending a second device path to a first device path. - @param DevicePath A pointer to a device path data structure. + This function allocates space for a new copy of the device path specified by DevicePath. If + DevicePath is NULL, then NULL is returned. If the memory is successfully allocated, then the + contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer + is returned. Otherwise, NULL is returned. + + @param DevicePath A pointer to a device path data structure. - @return The duplicated device path. + @return A pointer to the duplicated device path. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI DuplicateDevicePath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; @@ -92,24 +97,29 @@ DuplicateDevicePath ( } /** - This function appends the device path SecondDevicePath - to every device path instance in FirstDevicePath. + Creates a new device path by appending a second device path to a first device path. - @param FirstDevicePath A pointer to a device path data structure. - - @param SecondDevicePath A pointer to a device path data structure. + This function creates a new device path by appending a copy of SecondDevicePath to a copy of + FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from + SecondDevicePath is retained. The newly created device path is returned. + If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned. + If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned. + If both FirstDevicePath and SecondDevicePath are NULL, then NULL is returned. + If there is not enough memory for the newly allocated buffer, then NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. It is the + responsibility of the caller to free the memory allocated. - @return A pointer to the new device path is returned. - NULL is returned if space for the new device path could not be allocated from pool. - It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath - if they are no longer needed. + @param FirstDevicePath A pointer to a device path data structure. + @param SecondDevicePath A pointer to a device path data structure. + + @return A pointer to the new device path. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI AppendDevicePath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, - IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath + IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL + IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL ) { UINTN Size; @@ -119,7 +129,7 @@ AppendDevicePath ( EFI_DEVICE_PATH_PROTOCOL *DevicePath2; // - // If there's only 1 path, just duplicate it + // If there's only 1 path, just duplicate it. // if (FirstDevicePath == NULL) { return DuplicateDevicePath (SecondDevicePath); @@ -131,7 +141,7 @@ AppendDevicePath ( // // Allocate space for the combined device path. It only has one end node of - // length EFI_DEVICE_PATH_PROTOCOL + // length EFI_DEVICE_PATH_PROTOCOL. // Size1 = GetDevicePathSize (FirstDevicePath); Size2 = GetDevicePathSize (SecondDevicePath); @@ -142,9 +152,10 @@ AppendDevicePath ( if (NewDevicePath != NULL) { NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1); // - // Over write Src1 EndNode and do the copy + // Over write FirstDevicePath EndNode and do the copy // - DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL))); + DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL))); CopyMem (DevicePath2, SecondDevicePath, Size2); } @@ -152,23 +163,28 @@ AppendDevicePath ( } /** - This function appends the device path node SecondDevicePath - to every device path instance in FirstDevicePath. + Creates a new path by appending the device node to the device path. - @param DevicePath A pointer to a device path data structure. - - @param DevicePathNode A pointer to a single device path node. + This function creates a new device path by appending a copy of the device node specified by + DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer. + The end-of-device-path device node is moved after the end of the appended device node. + If DevicePath is NULL, then NULL is returned. + If DevicePathNode is NULL, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathNode A pointer to a single device path node. @return A pointer to the new device path. - If there is not enough temporary pool memory available to complete this function, - then NULL is returned. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI AppendDevicePathNode ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL ) { EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; @@ -176,6 +192,9 @@ AppendDevicePathNode ( EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; UINTN NodeLength; + if (DevicePath == NULL || DevicePathNode == NULL) { + return NULL; + } // // Build a Node that has a terminator on it // @@ -202,81 +221,103 @@ AppendDevicePathNode ( } /** - This function appends the device path instance Instance to the device path Source. - If Source is NULL, then a new device path with one instance is created. - - @param Source A pointer to a device path data structure. - @param Instance A pointer to a device path instance. + Creates a new device path by appending the specified device path instance to the specified device + path. + + This function creates a new device path by appending a copy of the device path instance specified + by DevicePathInstance to a copy of the device path secified by DevicePath in a allocated buffer. + The end-of-device-path device node is moved after the end of the appended device path instance + and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathInstance A pointer to a device path instance. @return A pointer to the new device path. - If there is not enough temporary pool memory available to complete this function, - then NULL is returned. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI AppendDevicePathInstance ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *Source, - IN CONST EFI_DEVICE_PATH_PROTOCOL *Instance + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL ) { EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; UINTN SrcSize; UINTN InstanceSize; - if (Source == NULL) { - return DuplicateDevicePath (Instance); + if (DevicePath == NULL) { + return DuplicateDevicePath (DevicePathInstance); + } + + if (DevicePathInstance == NULL) { + return NULL; } - SrcSize = GetDevicePathSize (Source); - InstanceSize = GetDevicePathSize (Instance); + SrcSize = GetDevicePathSize (DevicePath); + InstanceSize = GetDevicePathSize (DevicePathInstance); NewDevicePath = AllocatePool (SrcSize + InstanceSize); if (NewDevicePath != NULL) { - DevicePath = CopyMem (NewDevicePath, Source, SrcSize);; + TempDevicePath = CopyMem (NewDevicePath, DevicePath, SrcSize);; - while (!IsDevicePathEnd (DevicePath)) { - DevicePath = NextDevicePathNode (DevicePath); + while (!IsDevicePathEnd (TempDevicePath)) { + TempDevicePath = NextDevicePathNode (TempDevicePath); } - DevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; - - DevicePath = NextDevicePathNode (DevicePath); - CopyMem (DevicePath, Instance, InstanceSize); + TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + TempDevicePath = NextDevicePathNode (TempDevicePath); + CopyMem (TempDevicePath, DevicePathInstance, InstanceSize); } return NewDevicePath; } /** - Function retrieves the next device path instance from a device path data structure. - - @param DevicePath A pointer to a device path data structure. - - @param Size A pointer to the size of a device path instance in bytes. + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + This function creates a copy of the current device path instance. It also updates DevicePath to + point to the next device path instance in the device path (or NULL if no more) and updates Size + to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. + If Size is NULL, then ASSERT(). + + @param DevicePath On input, this holds the pointer to the current device path + instance. On output, this holds the pointer to the next device + path instance or NULL if there are no more device path + instances in the device path pointer to a device path data + structure. + @param Size On output, this holds the size of the device path instance, in + bytes or zero, if DevicePath is NULL. - @return This function returns a pointer to the current device path instance. - In addition, it returns the size in bytes of the current device path instance in Size, - and a pointer to the next device path instance in DevicePath. - If there are no more device path instances in DevicePath, then DevicePath will be set to NULL. + @return A pointer to the current device path instance. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI GetNextDevicePathInstance ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT UINTN *Size + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT UINTN *Size ) { EFI_DEVICE_PATH_PROTOCOL *DevPath; EFI_DEVICE_PATH_PROTOCOL *ReturnValue; UINT8 Temp; - ASSERT (DevicePath != NULL); ASSERT (Size != NULL); - if (*DevicePath == NULL) { + + if (DevicePath == NULL || *DevicePath == NULL) { *Size = 0; return NULL; } @@ -316,12 +357,61 @@ GetNextDevicePathInstance ( } /** - Return TRUE is this is a multi instance device path. + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + This function creates a new device node in a newly allocated buffer of size NodeLength and + initializes the device path node header with NodeType and NodeSubType. The new device path node + is returned. + If NodeLength is smaller than a device path header, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. + + @param NodeType The device node type for the new device node. + @param NodeSubType The device node sub-type for the new device node. + @param NodeLength The length of the new device node. + + @return The new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +EFIAPI +CreateDeviceNode ( + IN UINT8 NodeType, + IN UINT8 NodeSubType, + IN UINT16 NodeLength + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + // + // NodeLength is less than the size of the header. + // + return NULL; + } + + DevicePath = AllocatePool (NodeLength); + if (DevicePath != NULL) { + DevicePath->Type = NodeType; + DevicePath->SubType = NodeSubType; + SetDevicePathNodeLength (DevicePath, NodeLength); + } + + return DevicePath; +} + +/** + Determines if a device path is single or multi-instance. + + This function returns TRUE if the device path specified by DevicePath is multi-instance. + Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned. - @param DevicePath A pointer to a device path data structure. + @param DevicePath A pointer to a device path data structure. - @retval TRUE If DevicePath is multi-instance. - @retval FALSE If DevicePath is not multi-instance or DevicePath is NULL. + @retval TRUE DevicePath is multi-instance. + @retval FALSE DevicePath is not multi-instance or DevicePath is NULL. **/ BOOLEAN @@ -330,7 +420,7 @@ IsDevicePathMultiInstance ( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { - CONST EFI_DEVICE_PATH_PROTOCOL *Node; + CONST EFI_DEVICE_PATH_PROTOCOL *Node; if (DevicePath == NULL) { return FALSE; @@ -348,19 +438,22 @@ IsDevicePathMultiInstance ( return FALSE; } + /** - This function retrieves the device path protocol from a handle. + Retrieves the device path protocol from a handle. - @param Handle The handle from which to retrieve the device path protocol. + This function returns the device path protocol from the handle specified by Handle. If Handle is + NULL or Handle does not contain a device path protocol, then NULL is returned. + + @param Handle The handle from which to retrieve the device path protocol. - @return This function returns the device path protocol from the handle specified by Handle. - If Handle is NULL or Handle does not contain a device path protocol, then NULL is returned. + @return The device path protocol from the handle specified by Handle. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI DevicePathFromHandle ( - IN EFI_HANDLE Handle + IN EFI_HANDLE Handle ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; @@ -378,54 +471,54 @@ DevicePathFromHandle ( } /** - This function allocates a device path for a file and appends it to an existing device path. + Allocates a device path for a file and appends it to an existing device path. - @param Device A pointer to a device handle. This parameter is optional and may be NULL. - @param FileName A pointer to a Null-terminated Unicode string. + If Device is a valid device handle that contains a device path protocol, then a device path for + the file specified by FileName is allocated and appended to the device path associated with the + handle Device. The allocated device path is returned. If Device is NULL or Device is a handle + that does not support the device path protocol, then a device path containing a single device + path node for the file specified by FileName is allocated and returned. + If FileName is NULL, then ASSERT(). - @return If Device is a valid device handle that contains a device path protocol, - then a device path for the file specified by FileName is allocated - and appended to the device path associated with the handle Device. The allocated device path is returned. - If Device is NULL or Device is a handle that does not support the device path protocol, - then a device path containing a single device path node for the file specified by FileName - is allocated and returned. + @param Device A pointer to a device handle. This parameter is optional and + may be NULL. + @param FileName A pointer to a Null-terminated Unicode string. + + @return The allocated device path. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI FileDevicePath ( - IN EFI_HANDLE Device, OPTIONAL - IN CONST CHAR16 *FileName + IN EFI_HANDLE Device, OPTIONAL + IN CONST CHAR16 *FileName ) { - UINTN FileNameSize; - UINTN FilePathNodeSize; - FILEPATH_DEVICE_PATH *FilePathNode; + UINTN Size; + FILEPATH_DEVICE_PATH *FilePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; - DevicePath = NULL; + DevicePath = NULL; + + Size = StrSize (FileName); + FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + EFI_END_DEVICE_PATH_LENGTH); + if (FileDevicePath != NULL) { + FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; + FilePath->Header.Type = MEDIA_DEVICE_PATH; + FilePath->Header.SubType = MEDIA_FILEPATH_DP; + CopyMem (&FilePath->PathName, FileName, Size); + SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); + SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); - FileNameSize = StrSize (FileName); - FilePathNodeSize = FileNameSize + SIZE_OF_FILEPATH_DEVICE_PATH; - FilePathNode = AllocatePool (FilePathNodeSize); - if (FilePathNode != NULL) { - // - // Build a file path node - // - FilePathNode->Header.Type = MEDIA_DEVICE_PATH; - FilePathNode->Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength (&FilePathNode->Header, FilePathNodeSize); - CopyMem (FilePathNode->PathName, FileName, FileNameSize); - - // - // Append file path node to device's device path - // if (Device != NULL) { DevicePath = DevicePathFromHandle (Device); } - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) FilePathNode); - FreePool (FilePathNode); + + DevicePath = AppendDevicePath (DevicePath, FileDevicePath); + FreePool (FileDevicePath); } + return DevicePath; }