| 956 | } |
| 957 | |
| 958 | UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, const QModelIndex & parent, const UINT8 mode) |
| 959 | { |
| 960 | // Check that there is space for the volume header |
| 961 | if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { |
| 962 | msg(tr("parseVolume: input volume size %1h (%2) is smaller than volume header size 40h (64)").hexarg(volume.size()).arg(volume.size())); |
| 963 | return ERR_INVALID_VOLUME; |
| 964 | } |
| 965 | |
| 966 | // Populate volume header |
| 967 | const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData()); |
| 968 | |
| 969 | // Check sanity of HeaderLength value |
| 970 | if (ALIGN8(volumeHeader->HeaderLength) > volume.size()) { |
| 971 | msg(tr("parseVolume: volume header overlaps the end of data")); |
| 972 | return ERR_INVALID_VOLUME; |
| 973 | } |
| 974 | |
| 975 | // Check sanity of ExtHeaderOffset value |
| 976 | if (volumeHeader->ExtHeaderOffset > 0 |
| 977 | && (UINT32)volume.size() < ALIGN8(volumeHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER))) { |
| 978 | msg(tr("parseVolume: extended volume header overlaps the end of data")); |
| 979 | return ERR_INVALID_VOLUME; |
| 980 | } |
| 981 | |
| 982 | // Calculate volume header size |
| 983 | UINT32 headerSize; |
| 984 | if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { |
| 985 | const EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (const EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset); |
| 986 | headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize; |
| 987 | } |
| 988 | else |
| 989 | headerSize = volumeHeader->HeaderLength; |
| 990 | |
| 991 | // Sanity check after some crazy MSI images |
| 992 | headerSize = ALIGN8(headerSize); |
| 993 | |
| 994 | // Check for FFS v2/v3 volume |
| 995 | UINT8 subtype = Subtypes::UnknownVolume; |
| 996 | if (FFSv2Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))){ |
| 997 | subtype = Subtypes::Ffs2Volume; |
| 998 | } |
| 999 | else if (FFSv3Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))) { |
| 1000 | subtype = Subtypes::Ffs3Volume; |
| 1001 | } |
| 1002 | |
| 1003 | // Check attributes |
| 1004 | // Determine value of empty byte |
| 1005 | char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00'; |
| 1006 | |
| 1007 | // Get volume size |
| 1008 | UINT32 volumeSize; |
| 1009 | UINT32 bmVolumeSize; |
| 1010 | |
| 1011 | UINT8 result = getVolumeSize(volume, 0, volumeSize, bmVolumeSize); |
| 1012 | if (result) |
| 1013 | return result; |
| 1014 | |
| 1015 | // Check for Apple CRC32 in ZeroVector |
nothing calls this directly
no test coverage detected