Big update 0.20.0

- major refactoring round done
- added replace actions for volumes
- added better Intel signature handling
- added support for unsigned Aptio capsules
- more GUIDs added to known-GUIDs database
- more information about PE and TE sections
- shown information about item full size
- hexadecimal numbers format changed from 0xAB to ABh
- AppleCRC renamed to ZVCRC because it seems not Apple-specific feature
after all
This commit is contained in:
Nikolaj Schlej 2015-01-31 15:00:00 +01:00
parent fb7e1c4c89
commit 831603dbc9
23 changed files with 1229 additions and 1157 deletions

View File

@ -1,6 +1,6 @@
/* EFI11/Tiano Compress Implementation /* EFI11/Tiano Compress Implementation
Copyright (c) 2014, Nikolaj Schlej Copyright (c) 2015, Nikolaj Schlej
Copyright (c) 2006 - 2008, Intel Corporation Copyright (c) 2006 - 2008, Intel Corporation
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -278,7 +278,7 @@ STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NU
// //
// functions // functions
// //
UINT8 EFI_STATUS
EfiCompressLegacy( EfiCompressLegacy(
CONST VOID *SrcBuffer, CONST VOID *SrcBuffer,
UINT32 SrcSize, UINT32 SrcSize,
@ -373,7 +373,7 @@ EFI_INVALID_PARAMETER - Parameter supplied is wrong.
} }
UINT8 EFI_STATUS
TianoCompressLegacy ( TianoCompressLegacy (
CONST VOID *SrcBuffer, CONST VOID *SrcBuffer,
UINT32 SrcSize, UINT32 SrcSize,

View File

@ -1,6 +1,6 @@
/* EfiTianoDecompress.h /* EfiTianoDecompress.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.<BR> Copyright (c) 2015, Nikolaj Schlej. All rights reserved.<BR>
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -40,7 +40,7 @@ extern "C" {
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
EfiTianoGetInfo( EfiTianoGetInfo(
VOID *Source, const VOID *Source,
UINT32 SrcSize, UINT32 SrcSize,
UINT32 *DstSize, UINT32 *DstSize,
UINT32 *ScratchSize UINT32 *ScratchSize
@ -70,7 +70,7 @@ extern "C" {
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
EfiDecompress( EfiDecompress(
VOID *Source, const VOID *Source,
UINT32 SrcSize, UINT32 SrcSize,
VOID *Destination, VOID *Destination,
UINT32 DstSize, UINT32 DstSize,
@ -104,7 +104,7 @@ extern "C" {
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
TianoDecompress( TianoDecompress(
VOID *Source, const VOID *Source,
UINT32 SrcSize, UINT32 SrcSize,
VOID *Destination, VOID *Destination,
UINT32 DstSize, UINT32 DstSize,

View File

@ -52,7 +52,7 @@ int main(int argc, char *argv[])
} }
else { else {
std::cout << "UEFIExtract 0.3.5" << std::endl << std::endl << std::cout << "UEFIExtract 0.4.0" << std::endl << std::endl <<
"Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl << "Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
"Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl; "Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
return 1; return 1;

View File

@ -64,7 +64,7 @@ int main(int argc, char *argv[])
return ERR_SUCCESS; return ERR_SUCCESS;
} }
else { else {
std::cout << "UEFIFind 0.1.1" << std::endl << std::endl << std::cout << "UEFIFind 0.2.0" << std::endl << std::endl <<
"Usage: uefifind {header | body | all} {list | count} pattern imagefile\n"; "Usage: uefifind {header | body | all} {list | count} pattern imagefile\n";
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }

View File

@ -31,7 +31,7 @@ int main(int argc, char *argv[])
result = w.patchFromFile(a.arguments().at(1)); result = w.patchFromFile(a.arguments().at(1));
} }
else { else {
std::cout << "UEFIPatch 0.2.5 - UEFI image file patching utility" << std::endl << std::endl << std::cout << "UEFIPatch 0.3.0 - UEFI image file patching utility" << std::endl << std::endl <<
"Usage: UEFIPatch image_file" << std::endl << std::endl << "Usage: UEFIPatch image_file" << std::endl << std::endl <<
"Patches will be read from patches.txt file\n"; "Patches will be read from patches.txt file\n";
return ERR_SUCCESS; return ERR_SUCCESS;

View File

@ -1,6 +1,6 @@
/* basetypes.h /* basetypes.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -28,6 +28,7 @@ typedef int64_t INT64;
typedef uint64_t UINT64; typedef uint64_t UINT64;
typedef char CHAR8; typedef char CHAR8;
typedef uint16_t CHAR16; typedef uint16_t CHAR16;
typedef unsigned int UINTN;
#define CONST const #define CONST const
#define VOID void #define VOID void
@ -90,12 +91,12 @@ typedef uint16_t CHAR16;
#define IN #define IN
#define OUT #define OUT
#define EFIAPI #define EFIAPI
#define EFI_STATUS UINT8 #define EFI_STATUS UINTN
#define EFI_SUCCESS ERR_SUCCESS #define EFI_SUCCESS ERR_SUCCESS
#define EFI_INVALID_PARAMETER ERR_INVALID_PARAMETER #define EFI_INVALID_PARAMETER ERR_INVALID_PARAMETER
#define EFI_OUT_OF_RESOURCES ERR_OUT_OF_RESOURCES #define EFI_OUT_OF_RESOURCES ERR_OUT_OF_RESOURCES
#define EFI_BUFFER_TOO_SMALL ERR_BUFFER_TOO_SMALL #define EFI_BUFFER_TOO_SMALL ERR_BUFFER_TOO_SMALL
#define EFI_ERROR(X) X #define EFI_ERROR(X) (X)
// Compression algorithms // Compression algorithms
#define COMPRESSION_ALGORITHM_UNKNOWN 0 #define COMPRESSION_ALGORITHM_UNKNOWN 0
@ -138,7 +139,7 @@ typedef uint16_t CHAR16;
#define SEARCH_MODE_ALL 3 #define SEARCH_MODE_ALL 3
// EFI GUID // EFI GUID
typedef struct { typedef struct _EFI_GUID {
UINT8 Data[16]; UINT8 Data[16];
} EFI_GUID; } EFI_GUID;
@ -148,7 +149,9 @@ typedef struct {
#include <assert.h> #include <assert.h>
#define ASSERT(x) assert(x) #define ASSERT(x) assert(x)
//Hexarg macro //Hexarg macros
#define hexarg(X, Y) arg(QString("%1").arg((X),(Y),16,QChar('0')).toUpper()) #define hexarg(X) arg(QString("%1").arg((X),0,16).toUpper())
#define hexarg2(X, Y) arg(QString("%1").arg((X),(Y),16,QChar('0')).toUpper())
#endif #endif

View File

@ -1,6 +1,6 @@
/* descriptor.cpp /* descriptor.cpp
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -15,13 +15,13 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Calculate address of data structure addressed by descriptor address format // Calculate address of data structure addressed by descriptor address format
// 8 bit base or limit // 8 bit base or limit
UINT8* calculateAddress8(UINT8* baseAddress, const UINT8 baseOrLimit) const UINT8* calculateAddress8(const UINT8* baseAddress, const UINT8 baseOrLimit)
{ {
return baseAddress + baseOrLimit * 0x10; return baseAddress + baseOrLimit * 0x10;
} }
// 16 bit base or limit // 16 bit base or limit
UINT8* calculateAddress16(UINT8* baseAddress, const UINT16 baseOrLimit) const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLimit)
{ {
return baseAddress + baseOrLimit * 0x1000; return baseAddress + baseOrLimit * 0x1000;
} }

View File

@ -1,6 +1,6 @@
/* descriptor.h /* descriptor.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -20,7 +20,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#pragma pack(push,1) #pragma pack(push,1)
// Flash descriptor header // Flash descriptor header
typedef struct { typedef struct _FLASH_DESCRIPTOR_HEADER {
UINT8 FfVector[16]; // Must be 16 0xFFs UINT8 FfVector[16]; // Must be 16 0xFFs
UINT32 Signature; // 0x0FF0A55A UINT32 Signature; // 0x0FF0A55A
} FLASH_DESCRIPTOR_HEADER; } FLASH_DESCRIPTOR_HEADER;
@ -33,7 +33,7 @@ typedef struct {
// Descriptor map // Descriptor map
// Base fields are storing bits [11:4] of actual base addresses, all other bits are 0 // Base fields are storing bits [11:4] of actual base addresses, all other bits are 0
typedef struct { typedef struct _FLASH_DESCRIPTOR_MAP {
UINT8 ComponentBase; // 0x03 on most machines UINT8 ComponentBase; // 0x03 on most machines
UINT8 NumberOfFlashChips; // Zero-based number of flash chips installed on board UINT8 NumberOfFlashChips; // Zero-based number of flash chips installed on board
UINT8 RegionBase; // 0x04 on most machines UINT8 RegionBase; // 0x04 on most machines
@ -53,7 +53,7 @@ typedef struct {
// Component section // Component section
// Flash parameters DWORD structure // Flash parameters DWORD structure
typedef struct { typedef struct _FLASH_PARAMETERS {
UINT8 FirstChipDensity : 3; UINT8 FirstChipDensity : 3;
UINT8 SecondChipDensity : 3; UINT8 SecondChipDensity : 3;
UINT8 ReservedZero0 : 2; // Still unknown, zeros in all descriptors I have seen UINT8 ReservedZero0 : 2; // Still unknown, zeros in all descriptors I have seen
@ -81,7 +81,7 @@ typedef struct {
#define FLASH_FREQUENCY_50MHZ 0x04 #define FLASH_FREQUENCY_50MHZ 0x04
// Component section structure // Component section structure
typedef struct { typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION {
FLASH_PARAMETERS FlashParameters; FLASH_PARAMETERS FlashParameters;
UINT8 InvalidInstruction0; // Instructions for SPI chip, that must not be executed, like FLASH ERASE UINT8 InvalidInstruction0; // Instructions for SPI chip, that must not be executed, like FLASH ERASE
UINT8 InvalidInstruction1; // UINT8 InvalidInstruction1; //
@ -94,7 +94,7 @@ typedef struct {
// Region section // Region section
// All base and limit register are storing upper part of actual UINT32 base and limit // All base and limit register are storing upper part of actual UINT32 base and limit
// If limit is zero - region is not present // If limit is zero - region is not present
typedef struct { typedef struct _FLASH_DESCRIPTOR_REGION_SECTION {
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
UINT16 FlashBlockEraseSize; // Size of block erased by single BLOCK ERASE command UINT16 FlashBlockEraseSize; // Size of block erased by single BLOCK ERASE command
UINT16 BiosBase; UINT16 BiosBase;
@ -113,7 +113,7 @@ typedef struct {
#define FLASH_BLOCK_ERASE_SIZE_64KB 0x000F #define FLASH_BLOCK_ERASE_SIZE_64KB 0x000F
// Master section // Master section
typedef struct { typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION {
UINT16 BiosId; UINT16 BiosId;
UINT8 BiosRead; UINT8 BiosRead;
UINT8 BiosWrite; UINT8 BiosWrite;
@ -138,14 +138,14 @@ typedef struct {
#define FLASH_DESCRIPTOR_UPPER_MAP_BASE 0x0EFC #define FLASH_DESCRIPTOR_UPPER_MAP_BASE 0x0EFC
// Descriptor upper map structure // Descriptor upper map structure
typedef struct { typedef struct _FLASH_DESCRIPTOR_UPPER_MAP {
UINT8 VsccTableBase; // Base address of VSCC Table for ME, bits [11:4] UINT8 VsccTableBase; // Base address of VSCC Table for ME, bits [11:4]
UINT8 VsccTableSize; // Counted in UINT32s UINT8 VsccTableSize; // Counted in UINT32s
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
} FLASH_DESCRIPTOR_UPPER_MAP; } FLASH_DESCRIPTOR_UPPER_MAP;
// VSCC table entry structure // VSCC table entry structure
typedef struct { typedef struct _VSCC_TABLE_ENTRY {
UINT8 VendorId; // JEDEC VendorID byte UINT8 VendorId; // JEDEC VendorID byte
UINT8 DeviceId0; // JEDEC DeviceID first byte UINT8 DeviceId0; // JEDEC DeviceID first byte
UINT8 DeviceId1; // JEDEC DeviceID second byte UINT8 DeviceId1; // JEDEC DeviceID second byte
@ -162,9 +162,9 @@ typedef struct {
// Calculate address of data structure addressed by descriptor address format // Calculate address of data structure addressed by descriptor address format
// 8 bit base or limit // 8 bit base or limit
extern UINT8* calculateAddress8(UINT8* baseAddress, const UINT8 baseOrLimit); extern const UINT8* calculateAddress8(const UINT8* baseAddress, const UINT8 baseOrLimit);
// 16 bit base or limit // 16 bit base or limit
extern UINT8* calculateAddress16(UINT8* baseAddress, const UINT16 baseOrLimit); extern const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLimit);
// Calculate offset of region using it's base // Calculate offset of region using it's base
extern UINT32 calculateRegionOffset(const UINT16 base); extern UINT32 calculateRegionOffset(const UINT16 base);

184
ffs.cpp
View File

@ -1,6 +1,6 @@
/* ffs.cpp /* ffs.cpp
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -16,7 +16,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
const UINT8 ffsAlignmentTable[] = const UINT8 ffsAlignmentTable[] =
{ 0, 4, 7, 9, 10, 12, 15, 16 }; { 0, 4, 7, 9, 10, 12, 15, 16 };
UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize) UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
{ {
if (!buffer) if (!buffer)
return 0; return 0;
@ -29,7 +29,7 @@ UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize)
return (UINT8)0x100 - counter; return (UINT8)0x100 - counter;
} }
UINT16 calculateChecksum16(UINT16* buffer, UINT32 bufferSize) UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize)
{ {
if (!buffer) if (!buffer)
return 0; return 0;
@ -53,7 +53,7 @@ VOID uint32ToUint24(UINT32 size, UINT8* ffsSize)
ffsSize[0] = (UINT8)((size)); ffsSize[0] = (UINT8)((size));
} }
UINT32 uint24ToUint32(UINT8* ffsSize) UINT32 uint24ToUint32(const UINT8* ffsSize)
{ {
return (ffsSize[2] << 16) + return (ffsSize[2] << 16) +
(ffsSize[1] << 8) + (ffsSize[1] << 8) +
@ -63,17 +63,17 @@ UINT32 uint24ToUint32(UINT8* ffsSize)
QString guidToQString(const EFI_GUID& guid) QString guidToQString(const EFI_GUID& guid)
{ {
QByteArray baGuid = QByteArray::fromRawData((const char*)guid.Data, sizeof(EFI_GUID)); QByteArray baGuid = QByteArray::fromRawData((const char*)guid.Data, sizeof(EFI_GUID));
UINT32 i32 = *(UINT32*)baGuid.left(4).constData(); const UINT32 i32 = *(const UINT32*)baGuid.left(4).constData();
UINT16 i16_0 = *(UINT16*)baGuid.mid(4, 2).constData(); const UINT16 i16_0 = *(const UINT16*)baGuid.mid(4, 2).constData();
UINT16 i16_1 = *(UINT16*)baGuid.mid(6, 2).constData(); const UINT16 i16_1 = *(const UINT16*)baGuid.mid(6, 2).constData();
UINT8 i8_0 = *(UINT8*)baGuid.mid(8, 1).constData(); const UINT8 i8_0 = *(const UINT8*)baGuid.mid(8, 1).constData();
UINT8 i8_1 = *(UINT8*)baGuid.mid(9, 1).constData(); const UINT8 i8_1 = *(const UINT8*)baGuid.mid(9, 1).constData();
UINT8 i8_2 = *(UINT8*)baGuid.mid(10, 1).constData(); const UINT8 i8_2 = *(const UINT8*)baGuid.mid(10, 1).constData();
UINT8 i8_3 = *(UINT8*)baGuid.mid(11, 1).constData(); const UINT8 i8_3 = *(const UINT8*)baGuid.mid(11, 1).constData();
UINT8 i8_4 = *(UINT8*)baGuid.mid(12, 1).constData(); const UINT8 i8_4 = *(const UINT8*)baGuid.mid(12, 1).constData();
UINT8 i8_5 = *(UINT8*)baGuid.mid(13, 1).constData(); const UINT8 i8_5 = *(const UINT8*)baGuid.mid(13, 1).constData();
UINT8 i8_6 = *(UINT8*)baGuid.mid(14, 1).constData(); const UINT8 i8_6 = *(const UINT8*)baGuid.mid(14, 1).constData();
UINT8 i8_7 = *(UINT8*)baGuid.mid(15, 1).constData(); const UINT8 i8_7 = *(const UINT8*)baGuid.mid(15, 1).constData();
return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11") return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11")
.arg(i32, 8, 16, QChar('0')) .arg(i32, 8, 16, QChar('0'))
@ -93,36 +93,21 @@ QString fileTypeToQString(const UINT8 type)
{ {
switch (type) switch (type)
{ {
case EFI_FV_FILETYPE_RAW: case EFI_FV_FILETYPE_RAW: return QObject::tr("Raw");
return QObject::tr("Raw"); case EFI_FV_FILETYPE_FREEFORM: return QObject::tr("Freeform");
case EFI_FV_FILETYPE_FREEFORM: case EFI_FV_FILETYPE_SECURITY_CORE: return QObject::tr("SEC core");
return QObject::tr("Freeform"); case EFI_FV_FILETYPE_PEI_CORE: return QObject::tr("PEI core");
case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_DXE_CORE: return QObject::tr("DXE core");
return QObject::tr("Security core"); case EFI_FV_FILETYPE_PEIM: return QObject::tr("PEI module");
case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_DRIVER: return QObject::tr("DXE driver");
return QObject::tr("PEI core"); case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return QObject::tr("Combined PEI/DXE");
case EFI_FV_FILETYPE_DXE_CORE: case EFI_FV_FILETYPE_APPLICATION: return QObject::tr("Application");
return QObject::tr("DXE core"); case EFI_FV_FILETYPE_SMM: return QObject::tr("SMM module");
case EFI_FV_FILETYPE_PEIM: case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return QObject::tr("Volume image");
return QObject::tr("PEI module"); case EFI_FV_FILETYPE_COMBINED_SMM_DXE: return QObject::tr("Combined SMM/DXE");
case EFI_FV_FILETYPE_DRIVER: case EFI_FV_FILETYPE_SMM_CORE: return QObject::tr("SMM core");
return QObject::tr("DXE driver"); case EFI_FV_FILETYPE_PAD: return QObject::tr("Pad");
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: default: return QObject::tr("Unknown");
return QObject::tr("Combined PEI/DXE");
case EFI_FV_FILETYPE_APPLICATION:
return QObject::tr("Application");
case EFI_FV_FILETYPE_SMM:
return QObject::tr("SMM module");
case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
return QObject::tr("Volume image");
case EFI_FV_FILETYPE_COMBINED_SMM_DXE:
return QObject::tr("Combined SMM/DXE");
case EFI_FV_FILETYPE_SMM_CORE:
return QObject::tr("SMM core");
case EFI_FV_FILETYPE_PAD:
return QObject::tr("Pad");
default:
return QObject::tr("Unknown");
}; };
} }
@ -130,88 +115,53 @@ QString sectionTypeToQString(const UINT8 type)
{ {
switch (type) switch (type)
{ {
case EFI_SECTION_COMPRESSION: case EFI_SECTION_COMPRESSION: return QObject::tr("Compressed");
return QObject::tr("Compressed"); case EFI_SECTION_GUID_DEFINED: return QObject::tr("GUID defined");
case EFI_SECTION_GUID_DEFINED: case EFI_SECTION_DISPOSABLE: return QObject::tr("Disposable");
return QObject::tr("GUID defined"); case EFI_SECTION_PE32: return QObject::tr("PE32(+) image");
case EFI_SECTION_DISPOSABLE: case EFI_SECTION_PIC: return QObject::tr("PIC image");
return QObject::tr("Disposable"); case EFI_SECTION_TE: return QObject::tr("TE image");
case EFI_SECTION_PE32: case EFI_SECTION_DXE_DEPEX: return QObject::tr("DXE dependency");
return QObject::tr("PE32+ image"); case EFI_SECTION_VERSION: return QObject::tr("Version");
case EFI_SECTION_PIC: case EFI_SECTION_USER_INTERFACE: return QObject::tr("User interface");
return QObject::tr("PIC image"); case EFI_SECTION_COMPATIBILITY16: return QObject::tr("16-bit image");
case EFI_SECTION_TE: case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return QObject::tr("Volume image");
return QObject::tr("TE image"); case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return QObject::tr("Freeform subtype GUID");
case EFI_SECTION_DXE_DEPEX: case EFI_SECTION_RAW: return QObject::tr("Raw");
return QObject::tr("DXE dependency"); case EFI_SECTION_PEI_DEPEX: return QObject::tr("PEI dependency");
case EFI_SECTION_VERSION: case EFI_SECTION_SMM_DEPEX: return QObject::tr("SMM dependency");
return QObject::tr("Version"); case HP_SECTION_POSTCODE: return QObject::tr("HP postcode");
case EFI_SECTION_USER_INTERFACE: case SCT_SECTION_POSTCODE: return QObject::tr("SCT postcode");
return QObject::tr("User interface"); default: return QObject::tr("Unknown");
case EFI_SECTION_COMPATIBILITY16:
return QObject::tr("16-bit image");
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
return QObject::tr("Volume image");
case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
return QObject::tr("Freeform subtype GUID");
case EFI_SECTION_RAW:
return QObject::tr("Raw");
case EFI_SECTION_PEI_DEPEX:
return QObject::tr("PEI dependency");
case EFI_SECTION_SMM_DEPEX:
return QObject::tr("SMM dependency");
case HP_SECTION_POSTCODE:
return QObject::tr("HP postcode");
case SCT_SECTION_POSTCODE:
return QObject::tr("SCT postcode");
default:
return QObject::tr("Unknown");
} }
} }
UINT32 sizeOfSectionHeader(EFI_COMMON_SECTION_HEADER* header) UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header)
{ {
if (!header) if (!header)
return 0; return 0;
switch (header->Type) switch (header->Type)
{ {
case EFI_SECTION_COMPRESSION:
return sizeof(EFI_COMPRESSION_SECTION);
case EFI_SECTION_GUID_DEFINED: { case EFI_SECTION_GUID_DEFINED: {
EFI_GUID_DEFINED_SECTION* gdsHeader = (EFI_GUID_DEFINED_SECTION*)header; const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
return gdsHeader->DataOffset; } return gdsHeader->DataOffset; }
case EFI_SECTION_DISPOSABLE: case EFI_SECTION_COMPRESSION: return sizeof(EFI_COMPRESSION_SECTION);
return sizeof(EFI_DISPOSABLE_SECTION); case EFI_SECTION_DISPOSABLE: return sizeof(EFI_DISPOSABLE_SECTION);
case EFI_SECTION_PE32: case EFI_SECTION_PE32: return sizeof(EFI_PE32_SECTION);
return sizeof(EFI_PE32_SECTION); case EFI_SECTION_PIC: return sizeof(EFI_PIC_SECTION);
case EFI_SECTION_PIC: case EFI_SECTION_TE: return sizeof(EFI_TE_SECTION);
return sizeof(EFI_PIC_SECTION); case EFI_SECTION_DXE_DEPEX: return sizeof(EFI_DXE_DEPEX_SECTION);
case EFI_SECTION_TE: case EFI_SECTION_VERSION: return sizeof(EFI_VERSION_SECTION);
return sizeof(EFI_TE_SECTION); case EFI_SECTION_USER_INTERFACE: return sizeof(EFI_USER_INTERFACE_SECTION);
case EFI_SECTION_DXE_DEPEX: case EFI_SECTION_COMPATIBILITY16: return sizeof(EFI_COMPATIBILITY16_SECTION);
return sizeof(EFI_DXE_DEPEX_SECTION); case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
case EFI_SECTION_VERSION: case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
return sizeof(EFI_VERSION_SECTION); case EFI_SECTION_RAW: return sizeof(EFI_RAW_SECTION);
case EFI_SECTION_USER_INTERFACE: case EFI_SECTION_PEI_DEPEX: return sizeof(EFI_PEI_DEPEX_SECTION);
return sizeof(EFI_USER_INTERFACE_SECTION); case EFI_SECTION_SMM_DEPEX: return sizeof(EFI_SMM_DEPEX_SECTION);
case EFI_SECTION_COMPATIBILITY16: case HP_SECTION_POSTCODE: return sizeof(POSTCODE_SECTION);
return sizeof(EFI_COMPATIBILITY16_SECTION); case SCT_SECTION_POSTCODE: return sizeof(POSTCODE_SECTION);
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: default: return sizeof(EFI_COMMON_SECTION_HEADER);
return sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
return sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
case EFI_SECTION_RAW:
return sizeof(EFI_RAW_SECTION);
case EFI_SECTION_PEI_DEPEX:
return sizeof(EFI_PEI_DEPEX_SECTION);
case EFI_SECTION_SMM_DEPEX:
return sizeof(EFI_SMM_DEPEX_SECTION);
case HP_SECTION_POSTCODE:
return sizeof(POSTCODE_SECTION);
case SCT_SECTION_POSTCODE:
return sizeof(POSTCODE_SECTION);
default:
return sizeof(EFI_COMMON_SECTION_HEADER);
} }
} }

118
ffs.h
View File

@ -1,6 +1,6 @@
/* ffs.h /* ffs.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -15,6 +15,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
#include <QVector>
#include "basetypes.h" #include "basetypes.h"
// C++ functions // C++ functions
@ -25,9 +26,6 @@ extern QString fileTypeToQString(const UINT8 type);
// Section type to QString routine // Section type to QString routine
extern QString sectionTypeToQString(const UINT8 type); extern QString sectionTypeToQString(const UINT8 type);
#ifdef __cplusplus
extern "C" {
#endif
// Make sure we use right packing rules // Make sure we use right packing rules
#pragma pack(push,1) #pragma pack(push,1)
@ -35,7 +33,7 @@ extern "C" {
// EFI Capsule // EFI Capsule
//***************************************************************************** //*****************************************************************************
// Capsule header // Capsule header
typedef struct { typedef struct _EFI_CAPSULE_HEADER {
EFI_GUID CapsuleGuid; EFI_GUID CapsuleGuid;
UINT32 HeaderSize; UINT32 HeaderSize;
UINT32 Flags; UINT32 Flags;
@ -52,7 +50,7 @@ const QByteArray EFI_CAPSULE_GUID
("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16); ("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16);
// AMI Aptio extended capsule header // AMI Aptio extended capsule header
typedef struct { typedef struct _APTIO_CAPSULE_HEADER {
EFI_CAPSULE_HEADER CapsuleHeader; EFI_CAPSULE_HEADER CapsuleHeader;
UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of
// the capsule volume // the capsule volume
@ -63,22 +61,28 @@ typedef struct {
//ROM_AREA RomAreaMap[1]; //ROM_AREA RomAreaMap[1];
} APTIO_CAPSULE_HEADER; } APTIO_CAPSULE_HEADER;
// AMI Aptio extended capsule GUID // AMI Aptio signed extended capsule GUID
const QByteArray APTIO_CAPSULE_GUID const QByteArray APTIO_SIGNED_CAPSULE_GUID
("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16); ("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16);
// AMI Aptio unsigned extended capsule GUID
const QByteArray APTIO_UNSIGNED_CAPSULE_GUID
("\x90\xBB\xEE\x14\x0A\x89\xDB\x43\xAE\xD1\x5D\x3C\x45\x88\xA4\x18", 16);
//14EEBB90-890A-43DB-AED1-5D3C4588A418
//***************************************************************************** //*****************************************************************************
// EFI Firmware Volume // EFI Firmware Volume
//***************************************************************************** //*****************************************************************************
// Firmware block map entry // Firmware block map entry
// FvBlockMap ends with an entry {0x00000000, 0x00000000} // FvBlockMap ends with an entry {0x00000000, 0x00000000}
typedef struct { typedef struct _EFI_FV_BLOCK_MAP_ENTRY {
UINT32 NumBlocks; UINT32 NumBlocks;
UINT32 Length; UINT32 Length;
} EFI_FV_BLOCK_MAP_ENTRY; } EFI_FV_BLOCK_MAP_ENTRY;
// Volume header // Volume header
typedef struct { typedef struct _EFI_FIRMWARE_VOLUME_HEADER {
UINT8 ZeroVector[16]; UINT8 ZeroVector[16];
EFI_GUID FileSystemGuid; EFI_GUID FileSystemGuid;
UINT64 FvLength; UINT64 FvLength;
@ -92,15 +96,38 @@ typedef struct {
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1]; //EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1];
} EFI_FIRMWARE_VOLUME_HEADER; } EFI_FIRMWARE_VOLUME_HEADER;
// File system GUIDs // Standard file system GUIDs
const QByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID const QByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID
("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16); ("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16);
const QByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16);
// Vendor-specific file system GUIDs
const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16); ("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16); ("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
const QByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID const QByteArray EFI_INTEL_FILE_SYSTEM_GUID
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16); ("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
//AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 //Intel 1
const QByteArray EFI_INTEL_FILE_SYSTEM2_GUID
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
//D6A1CD70-4B33-4994-A6EA-375F2CCC5437 //Intel 2
const QByteArray EFI_SONY_FILE_SYSTEM_GUID
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
//4F494156-AED6-4D64-A537-B8A5557BCEEC //Sony 1
//Vector of volume GUIDs with FFSv2-compatible files
const QVector<QByteArray> FFSv2Volumes
({
EFI_FIRMWARE_FILE_SYSTEM_GUID,
EFI_FIRMWARE_FILE_SYSTEM2_GUID,
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID,
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID,
EFI_INTEL_FILE_SYSTEM_GUID,
EFI_INTEL_FILE_SYSTEM2_GUID,
EFI_SONY_FILE_SYSTEM_GUID
});
// Firmware volume signature // Firmware volume signature
const QByteArray EFI_FV_SIGNATURE("_FVH", 4); const QByteArray EFI_FV_SIGNATURE("_FVH", 4);
@ -188,7 +215,7 @@ const QByteArray EFI_FV_SIGNATURE("_FVH", 4);
#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000 #define EFI_FVB2_WEAK_ALIGNMENT 0x80000000
// Extended firmware volume header // Extended firmware volume header
typedef struct { typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER {
EFI_GUID FvName; EFI_GUID FvName;
UINT32 ExtHeaderSize; UINT32 ExtHeaderSize;
} EFI_FIRMWARE_VOLUME_EXT_HEADER; } EFI_FIRMWARE_VOLUME_EXT_HEADER;
@ -197,31 +224,31 @@ typedef struct {
// The extended header entries follow each other and are // The extended header entries follow each other and are
// terminated by ExtHeaderType EFI_FV_EXT_TYPE_END // terminated by ExtHeaderType EFI_FV_EXT_TYPE_END
#define EFI_FV_EXT_TYPE_END 0x00 #define EFI_FV_EXT_TYPE_END 0x00
typedef struct { typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY {
UINT16 ExtEntrySize; UINT16 ExtEntrySize;
UINT16 ExtEntryType; UINT16 ExtEntryType;
} EFI_FIRMWARE_VOLUME_EXT_ENTRY; } EFI_FIRMWARE_VOLUME_EXT_ENTRY;
// GUID that maps OEM file types to GUIDs // GUID that maps OEM file types to GUIDs
#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01 #define EFI_FV_EXT_TYPE_OEM_TYPE 0x01
typedef struct { typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE {
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header; EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
UINT32 TypeMask; UINT32 TypeMask;
//EFI_GUID Types[1]; //EFI_GUID Types[1];
} EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE; } EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE;
#define EFI_FV_EXT_TYPE_GUID_TYPE 0x02 #define EFI_FV_EXT_TYPE_GUID_TYPE 0x02
typedef struct { typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE {
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header; EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
EFI_GUID FormatType; EFI_GUID FormatType;
//UINT8 Data[]; //UINT8 Data[];
} EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE; } EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE;
// NVRAM volume signature //!TODO: add proper NVRAM parsing
const QByteArray EFI_FIRMWARE_VOLUME_NVRAM_SIGNATURE("$VSS", 4); //const QByteArray EFI_FIRMWARE_VOLUME_NVRAM_SIGNATURE("$VSS", 4);
// Volume header 16bit checksum calculation routine // Volume header 16bit checksum calculation routine
extern UINT16 calculateChecksum16(UINT16* buffer, UINT32 bufferSize); extern UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize);
//***************************************************************************** //*****************************************************************************
// EFI FFS File // EFI FFS File
@ -236,7 +263,7 @@ typedef union {
UINT16 Checksum16; // Revision 2 UINT16 Checksum16; // Revision 2
} EFI_FFS_INTEGRITY_CHECK; } EFI_FFS_INTEGRITY_CHECK;
// File header // File header
typedef struct { typedef struct _EFI_FFS_FILE_HEADER {
EFI_GUID Name; EFI_GUID Name;
EFI_FFS_INTEGRITY_CHECK IntegrityCheck; EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
UINT8 Type; UINT8 Type;
@ -246,15 +273,15 @@ typedef struct {
} EFI_FFS_FILE_HEADER; } EFI_FFS_FILE_HEADER;
// Large file header // Large file header
//typedef struct { typedef struct _EFI_FFS_FILE_HEADER2 {
// EFI_GUID Name; EFI_GUID Name;
// EFI_FFS_INTEGRITY_CHECK IntegrityCheck; EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
// UINT8 Type; UINT8 Type;
// UINT8 Attributes; UINT8 Attributes;
// UINT8 Size[3]; UINT8 Size[3];
// UINT8 State; UINT8 State;
// UINT32 ExtendedSize; UINT32 ExtendedSize;
//} EFI_FFS_FILE_HEADER2; } EFI_FFS_FILE_HEADER2;
// Standard data checksum, used if FFS_ATTRIB_CHECKSUM is clear // Standard data checksum, used if FFS_ATTRIB_CHECKSUM is clear
#define FFS_FIXED_CHECKSUM 0x5A #define FFS_FIXED_CHECKSUM 0x5A
@ -319,25 +346,25 @@ const QByteArray EFI_FFS_PAD_FILE_GUID
// FFS size conversion routines // FFS size conversion routines
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize); extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
extern UINT32 uint24ToUint32(UINT8* ffsSize); extern UINT32 uint24ToUint32(const UINT8* ffsSize);
// FFS file 8bit checksum calculation routine // FFS file 8bit checksum calculation routine
extern UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize); extern UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize);
//***************************************************************************** //*****************************************************************************
// EFI FFS File Section // EFI FFS File Section
//***************************************************************************** //*****************************************************************************
// Common section header // Common section header
typedef struct { typedef struct _EFI_COMMON_SECTION_HEADER {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
} EFI_COMMON_SECTION_HEADER; } EFI_COMMON_SECTION_HEADER;
// Large file common section header // Large file common section header
//typedef struct { typedef struct _EFI_COMMON_SECTION_HEADER2 {
// UINT8 Size[3]; //Must be 0xFFFFFF for this header to be used UINT8 Size[3]; //Must be 0xFFFFFF for this header to be used
// UINT8 Type; UINT8 Type;
// UINT32 ExtendedSize; UINT32 ExtendedSize;
//} EFI_COMMON_SECTION_HEADER2; } EFI_COMMON_SECTION_HEADER2;
// File section types // File section types
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS #define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
@ -364,7 +391,7 @@ typedef struct {
#define HP_SECTION_POSTCODE 0x20 // Specific to HP images #define HP_SECTION_POSTCODE 0x20 // Specific to HP images
// Compression section // Compression section
typedef struct { typedef struct _EFI_COMPRESSION_SECTION {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
UINT32 UncompressedLength; UINT32 UncompressedLength;
@ -377,7 +404,7 @@ typedef struct {
#define EFI_CUSTOMIZED_COMPRESSION 0x02 #define EFI_CUSTOMIZED_COMPRESSION 0x02
//GUID defined section //GUID defined section
typedef struct { typedef struct _EFI_GUID_DEFINED_SECTION {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
EFI_GUID SectionDefinitionGuid; EFI_GUID SectionDefinitionGuid;
@ -403,21 +430,21 @@ const QByteArray EFI_GUIDED_SECTION_INTEL_SIGNED //0F9D89E8-9259-4F76-A5AF-0C89E
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16); ("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
// Version section // Version section
typedef struct { typedef struct _EFI_VERSION_SECTION {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
UINT16 BuildNumber; UINT16 BuildNumber;
} EFI_VERSION_SECTION; } EFI_VERSION_SECTION;
// Freeform subtype GUID section // Freeform subtype GUID section
typedef struct { typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
EFI_GUID SubTypeGuid; EFI_GUID SubTypeGuid;
} EFI_FREEFORM_SUBTYPE_GUID_SECTION; } EFI_FREEFORM_SUBTYPE_GUID_SECTION;
// Phoenix SCT and HP postcode section // Phoenix SCT and HP postcode section
typedef struct { typedef struct _POSTCODE_SECTION {
UINT8 Size[3]; UINT8 Size[3];
UINT8 Type; UINT8 Type;
UINT32 Postcode; UINT32 Postcode;
@ -437,7 +464,7 @@ typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION; typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
//Section routines //Section routines
extern UINT32 sizeOfSectionHeader(EFI_COMMON_SECTION_HEADER* header); extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
//***************************************************************************** //*****************************************************************************
// EFI Dependency Expression // EFI Dependency Expression
@ -475,7 +502,4 @@ extern UINT32 sizeOfSectionHeader(EFI_COMMON_SECTION_HEADER* header);
// Restore previous packing rules // Restore previous packing rules
#pragma pack(pop) #pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* ffsengine.h /* ffsengine.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -110,7 +110,7 @@ private:
UINT32 newPeiCoreEntryPoint; UINT32 newPeiCoreEntryPoint;
// Parsing helpers // Parsing helpers
UINT8 getPaddingType(const QByteArray & padding); UINT32 getPaddingType(const QByteArray & padding);
void parseAprioriRawSection(const QByteArray & body, QString & parsed); void parseAprioriRawSection(const QByteArray & body, QString & parsed);
UINT8 parseDepexSection(const QByteArray & body, QString & parsed); UINT8 parseDepexSection(const QByteArray & body, QString & parsed);
UINT8 findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); UINT8 findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);

8
gbe.h
View File

@ -1,6 +1,6 @@
/* gbe.h /* gbe.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -18,14 +18,14 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Make sure we use right packing rules // Make sure we use right packing rules
#pragma pack(push,1) #pragma pack(push,1)
typedef struct { typedef struct _GBE_MAC_ADDRESS {
UINT8 vendor[3]; UINT8 vendor[3];
UINT8 device[3]; UINT8 device[3];
} GBE_MAC; } GBE_MAC_ADDRESS;
#define GBE_VERSION_OFFSET 10 #define GBE_VERSION_OFFSET 10
typedef struct { typedef struct _GBE_VERSION {
UINT8 id : 4; UINT8 id : 4;
UINT8 minor : 4; UINT8 minor : 4;
UINT8 major; UINT8 major;

4
me.h
View File

@ -1,6 +1,6 @@
/* me.h /* me.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -21,7 +21,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
const QByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2 const QByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
typedef struct { typedef struct _ME_VERSION {
UINT32 signature; UINT32 signature;
UINT32 reserved; // Unknown for me UINT32 reserved; // Unknown for me
UINT16 major; UINT16 major;

View File

@ -1,6 +1,6 @@
/* peimage.h /* peimage.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved. Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
@ -224,6 +224,12 @@ typedef struct {
EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
} EFI_IMAGE_OPTIONAL_HEADER64; } EFI_IMAGE_OPTIONAL_HEADER64;
// Union for pointers to either PE32 or PE32+ headers
typedef union _EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION {
const EFI_IMAGE_OPTIONAL_HEADER32* H32;
const EFI_IMAGE_OPTIONAL_HEADER64* H64;
} EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION;
typedef struct typedef struct
{ {
UINT32 Signature; UINT32 Signature;

View File

@ -1,6 +1,6 @@
/* treeitem.cpp /* treeitem.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -15,25 +15,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h" #include "treeitem.h"
#include "types.h" #include "types.h"
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, const UINT8 compression, TreeItem::TreeItem(const UINT8 type, const UINT32 attributes, const UINT8 compression,
const QString & name, const QString & text, const QString & info, const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & tail, const QByteArray & header, const QByteArray & body,
TreeItem *parent) TreeItem *parent) :
itemAction(Actions::NoAction),
itemType(type),
itemAttributes(attributes),
itemCompression(compression),
itemName(name),
itemText(text),
itemInfo(info),
itemHeader(header),
itemBody(body),
parentItem(parent)
{ {
itemAction = Actions::NoAction;
itemType = type;
itemSubtype = subtype;
itemCompression = compression;
itemName = name;
itemText = text;
itemInfo = info;
itemHeader = header;
itemBody = body;
itemTail = tail;
parentItem = parent;
// Set default names
setDefaultNames();
} }
TreeItem::~TreeItem() TreeItem::~TreeItem()
@ -41,11 +37,11 @@ TreeItem::~TreeItem()
qDeleteAll(childItems); qDeleteAll(childItems);
} }
void TreeItem::setDefaultNames() /*void TreeItem::setDefaultNames()
{ {
itemTypeName = itemTypeToQString(itemType); itemTypeName = itemTypeToQString(itemType);
itemSubtypeName = itemSubtypeToQString(itemType, itemSubtype); itemSubtypeName = itemSubtypeToQString(itemType, itemSubtype);
} }*/
void TreeItem::appendChild(TreeItem *item) void TreeItem::appendChild(TreeItem *item)
{ {
@ -94,15 +90,15 @@ QVariant TreeItem::data(int column) const
{ {
switch (column) switch (column)
{ {
case 0: //Name case 0: // Name
return itemName; return itemName;
case 1: //Action case 1: // Action
return actionTypeToQString(itemAction); return actionTypeToQString(itemAction);
case 2: //Type case 2: // Type
return itemTypeName; return itemTypeToQString(itemType);
case 3: //Subtype case 3: // Attributes
return itemSubtypeName; return itemAttributesToQString(itemType, itemAttributes);
case 4: //Text case 4: // Text
return itemText; return itemText;
default: default:
return QVariant(); return QVariant();
@ -114,9 +110,19 @@ TreeItem *TreeItem::parent()
return parentItem; return parentItem;
} }
void TreeItem::setName(const QString &text) QString TreeItem::name() const
{ {
itemName = text; return itemName;
}
void TreeItem::setName(const QString &name)
{
itemName = name;
}
QString TreeItem::text() const
{
return itemText;
} }
void TreeItem::setText(const QString &text) void TreeItem::setText(const QString &text)
@ -124,21 +130,21 @@ void TreeItem::setText(const QString &text)
itemText = text; itemText = text;
} }
void TreeItem::setTypeName(const QString &text)
{
itemTypeName = text;
}
void TreeItem::setSubtypeName(const QString &text)
{
itemSubtypeName = text;
}
QString TreeItem::info() const QString TreeItem::info() const
{ {
return itemInfo; return itemInfo;
} }
void TreeItem::addInfo(const QString &info)
{
itemInfo += info;
}
void TreeItem::setInfo(const QString &info)
{
itemInfo = info;
}
int TreeItem::row() const int TreeItem::row() const
{ {
if (parentItem) if (parentItem)
@ -152,11 +158,22 @@ UINT8 TreeItem::type() const
return itemType; return itemType;
} }
UINT8 TreeItem::subtype() const void TreeItem::setType(const UINT8 type)
{ {
return itemSubtype; itemType = type;
} }
UINT32 TreeItem::attributes() const
{
return itemAttributes;
}
void TreeItem::setAttributes(const UINT32 attributes)
{
itemAttributes = attributes;
}
UINT8 TreeItem::compression() const UINT8 TreeItem::compression() const
{ {
return itemCompression; return itemCompression;
@ -172,11 +189,6 @@ QByteArray TreeItem::body() const
return itemBody; return itemBody;
} }
QByteArray TreeItem::tail() const
{
return itemTail;
}
bool TreeItem::hasEmptyHeader() const bool TreeItem::hasEmptyHeader() const
{ {
return itemHeader.isEmpty(); return itemHeader.isEmpty();
@ -187,11 +199,6 @@ bool TreeItem::hasEmptyBody() const
return itemBody.isEmpty(); return itemBody.isEmpty();
} }
bool TreeItem::hasEmptyTail() const
{
return itemTail.isEmpty();
}
UINT8 TreeItem::action() const UINT8 TreeItem::action() const
{ {
return itemAction; return itemAction;
@ -212,8 +219,3 @@ void TreeItem::setAction(const UINT8 action)
parentItem->setAction(Actions::Rebuild); parentItem->setAction(Actions::Rebuild);
} }
void TreeItem::setSubtype(const UINT8 subtype)
{
itemSubtype = subtype;
itemSubtypeName = itemSubtypeToQString(itemType, itemSubtype);
}

View File

@ -1,6 +1,6 @@
/* treeitem.h /* treeitem.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -24,9 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
class TreeItem class TreeItem
{ {
public: public:
TreeItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE, TreeItem(const UINT8 type, const UINT32 attributes = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString &name = QString(), const QString &text = QString(), const QString &info = QString(), const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(), const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
TreeItem *parent = 0); TreeItem *parent = 0);
~TreeItem(); ~TreeItem();
@ -45,42 +45,42 @@ public:
TreeItem *parent(); TreeItem *parent();
// Reading operations for item parameters // Reading operations for item parameters
UINT8 type() const; QString name() const;
UINT8 subtype() const;
QByteArray header() const;
bool hasEmptyHeader() const;
QByteArray body() const;
bool hasEmptyBody() const;
QByteArray tail() const;
bool hasEmptyTail() const;
QString info() const;
UINT8 action() const;
UINT8 compression() const;
// Some values can be changed after item construction
void setAction(const UINT8 action);
void setSubtype(const UINT8 subtype);
void setTypeName(const QString &text);
void setSubtypeName(const QString &text);
void setName(const QString &text); void setName(const QString &text);
UINT8 type() const;
void setType(const UINT8 type);
UINT32 attributes() const;
void setAttributes(const UINT32 attributes);
QString text() const;
void setText(const QString &text); void setText(const QString &text);
private: QByteArray header() const;
// Set default names after construction bool hasEmptyHeader() const;
// They can later be changed by set* methods
void setDefaultNames();
QByteArray body() const;
bool hasEmptyBody() const;
QString info() const;
void addInfo(const QString &info);
void setInfo(const QString &info);
UINT8 action() const;
void setAction(const UINT8 action);
UINT8 compression() const;
private:
QList<TreeItem*> childItems; QList<TreeItem*> childItems;
UINT8 itemAction; UINT8 itemAction;
UINT8 itemType; UINT8 itemType;
UINT8 itemSubtype; UINT32 itemAttributes;
UINT8 itemCompression; UINT8 itemCompression;
QByteArray itemHeader; QByteArray itemHeader;
QByteArray itemBody; QByteArray itemBody;
QByteArray itemTail;
QString itemName; QString itemName;
QString itemTypeName;
QString itemSubtypeName;
QString itemText; QString itemText;
QString itemInfo; QString itemInfo;
TreeItem *parentItem; TreeItem *parentItem;

View File

@ -1,6 +1,6 @@
/* treemodel.cpp /* treemodel.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -138,12 +138,12 @@ UINT8 TreeModel::type(const QModelIndex &index) const
return item->type(); return item->type();
} }
UINT8 TreeModel::subtype(const QModelIndex &index) const UINT32 TreeModel::attributes(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->subtype(); return item->attributes();
} }
QByteArray TreeModel::header(const QModelIndex &index) const QByteArray TreeModel::header(const QModelIndex &index) const
@ -178,20 +178,20 @@ bool TreeModel::hasEmptyBody(const QModelIndex &index) const
return item->hasEmptyBody(); return item->hasEmptyBody();
} }
QByteArray TreeModel::tail(const QModelIndex &index) const QString TreeModel::name(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return QByteArray(); return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->tail(); return item->name();
} }
bool TreeModel::hasEmptyTail(const QModelIndex &index) const QString TreeModel::text(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return true; return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyTail(); return item->text();
} }
QString TreeModel::info(const QModelIndex &index) const QString TreeModel::info(const QModelIndex &index) const
@ -218,17 +218,17 @@ UINT8 TreeModel::compression(const QModelIndex &index) const
return item->compression(); return item->compression();
} }
void TreeModel::setSubtype(const QModelIndex & index, UINT8 subtype) void TreeModel::setAttributes(const QModelIndex & index, const UINT32 attributes)
{ {
if (!index.isValid()) if (!index.isValid())
return; return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setSubtype(subtype); item->setAttributes(attributes);
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setNameString(const QModelIndex &index, const QString &data) void TreeModel::setName(const QModelIndex &index, const QString &data)
{ {
if (!index.isValid()) if (!index.isValid())
return; return;
@ -238,27 +238,17 @@ void TreeModel::setNameString(const QModelIndex &index, const QString &data)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setTypeString(const QModelIndex &index, const QString &data) void TreeModel::setType(const QModelIndex &index, const UINT8 data)
{ {
if (!index.isValid()) if (!index.isValid())
return; return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setTypeName(data); item->setType(data);
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setSubtypeString(const QModelIndex &index, const QString &data) void TreeModel::setText(const QModelIndex &index, const QString &data)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setSubtypeName(data);
emit dataChanged(index, index);
}
void TreeModel::setTextString(const QModelIndex &index, const QString &data)
{ {
if (!index.isValid()) if (!index.isValid())
return; return;
@ -268,50 +258,14 @@ void TreeModel::setTextString(const QModelIndex &index, const QString &data)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
QString TreeModel::nameString(const QModelIndex &index) const /*QString TreeModel::name(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return QString(); return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(0).toString(); return item->name();
} }*/
QString TreeModel::actionString(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(1).toString();
}
QString TreeModel::typeString(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(2).toString();
}
QString TreeModel::subtypeString(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(3).toString();
}
QString TreeModel::textString(const QModelIndex &index) const
{
if (!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(4).toString();
}
void TreeModel::setAction(const QModelIndex &index, const UINT8 action) void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
{ {
@ -323,9 +277,9 @@ void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
emit dataChanged(this->index(0, 0), index); emit dataChanged(this->index(0, 0), index);
} }
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT8 compression, QModelIndex TreeModel::addItem(const UINT8 type, const UINT32 attributes, const UINT8 compression,
const QString & name, const QString & text, const QString & info, const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & tail, const QByteArray & header, const QByteArray & body,
const QModelIndex & parent, const UINT8 mode) const QModelIndex & parent, const UINT8 mode)
{ {
TreeItem *item = 0; TreeItem *item = 0;
@ -347,7 +301,7 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT
} }
} }
TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, tail, parentItem); TreeItem *newItem = new TreeItem(type, attributes, compression, name, text, info, header, body, parentItem);
if (mode == CREATE_MODE_APPEND) { if (mode == CREATE_MODE_APPEND) {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
parentItem->appendChild(newItem); parentItem->appendChild(newItem);

View File

@ -1,6 +1,6 @@
/* treemodel.h /* treemodel.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -42,35 +42,27 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const;
QString nameString(const QModelIndex &index) const;
QString actionString(const QModelIndex &index) const;
QString typeString(const QModelIndex &index) const;
QString subtypeString(const QModelIndex &index) const;
QString textString(const QModelIndex &index) const;
void setAction(const QModelIndex &index, const UINT8 action); void setAction(const QModelIndex &index, const UINT8 action);
void setTypeString(const QModelIndex &index, const QString &text); void setType(const QModelIndex &index, const UINT8 type);
void setSubtypeString(const QModelIndex &index, const QString &text); void setAttributes(const QModelIndex &index, const UINT32 attributes);
void setNameString(const QModelIndex &index, const QString &text); void setName(const QModelIndex &index, const QString &name);
void setTextString(const QModelIndex &index, const QString &text); void setText(const QModelIndex &index, const QString &text);
void setSubtype(const QModelIndex & index, UINT8 subtype);
QString name(const QModelIndex &index) const;
QString text(const QModelIndex &index) const;
QString info(const QModelIndex &index) const;
UINT8 type(const QModelIndex &index) const; UINT8 type(const QModelIndex &index) const;
UINT8 subtype(const QModelIndex &index) const; UINT32 attributes(const QModelIndex &index) const;
QByteArray header(const QModelIndex &index) const; QByteArray header(const QModelIndex &index) const;
bool hasEmptyHeader(const QModelIndex &index) const; bool hasEmptyHeader(const QModelIndex &index) const;
QByteArray body(const QModelIndex &index) const; QByteArray body(const QModelIndex &index) const;
bool hasEmptyBody(const QModelIndex &index) const; bool hasEmptyBody(const QModelIndex &index) const;
QByteArray tail(const QModelIndex &index) const;
bool hasEmptyTail(const QModelIndex &index) const;
QString info(const QModelIndex &index) const;
UINT8 action(const QModelIndex &index) const; UINT8 action(const QModelIndex &index) const;
UINT8 compression(const QModelIndex &index) const; UINT8 compression(const QModelIndex &index) const;
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE, QModelIndex addItem(const UINT8 type, const UINT32 attributes = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(), const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(), const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND); const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const; QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;

104
types.cpp
View File

@ -1,6 +1,6 @@
/* types.cpp /* types.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -19,15 +19,15 @@ QString regionTypeToQString(const UINT8 type)
{ {
switch (type) switch (type)
{ {
case Subtypes::DescriptorRegion: case ATTR_REGION_TYPE_DESCRIPTOR:
return QObject::tr("Descriptor"); return QObject::tr("Descriptor");
case Subtypes::GbeRegion: case ATTR_REGION_TYPE_GBE:
return QObject::tr("GbE"); return QObject::tr("GbE");
case Subtypes::MeRegion: case ATTR_REGION_TYPE_ME:
return QObject::tr("ME"); return QObject::tr("ME/TXE");
case Subtypes::BiosRegion: case ATTR_REGION_TYPE_BIOS:
return QObject::tr("BIOS"); return QObject::tr("BIOS");
case Subtypes::PdrRegion: case ATTR_REGION_TYPE_PDR:
return QObject::tr("PDR"); return QObject::tr("PDR");
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
@ -58,60 +58,76 @@ QString itemTypeToQString(const UINT8 type)
} }
} }
QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype) QString itemAttributesToQString(const UINT8 type, const UINT8 attributes)
{ {
switch (type) { switch (type) {
case Types::Root: case Types::Root:
case Types::Image: case Types::Image:
if (subtype == Subtypes::IntelImage) if (attributes == ATTR_IMAGE_TYPE_DESCRIPTOR)
return QObject::tr("Intel"); return QObject::tr("Intel");
else if (subtype == Subtypes::BiosImage) else if (attributes == ATTR_IMAGE_TYPE_UEFI)
return QObject::tr("BIOS"); return QObject::tr("UEFI");
else else
return QObject::tr("Unknown"); return QObject::tr("Unknown");
case Types::Padding: case Types::Padding:
if (subtype == Subtypes::ZeroPadding) if (attributes == ATTR_PADDING_ZERO_EMPTY)
return QObject::tr("Empty(0x00)"); return QObject::tr("Empty (0x00)");
else if (subtype == Subtypes::OnePadding) else if (attributes == ATTR_PADDING_ONE_EMPTY)
return QObject::tr("Empty(0xFF)"); return QObject::tr("Empty (0xFF)");
else if (subtype == Subtypes::DataPadding) else if (attributes == ATTR_PADDING_DATA)
return QObject::tr("Nonempty"); return QObject::tr("Non-empty");
else
return "";
case Types::Volume:
if (subtype == Subtypes::BootVolume)
return QObject::tr("Boot");
else if (subtype == Subtypes::UnknownVolume)
return QObject::tr("Unknown");
else if (subtype == Subtypes::NvramVolume)
return QObject::tr("NVRAM");
else if (subtype == Subtypes::AppleCrcVolume)
return QObject::tr("AppleCRC");
else if (subtype == Subtypes::UnknownAppleCrcVolume)
return QObject::tr("AppleCRC Unknown");
else if (subtype == Subtypes::BootAppleCrcVolume)
return QObject::tr("AppleCRC Boot");
else
return "";
case Types::Capsule:
if (subtype == Subtypes::AptioCapsule)
return QObject::tr("AMI Aptio");
else if (subtype == Subtypes::UefiCapsule)
return QObject::tr("UEFI 2.0");
else else
return QObject::tr("Unknown"); return QObject::tr("Unknown");
case Types::Volume: {
QString string;
VOLUME_ATTRIBUTES* volumeAttr = (VOLUME_ATTRIBUTES*)&attributes;
if (volumeAttr->ZeroVectorCrc)
string += QObject::tr("ZVCRC ");
if (volumeAttr->VtfPresent)
string += QObject::tr("Boot ");
if (volumeAttr->Unknown) {
string += QObject::tr("Unknown");
return string;
}
if (volumeAttr->FsVersion == 2 || volumeAttr->FsVersion == 3)
string += QObject::tr("FFSv%1").arg(volumeAttr->FsVersion);
else
return QObject::tr("Unknown FFS version");
return string;
}
case Types::Capsule: {
QString string;
CAPSULE_ATTRIBUTES* capsuleAttr = (CAPSULE_ATTRIBUTES*)&attributes;
if (capsuleAttr->Type == ATTR_CAPSULE_TYPE_APTIO)
string += QObject::tr("Aptio ");
else if (capsuleAttr->Type == ATTR_CAPSULE_TYPE_UEFI20)
string += QObject::tr("UEFI 2.0 ");
else
return QObject::tr("Unknown type");
if (capsuleAttr->Signed)
string += QObject::tr("signed");
else
string += QObject::tr("unsigned");
return string;
}
case Types::Region: case Types::Region:
return regionTypeToQString(subtype); return regionTypeToQString(attributes);
case Types::File: case Types::File:
return fileTypeToQString(subtype); return fileTypeToQString(attributes);
case Types::Section: case Types::Section:
return sectionTypeToQString(subtype); return sectionTypeToQString(attributes);
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
} }
} }
QString compressionTypeToQString(UINT8 algorithm) QString compressionTypeToQString(const UINT8 algorithm)
{ {
switch (algorithm) { switch (algorithm) {
case COMPRESSION_ALGORITHM_NONE: case COMPRESSION_ALGORITHM_NONE:
@ -129,7 +145,7 @@ QString compressionTypeToQString(UINT8 algorithm)
} }
} }
QString actionTypeToQString(UINT8 action) QString actionTypeToQString(const UINT8 action)
{ {
switch (action) { switch (action) {
case Actions::NoAction: case Actions::NoAction:

81
types.h
View File

@ -1,6 +1,6 @@
/* types.h /* types.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -16,6 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "basetypes.h" #include "basetypes.h"
#pragma pack(push, 1)
// Actions // Actions
namespace Actions namespace Actions
{ {
@ -44,46 +46,57 @@ namespace Types {
}; };
} }
namespace Subtypes { // Capsule attributes
enum ImageSubtypes{ typedef struct _CAPSULE_ATTRIBUTES {
IntelImage = 70, UINT32 Type : 7;
BiosImage UINT32 Signed : 1;
}; UINT32 Reserved : 24;
} CAPSULE_ATTRIBUTES;
#define ATTR_CAPSULE_TYPE_UEFI20 0
#define ATTR_CAPSULE_TYPE_APTIO 1
enum CapsuleSubtypes { typedef struct _IMAGE_ATTRIBUTES {
AptioCapsule = 80, UINT32 IntelDescriptor : 1;
UefiCapsule UINT32 Reserved : 31;
}; } IMAGE_ATTRIBUTES;
#define ATTR_IMAGE_TYPE_UEFI 0
#define ATTR_IMAGE_TYPE_DESCRIPTOR 1
enum VolumeSubtypes { typedef struct _REGION_ATTRIBUTES {
NormalVolume = 90, UINT32 Type : 7;
BootVolume, UINT32 Empty : 1;
UnknownVolume, UINT32 Reserved : 24;
NvramVolume, } REGION_ATTRIBUTES;
AppleCrcVolume,
UnknownAppleCrcVolume,
BootAppleCrcVolume
};
enum RegionSubtypes { #define ATTR_REGION_TYPE_DESCRIPTOR 0
DescriptorRegion = 100, #define ATTR_REGION_TYPE_GBE 1
GbeRegion, #define ATTR_REGION_TYPE_ME 2
MeRegion, #define ATTR_REGION_TYPE_BIOS 3
BiosRegion, #define ATTR_REGION_TYPE_PDR 4
PdrRegion
};
enum PaddingSubtypes { typedef struct _VOLUME_ATTRIBUTES {
ZeroPadding = 110, UINT32 Unknown : 1;
OnePadding, UINT32 VtfPresent : 1;
DataPadding UINT32 ZeroVectorCrc : 1;
}; UINT32 FsVersion : 5;
}; UINT32 Reserved : 24;
} VOLUME_ATTRIBUTES;
typedef struct _PADDING_ATTRIBUTES {
UINT32 Empty : 1;
UINT32 ErasePolarity : 1;
UINT32 Reserved : 30;
} PADDING_ATTRIBUTES;
#define ATTR_PADDING_DATA 0
#define ATTR_PADDING_ZERO_EMPTY 1
#define ATTR_PADDING_ONE_EMPTY 3
#pragma pack(pop)
// *ToQString conversion routines // *ToQString conversion routines
extern QString actionTypeToQString(const UINT8 action); extern QString actionTypeToQString(const UINT8 action);
extern QString itemTypeToQString(const UINT8 type); extern QString itemTypeToQString(const UINT8 type);
extern QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype); extern QString itemAttributesToQString(const UINT8 type, const UINT8 attributes);
extern QString compressionTypeToQString(UINT8 algorithm); extern QString compressionTypeToQString(const UINT8 algorithm);
extern QString regionTypeToQString(const UINT8 type); extern QString regionTypeToQString(const UINT8 type);
#endif #endif

View File

@ -1,6 +1,6 @@
/* uefitool.cpp /* uefitool.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("0.19.6")) version(tr("0.20.0"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -123,7 +123,7 @@ void UEFITool::populateUi(const QModelIndex &current)
TreeModel* model = ffsEngine->treeModel(); TreeModel* model = ffsEngine->treeModel();
UINT8 type = model->type(current); UINT8 type = model->type(current);
UINT8 subtype = model->subtype(current); UINT32 attributes = model->attributes(current);
// Set info text // Set info text
ui->infoEdit->setPlainText(model->info(current)); ui->infoEdit->setPlainText(model->info(current));
@ -138,17 +138,17 @@ void UEFITool::populateUi(const QModelIndex &current)
ui->menuSectionActions->setEnabled(type == Types::Section); ui->menuSectionActions->setEnabled(type == Types::Section);
// Enable actions // Enable actions
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current)); ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section); ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current)); ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section); ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) || ui->actionInsertInto->setEnabled((type == Types::Volume && ((VOLUME_ATTRIBUTES*)&attributes)->Unknown == 0) ||
(type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) || (type == Types::File && attributes != EFI_FV_FILETYPE_ALL && attributes != EFI_FV_FILETYPE_RAW && attributes != EFI_FV_FILETYPE_PAD) ||
(type == Types::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE))); (type == Types::Section && (attributes == EFI_SECTION_COMPRESSION || attributes == EFI_SECTION_GUID_DEFINED || attributes == EFI_SECTION_DISPOSABLE)));
ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section); ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section);
ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section); ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section);
ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::File || type == Types::Section); ui->actionReplace->setEnabled((type == Types::Region && ((REGION_ATTRIBUTES*)&attributes)->Type != ATTR_REGION_TYPE_DESCRIPTOR) || type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionReplaceBody->setEnabled(type == Types::File || type == Types::Section); ui->actionReplaceBody->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionMessagesCopy->setEnabled(false); ui->actionMessagesCopy->setEnabled(false);
} }
@ -321,14 +321,24 @@ void UEFITool::replace(const UINT8 mode)
else else
return; return;
} }
if (model->type(index) == Types::Volume) {
if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected object"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
}
else if (mode == REPLACE_MODE_BODY) {
path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace body"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
}
else
return;
}
else if (model->type(index) == Types::File) { else if (model->type(index) == Types::File) {
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace selected object"), currentDir, "FFS files (*.ffs *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace selected object"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) if (model->attributes(index) == EFI_FV_FILETYPE_ALL || model->attributes(index) == EFI_FV_FILETYPE_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced else if (model->attributes(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced
return; return;
else else
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
@ -341,11 +351,11 @@ void UEFITool::replace(const UINT8 mode)
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sec *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sec *.bin);;All files (*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) if (model->attributes(index) == EFI_SECTION_COMPRESSION || model->attributes(index) == EFI_SECTION_GUID_DEFINED || model->attributes(index) == EFI_SECTION_DISPOSABLE)
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) else if (model->attributes(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_RAW) else if (model->attributes(index) == EFI_SECTION_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else else
path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"), currentDir, "Binary files (*.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"), currentDir, "Binary files (*.bin);;All files (*)");
@ -436,19 +446,22 @@ void UEFITool::extract(const UINT8 mode)
case Types::Capsule: case Types::Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), currentDir, "Image files (*.rom *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), currentDir, "Image files (*.rom *.bin);;All files (*)");
break; break;
case Types::Volume:
path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
break;
case Types::File: { case Types::File: {
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) if (model->attributes(index) == EFI_FV_FILETYPE_ALL || model->attributes(index) == EFI_FV_FILETYPE_RAW)
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else else
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
} }
break; break;
case Types::Section: { case Types::Section: {
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) if (model->attributes(index) == EFI_SECTION_COMPRESSION || model->attributes(index) == EFI_SECTION_GUID_DEFINED || model->attributes(index) == EFI_SECTION_DISPOSABLE)
path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) else if (model->attributes(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_RAW) else if (model->attributes(index) == EFI_SECTION_RAW)
path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else else
path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), currentDir, "Binary files (*.bin);;All files (*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), currentDir, "Binary files (*.bin);;All files (*)");
@ -485,7 +498,7 @@ void UEFITool::extract(const UINT8 mode)
void UEFITool::about() void UEFITool::about()
{ {
QMessageBox::about(this, tr("About UEFITool"), tr( QMessageBox::about(this, tr("About UEFITool"), tr(
"Copyright (c) 2014, Nikolaj Schlej aka <b>CodeRush</b>.<br>" "Copyright (c) 2015, Nikolaj Schlej aka <b>CodeRush</b>.<br>"
"Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br><br>" "Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br><br>"
"The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br>" "The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br>"
"The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br>" "The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br>"

View File

@ -180,7 +180,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>800</width> <width>800</width>
<height>22</height> <height>21</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -243,7 +243,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionInsertInto"/> <addaction name="actionInsertInto"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionRemove"/> <addaction name="actionReplace"/>
<addaction name="actionReplaceBody"/>
</widget> </widget>
<widget class="QMenu" name="menuFileActions"> <widget class="QMenu" name="menuFileActions">
<property name="title"> <property name="title">