From a2484fdb5f09653410eb86f0156887aeb19dabbb Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Sun, 26 Jun 2016 10:05:45 +0200 Subject: [PATCH] CBString modified and integrated - CBString is used instead of QString, as PoC - removed submodule --- .gitmodules | 3 - UEFIExtract/ffsdumper.cpp | 13 ++-- UEFIExtract/uefiextract_main.cpp | 42 +++++----- common/ffsparser.cpp | 129 ++++++++++++++++--------------- common/ffsreport.cpp | 4 +- common/fitparser.cpp | 6 +- common/nvram.cpp | 12 ++- common/treeitem.cpp | 35 ++++++--- common/treeitem.h | 19 +++-- common/treemodel.cpp | 4 +- common/ustring.cpp | 73 ++++++++++++++++- common/ustring.h | 11 +-- 12 files changed, 217 insertions(+), 134 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2f51807..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "bstrlib"] - path = bstrlib - url = https://github.com/websnarf/bstrlib diff --git a/UEFIExtract/ffsdumper.cpp b/UEFIExtract/ffsdumper.cpp index 7e97448..ceaf719 100644 --- a/UEFIExtract/ffsdumper.cpp +++ b/UEFIExtract/ffsdumper.cpp @@ -43,16 +43,16 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path guidToUString(*(const EFI_GUID*)model->header(index).constData()) == guid || guidToUString(*(const EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData()) == guid) { - if (dir.cd(path)) + if (dir.cd(QString(path))) return U_DIR_ALREADY_EXIST; - if (!dir.mkpath(path)) + if (!dir.mkpath(QString(path))) return U_DIR_CREATE; QFile file; if (dumpAll || model->rowCount(index) == 0) { // Dump if leaf item or dumpAll is true if (!model->header(index).isEmpty()) { - file.setFileName(path + UString("/header.bin")); + file.setFileName(QString(path) + UString("/header.bin")); if (!file.open(QFile::WriteOnly)) return U_FILE_OPEN; @@ -61,7 +61,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path } if (!model->body(index).isEmpty()) { - file.setFileName(path + UString("/body.bin")); + file.setFileName(QString(path) + UString("/body.bin")); if (!file.open(QFile::WriteOnly)) return U_FILE_OPEN; @@ -75,11 +75,11 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path + UString("Subtype: ") + itemSubtypeToUString(model->type(index), model->subtype(index)) + UString("\n") + (model->text(index).isEmpty() ? UString("") : UString("Text: ") + model->text(index) + UString("\n")) + model->info(index) + UString("\n"); - file.setFileName(path + UString("/info.txt")); + file.setFileName(QString(path) + UString("/info.txt")); if (!file.open(QFile::Text | QFile::WriteOnly)) return U_FILE_OPEN; - file.write(info.toLatin1()); + file.write(info); file.close(); dumped = true; } @@ -98,4 +98,5 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path } return U_SUCCESS; + } diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 37a7978..3fa8d08 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include <../common/ustring.h> #include "../common/ffsparser.h" @@ -34,14 +35,15 @@ int main(int argc, char *argv[]) if (a.arguments().length() > 1) { // Check that input file exists - UString path = a.arguments().at(1); - QFileInfo fileInfo(path); + UString path(a.arguments().at(1).toLatin1()); + QString qpath = QString(path); + QFileInfo fileInfo(qpath); if (!fileInfo.exists()) return U_FILE_OPEN; // Open the input file QFile inputFile; - inputFile.setFileName(path); + inputFile.setFileName(qpath); if (!inputFile.open(QFile::ReadOnly)) return U_FILE_OPEN; @@ -60,7 +62,7 @@ int main(int argc, char *argv[]) // Show ffsParser's messages std::vector > messages = ffsParser.getMessages(); for (size_t i = 0; i < messages.size(); i++) { - std::cout << messages[i].first.toLatin1().constData() << std::endl; + std::cout << messages[i].first << std::endl; } // Get last VTF @@ -74,7 +76,7 @@ int main(int argc, char *argv[]) // Show fitParser's messages std::vector > fitMessages = fitParser.getMessages(); for (size_t i = 0; i < fitMessages.size(); i++) { - std::cout << fitMessages[i].first.toLatin1().constData() << std::endl; + std::cout << fitMessages[i].first << std::endl; } // Show FIT table @@ -84,11 +86,11 @@ int main(int argc, char *argv[]) std::cout << " Address | Size | Ver | Type | CS " << std::endl; std::cout << "-------------------------------------------------------------------" << std::endl; for (size_t i = 0; i < fitTable.size(); i++) { - std::cout << fitTable[i][0].toLatin1().constData() << " | " - << fitTable[i][1].toLatin1().constData() << " | " - << fitTable[i][2].toLatin1().constData() << " | " - << fitTable[i][3].toLatin1().constData() << " | " - << fitTable[i][4].toLatin1().constData() << std::endl; + std::cout << fitTable[i][0] << " | " + << fitTable[i][1] << " | " + << fitTable[i][2] << " | " + << fitTable[i][3] << " | " + << fitTable[i][4] << std::endl; } } } @@ -98,14 +100,12 @@ int main(int argc, char *argv[]) FfsReport ffsReport(&model); std::vector report = ffsReport.generate(); if (report.size()) { - QFile file; - file.setFileName(fileInfo.fileName().append(".report.txt")); - if (file.open(QFile::Text | QFile::WriteOnly)) { - for (size_t i = 0; i < report.size(); i++) { - file.write(report[i].toLatin1().append('\n')); - } - file.close(); + std::ofstream ofs; + ofs.open("report.txt", std::ofstream::out); + for (size_t i = 0; i < report.size(); i++) { + ofs << report[i] << std::endl; } + ofs.close(); } // Create ffsDumper @@ -113,10 +113,10 @@ int main(int argc, char *argv[]) // Dump all non-leaf elements if (a.arguments().length() == 2) { - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS); + return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData()) != U_SUCCESS); } else if (a.arguments().length() == 3 && a.arguments().at(2) == UString("all")) { // Dump everything - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != U_SUCCESS); + return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData(), true) != U_SUCCESS); } else if (a.arguments().length() == 3 && a.arguments().at(2) == UString("none")) { // Skip dumping return 0; @@ -124,7 +124,7 @@ int main(int argc, char *argv[]) else { // Dump specific files UINT32 returned = 0; for (int i = 2; i < a.arguments().length(); i++) { - result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true, a.arguments().at(i)); + result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData(), true, a.arguments().at(i).toLatin1().constData()); if (result) returned |= (1 << (i - 1)); } @@ -142,4 +142,6 @@ int main(int argc, char *argv[]) << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl; return 1; } + +return 0; } diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index f3880e7..0c2cf52 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -14,6 +14,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +#include // Region info structure definition struct REGION_INFO { @@ -225,7 +226,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p // Check for buffer size to be greater or equal to descriptor region size if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) { - msg(usprintf("parseIntelImage: input file is smaller than minimum descriptor size of %X (%u) bytes", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); + msg(usprintf("parseIntelImage: input file is smaller than minimum descriptor size of %Xh (%u) bytes", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); return U_INVALID_FLASH_DESCRIPTOR; } @@ -486,8 +487,8 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p // Add offsets of actual regions for (size_t i = 0; i < regions.size(); i++) { if (regions[i].type != Subtypes::ZeroPadding && regions[i].type != Subtypes::OnePadding && regions[i].type != Subtypes::DataPadding) - info += itemSubtypeToUString(Types::Region, regions[i].type).prepend("\n") - + usprintf(" region offset: %Xh", itemSubtypeToUString(Types::Region, regions[i].type), regions[i].offset + parentOffset); + info += UString("\n") + itemSubtypeToUString(Types::Region, regions[i].type) + + usprintf(" region offset: %Xh", regions[i].offset + parentOffset); } // Region access settings @@ -517,8 +518,8 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p } else if (descriptorVersion == 2) { const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase); - info += ("\nRegion access settings:"); - info += ("\nBIOS: %03Xh %03Xh ME: %03Xh %03Xh\nGbE: %03Xh %03Xh EC: %03Xh %03Xh", + info += UString("\nRegion access settings:"); + info += usprintf("\nBIOS: %03Xh %03Xh ME: %03Xh %03Xh\nGbE: %03Xh %03Xh EC: %03Xh %03Xh", masterSection->BiosRead, masterSection->BiosWrite, masterSection->MeRead, @@ -554,7 +555,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p info += UString("\nFlash chips in VSCC table:"); UINT8 vsscTableSize = upperMap->VsccTableSize * sizeof(UINT32) / sizeof(VSCC_TABLE_ENTRY); for (int i = 0; i < vsscTableSize; i++) { - info += usprintf("\n02X%02X%02Xh", + info += usprintf("\n%02X%02X%02Xh", vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1); vsccTableEntry++; } @@ -598,7 +599,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p // Get info name = UString("Padding"); - info = usprintf("Full size: %X (%u)", + info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); // Construct parsing data @@ -1104,15 +1105,15 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 par volumeHeader->ZeroVector[8], volumeHeader->ZeroVector[9], volumeHeader->ZeroVector[10], volumeHeader->ZeroVector[11], volumeHeader->ZeroVector[12], volumeHeader->ZeroVector[13], volumeHeader->ZeroVector[14], volumeHeader->ZeroVector[15]) + guidToUString(volumeHeader->FileSystemGuid) \ - + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRevision: %u\nAttributes: %08Xh\nErase polarity: %u\nChecksum: %02Xh", + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRevision: %u\nAttributes: %08Xh\nErase polarity: %u\nChecksum: %04Xh", volumeSize, volumeSize, headerSize, headerSize, volumeSize - headerSize, volumeSize - headerSize, volumeHeader->Revision, - volumeHeader->Attributes, 8, - emptyByte ? 1 : 0, + volumeHeader->Attributes, + (emptyByte ? 1 : 0), volumeHeader->Checksum) + - (msgInvalidChecksum ? usprintf("invalid, should be %04Xh", calculated) : UString("valid")); + (msgInvalidChecksum ? usprintf(", invalid, should be %04Xh", calculated) : UString(", valid")); // Extended header present if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { @@ -1177,19 +1178,19 @@ USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, nextIndex + 1)) { const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET); if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid FvLength %Xh", + msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid FvLength %"PRIX64"h", parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), volumeHeader->FvLength), index); continue; } if (volumeHeader->Reserved != 0xFF && volumeHeader->Reserved != 0x00) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Reserved byte value %02X", + msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Reserved byte value %02Xh", parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), volumeHeader->Reserved), index); continue; } if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Revision byte value %02X", + msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET) ,volumeHeader->Revision), index); continue; @@ -1576,17 +1577,17 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 parentO else name = UString("Pad-file"); - info = guidToUString(fileHeader->Name).prepend("File GUID : ") + - usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh\n", + info = UString("File GUID: ") + guidToUString(fileHeader->Name) + + usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh", fileHeader->Type, fileHeader->Attributes, header.size() + body.size() + tail.size(), header.size() + body.size() + tail.size(), header.size(), header.size(), body.size(), body.size(), tail.size(), tail.size(), - fileHeader->State) - + (msgInvalidHeaderChecksum ? usprintf("%02Xh, invalid, should be %02Xh", fileHeader->IntegrityCheck.Checksum.Header, calculatedHeader) : usprintf("%02X, valid", calculatedHeader)) - + (msgInvalidDataChecksum ? usprintf("%02Xh, invalid, should be %02Xh", fileHeader->IntegrityCheck.Checksum.File, calculatedData) : usprintf("%02X, valid", calculatedData)); + fileHeader->State) + + usprintf("\nHeader checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.Header) + (msgInvalidHeaderChecksum ? usprintf(", invalid, should be %02Xh", calculatedHeader) : UString(", valid")) + + usprintf("\nData checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.File) + (msgInvalidDataChecksum ? usprintf(", invalid, should be %02Xh", calculatedData) : UString(", valid")); // Add file GUID to parsing data pdata.file.guid = fileHeader->Name; @@ -2024,7 +2025,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI return U_INVALID_SECTION; // Check for special GUIDed sections - UByteArray additionalInfo; + UString additionalInfo; UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); bool msgSignedSectionFound = false; bool msgNoAuthStatusAttribute = false; @@ -2049,7 +2050,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI additionalInfo += usprintf("\nChecksum: %08Xh, valid", crc); } else { - additionalInfo += usprintf("\nChecksum: %02Xh, invalid, should be %02Xh", crc, calculated); + additionalInfo += usprintf("\nChecksum: %08Xh, invalid, should be %08Xh", crc, calculated); msgInvalidCrc = true; } // No need to change dataOffset here @@ -2118,7 +2119,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI attributes); // Append additional info - info.append(additionalInfo); + info += additionalInfo; // Construct parsing data pdata.offset += parentOffset; @@ -2261,7 +2262,7 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U // Get info UString name = sectionTypeToUString(type) + (" section"); - UString info = ("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nBuild number: %u", + UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nBuild number: %u", type, section.size(), section.size(), header.size(), header.size(), @@ -2323,8 +2324,8 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const // Get info UString name = sectionTypeToUString(type) + (" section"); - UString info = ("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nPostcode: %Xh", - type, 2, + UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nPostcode: %Xh", + type, section.size(), section.size(), header.size(), header.size(), body.size(), body.size(), @@ -2682,7 +2683,7 @@ USTATUS FfsParser::parseAprioriRawSection(const UByteArray & body, UString & par if (count > 0) { for (UINT32 i = 0; i < count; i++) { const EFI_GUID* guid = (const EFI_GUID*)body.constData() + i; - parsed += guidToUString(*guid).prepend("\n"); + parsed += UString("\n") + guidToUString(*guid); } } @@ -2752,7 +2753,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) return U_SUCCESS; } - UByteArray info; + UString info; const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)body.constData(); if (dosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { info += usprintf("\nDOS signature: %04Xh, invalid", dosHeader->e_magic); @@ -2787,7 +2788,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) info += usprintf("\nDOS signature: %04Xh\nPE signature: %08Xh", dosHeader->e_magic, peHeader->Signature) + - machineTypeToUString(imageFileHeader->Machine).prepend("\nMachine type: ") + + UString("\nMachine type: ") + machineTypeToUString(imageFileHeader->Machine) + usprintf("\nNumber of sections: %u\nCharacteristics: %04Xh", imageFileHeader->NumberOfSections, imageFileHeader->Characteristics); @@ -2810,7 +2811,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) optionalHeader.H32->ImageBase); } else if (optionalHeader.H32->Magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) { - info += usprintf("\nOptional header signature: %04Xh\nSubsystem: %04Xh\nAddress of entry point: %Xh\nBase of code: %Xh\nImage base: %Xh", + info += usprintf("\nOptional header signature: %04Xh\nSubsystem: %04Xh\nAddress of entry point: %Xh\nBase of code: %Xh\nImage base: %"PRIX64"h", optionalHeader.H64->Magic, optionalHeader.H64->Subsystem, optionalHeader.H64->AddressOfEntryPoint, @@ -2840,7 +2841,7 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index) return U_SUCCESS; } - UByteArray info; + UString info; const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)body.constData(); if (teHeader->Signature != EFI_IMAGE_TE_SIGNATURE) { info += usprintf("\nSignature: %04Xh, invalid", teHeader->Signature); @@ -2848,9 +2849,9 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index) } else { info += usprintf("\nSignature: %04Xh", teHeader->Signature) + - machineTypeToUString(teHeader->Machine).prepend("\nMachine type: ") + + UString("\nMachine type: ") + machineTypeToUString(teHeader->Machine) + usprintf("\nNumber of sections: %u\nSubsystem: %02Xh\nStripped size: %Xh (%u)\n" - "Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %Xh\nAdjusted image base: %Xh", + "Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %"PRIX64"h\nAdjusted image base: %"PRIX64"h", teHeader->NumberOfSections, teHeader->Subsystem, teHeader->StrippedSize, teHeader->StrippedSize, @@ -3256,9 +3257,8 @@ parsing_done: info += usprintf("\nAttributes: %02Xh", entryHeader->Attributes); // Translate attributes to text if (entryHeader->Attributes && entryHeader->Attributes != 0xFF) - info += nvarAttributesToUString(entryHeader->Attributes).prepend(" (").append(")"); - - + info += UString(" (") + nvarAttributesToUString(entryHeader->Attributes) + UString(")"); + // Add next node info if (!isInvalid && entryHeader->Next != lastVariableFlag) info += usprintf("\nNext node at offset: %Xh", parentOffset + offset + entryHeader->Next); @@ -3267,7 +3267,7 @@ parsing_done: if (hasExtendedHeader) { info += usprintf("\nExtended header size: %Xh (%u)\nExtended attributes: %Xh (", extendedHeaderSize, extendedHeaderSize, - extendedAttributes) + nvarExtendedAttributesToUString(extendedAttributes).append(")"); + extendedAttributes) + nvarExtendedAttributesToUString(extendedAttributes) + UString(")"); // Checksum if (hasChecksum) @@ -3275,8 +3275,8 @@ parsing_done: (calculatedChecksum ? usprintf(", invalid, should be %02Xh", 0x100 - calculatedChecksum) : UString(", valid")); // Authentication data if (hasTimestampAndHash) { - info += usprintf("\nTimestamp: %Xh\nHash: ", - timestamp) + hash.toHex().toUpper(); + info += usprintf("\nTimestamp: %"PRIX64"h\nHash: ", + timestamp) + UString(hash.toHex().toUpper()); } } @@ -3378,8 +3378,8 @@ USTATUS FfsParser::parseNvramVolumeBody(const UModelIndex & index) UByteArray padding = data.mid(storeOffset); // Get info - name = ("Padding"); - info = ("Full size: %Xh (%u)", padding.size(), padding.size()); + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); // Construct parsing data pdata.offset = parentOffset + storeOffset; @@ -3770,14 +3770,14 @@ USTATUS FfsParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 pa // Add info UString name("FTW store"); - UString info = guidToUString(ftw32BlockHeader->Signature).prepend("Signature:") + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: ", + UString info = UString("Signature: ") + guidToUString(ftw32BlockHeader->Signature) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh", ftwBlockSize, ftwBlockSize, headerSize, headerSize, body.size(), body.size(), - ftw32BlockHeader->State) + - (ftw32BlockHeader->Crc == calculatedCrc ? usprintf("%08Xh, valid", ftw32BlockHeader->Crc) : - usprintf("%08Xh, invalid, should be %08Xh", ftw32BlockHeader->Crc, calculatedCrc)); + ftw32BlockHeader->State, + ftw32BlockHeader->Crc) + + (ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); // Add correct offset pdata.offset = parentOffset; @@ -3896,14 +3896,14 @@ USTATUS FfsParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 p // Add info bool isGaidStore = (fsysStoreHeader->Signature == NVRAM_APPLE_GAID_STORE_SIGNATURE); UString name = isGaidStore ? UString("Gaid store") : UString("Fsys store"); - UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nUnknown0: %02Xh\nUnknown1: %08Xh\nCRC32: ", + UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nUnknown0: %02Xh\nUnknown1: %08Xh\nCRC32: %08Xh", isGaidStore ? "Gaid" : "Fsys", fsysStoreHeader->Size, fsysStoreHeader->Size, header.size(), header.size(), body.size(), body.size(), fsysStoreHeader->Unknown0, fsysStoreHeader->Unknown1) - + (storedCrc == calculatedCrc ? usprintf("%08Xh, valid", storedCrc) : usprintf("%08Xh, invalid, should be %08Xh", storedCrc, calculatedCrc)); + + (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); // Add correct offset pdata.offset = parentOffset; @@ -3947,13 +3947,14 @@ USTATUS FfsParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 p // Add info UString name("EVSA store"); - UString info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nAttributes: %08Xh\nChecksum: ", + UString info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nAttributes: %08Xh\nChecksum: %02Xh", evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, header.size(), header.size(), body.size(), body.size(), evsaStoreHeader->Header.Type, - evsaStoreHeader->Attributes) + - (evsaStoreHeader->Header.Checksum == calculated ? usprintf("%02Xh, valid", calculated) : usprintf("%02Xh, invalid, should be %02Xh", evsaStoreHeader->Header.Checksum, calculated)); + evsaStoreHeader->Attributes, + evsaStoreHeader->Header.Checksum) + + (evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid")); // Add correct offset pdata.offset = parentOffset; @@ -4084,7 +4085,7 @@ USTATUS FfsParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 // Add info UString name("SLIC pubkey"); UString info = usprintf("Type: 0h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n" - "Key type :%02Xh\nVersion: %02Xh\nAlgorithm: %08Xh\nMagic: RSA1\nBit length: %08Xh\nExponent:%08Xh", + "Key type :%02Xh\nVersion: %02Xh\nAlgorithm: %08Xh\nMagic: RSA1\nBit length: %08Xh\nExponent: %08Xh", pubkeyHeader->Size, pubkeyHeader->Size, header.size(), header.size(), pubkeyHeader->KeyType, @@ -4136,8 +4137,8 @@ USTATUS FfsParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 markerHeader->Size, markerHeader->Size, header.size(), header.size(), markerHeader->Version, - (const char*)&(markerHeader->OemId), - (const char*)&(markerHeader->OemTableId), + (const char*)UString((const char*)&(markerHeader->OemId), 6), + (const char*)UString((const char*)&(markerHeader->OemTableId), 8), markerHeader->SlicVersion); // Add correct offset @@ -4416,20 +4417,20 @@ USTATUS FfsParser::parseVssStoreBody(const UModelIndex & index) header.size(), header.size(), body.size(), body.size(), variableHeader->State, - variableHeader->Attributes) + vssAttributesToUString(variableHeader->Attributes).append(")"); + variableHeader->Attributes) + vssAttributesToUString(variableHeader->Attributes) + UString(")"); // Set subtype and add related info if (isInvalid) subtype = Subtypes::InvalidVssEntry; else if (isAuthenticated) { subtype = Subtypes::AuthVssEntry; - info += usprintf("\nMonotonic counter: %Xh\nTimestamp:", monotonicCounter) + efiTimeToUString(timestamp) + info += usprintf("\nMonotonic counter: %"PRIX64"h\nTimestamp: ", monotonicCounter) + efiTimeToUString(timestamp) + usprintf("\nPubKey index: %u", pubKeyIndex); } else if (isAppleCrc32) { subtype = Subtypes::AppleVssEntry; - info += usprintf("\nData checksum: %08X", storedCrc32) + - (storedCrc32 == calculatedCrc32 ? UString(", valid") : usprintf(", invalid, should be %08Xh", calculatedCrc32)); + info += usprintf("\nData checksum: %08Xh", storedCrc32) + + (storedCrc32 != calculatedCrc32 ? usprintf(", invalid, should be %08Xh", calculatedCrc32) : UString(", valid")); } else subtype = Subtypes::StandardVssEntry; @@ -4487,7 +4488,7 @@ USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index) pdata.offset = parentOffset + offset; // Add EOF tree item - model->addItem(Types::FsysEntry, 0, name, UString(), info, header, UByteArray(), UByteArray(), false, parsingDataToUByteArray(pdata), index); + model->addItem(Types::FsysEntry, 0, UString(name), UString(), info, header, UByteArray(), UByteArray(), false, parsingDataToUByteArray(pdata), index); // Add free space offset += header.size(); @@ -4541,7 +4542,7 @@ USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index) pdata.offset = parentOffset + offset; // Add tree item - model->addItem(Types::FsysEntry, 0, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); + model->addItem(Types::FsysEntry, 0, UString(name), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); // Move to next variable offset += variableSize; @@ -4628,7 +4629,7 @@ USTATUS FfsParser::parseEvsaStoreBody(const UModelIndex & index) body.size(), body.size(), guidHeader->Header.Type, guidHeader->Header.Checksum) - + (guidHeader->Header.Checksum == calculated ? UString(", valid") : usprintf(", invalid, should be %02Xh", calculated)) + + (guidHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + usprintf("\nGuidId: %04Xh", guidHeader->GuidId); subtype = Subtypes::GuidEvsaEntry; guidMap.insert(std::pair(guidHeader->GuidId, guid)); @@ -4646,7 +4647,7 @@ USTATUS FfsParser::parseEvsaStoreBody(const UModelIndex & index) body.size(), body.size(), nameHeader->Header.Type, nameHeader->Header.Checksum) - + (nameHeader->Header.Checksum == calculated ? UString(", valid") : usprintf(", invalid, should be %02Xh", calculated)) + + (nameHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + usprintf("\nVarId: %04Xh", nameHeader->VarId); subtype = Subtypes::NameEvsaEntry; nameMap.insert(std::pair(nameHeader->VarId, name)); @@ -4675,12 +4676,12 @@ USTATUS FfsParser::parseEvsaStoreBody(const UModelIndex & index) dataSize, dataSize, dataHeader->Header.Type, dataHeader->Header.Checksum) - + (dataHeader->Header.Checksum == calculated ? UString("valid") : usprintf(", invalid, should be %02Xh", calculated)) + + (dataHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + usprintf("\nVarId: %04Xh\nGuidId: %04Xh\nAttributes: %08Xh (", dataHeader->VarId, dataHeader->GuidId, dataHeader->Attributes) - + evsaAttributesToUString(dataHeader->Attributes).append(")"); + + evsaAttributesToUString(dataHeader->Attributes) + UString(")"); subtype = Subtypes::DataEvsaEntry; } // Unknown entry or free space @@ -4759,7 +4760,7 @@ USTATUS FfsParser::parseEvsaStoreBody(const UModelIndex & index) model->setName(current, guid); } model->setText(current, name); - model->addInfo(current, guid.prepend("GUID: ") + name.prepend("\nName: "), false); + model->addInfo(current, UString("GUID: ") + guid + UString("\nName: ") + name + UString("\n"), false); } } } diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp index 3f9638c..a16c592 100644 --- a/common/ffsreport.cpp +++ b/common/ffsreport.cpp @@ -53,9 +53,9 @@ USTATUS FfsReport::generateRecursive(std::vector & report, UModelIndex UString text = model->text(index); report.push_back( UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16) - + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) + + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) + usprintf("| %08X | %08X | ", data.size(), crc) - + UString(level, '-') + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) + + UString('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) ); // Information on child items diff --git a/common/fitparser.cpp b/common/fitparser.cpp index a01c1dc..21e7ceb 100644 --- a/common/fitparser.cpp +++ b/common/fitparser.cpp @@ -58,10 +58,10 @@ USTATUS FitParser::parse(const UModelIndex & index, const UModelIndex & lastVtfI // Add FIT header to fitTable std::vector currentStrings; currentStrings.push_back(UString("_FIT_ ")); - currentStrings.push_back(usprintf("%08X",fitSize)); - currentStrings.push_back(usprintf("%04X",fitHeader->Version)); + currentStrings.push_back(usprintf("%08X", fitSize)); + currentStrings.push_back(usprintf("%04X", fitHeader->Version)); currentStrings.push_back(fitEntryTypeToUString(fitHeader->Type)); - currentStrings.push_back(usprintf("%02X",fitHeader->Checksum)); + currentStrings.push_back(usprintf("%02X", fitHeader->Checksum)); fitTable.push_back(currentStrings); // Process all other entries diff --git a/common/nvram.cpp b/common/nvram.cpp index c279d56..d34af8b 100644 --- a/common/nvram.cpp +++ b/common/nvram.cpp @@ -28,7 +28,8 @@ UString nvarAttributesToUString(const UINT8 attributes) if (attributes & NVRAM_NVAR_ENTRY_AUTH_WRITE) str += UString(", AuthWrite"); if (attributes & NVRAM_NVAR_ENTRY_VALID) str += UString(", Valid"); - return str.mid(2); // Remove first comma and space + str.remove(0, 2); // Remove first comma and space + return str; } UString nvarExtendedAttributesToUString(const UINT8 attributes) @@ -39,7 +40,8 @@ UString nvarExtendedAttributesToUString(const UINT8 attributes) if (attributes & NVRAM_NVAR_ENTRY_EXT_TIME_BASED) str += UString(", TimeBasedAuthWrite"); if (attributes & NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK) str += UString(", Unknown"); - return str.mid(2); // Remove first comma and space + str.remove(0, 2); // Remove first comma and space + return str; } extern UString vssAttributesToUString(const UINT32 attributes) @@ -55,7 +57,8 @@ extern UString vssAttributesToUString(const UINT32 attributes) if (attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) str += UString(", AppleChecksum"); if (attributes & NVRAM_VSS_VARIABLE_UNKNOWN_MASK) str += UString(", Unknown"); - return str.mid(2); // Remove first comma and space + str.remove(0, 2); // Remove first comma and space + return str; } UString evsaAttributesToUString(const UINT32 attributes) @@ -71,7 +74,8 @@ UString evsaAttributesToUString(const UINT32 attributes) if (attributes & NVRAM_EVSA_DATA_EXTENDED_HEADER) str += UString(", ExtendedHeader"); if (attributes & NVRAM_EVSA_DATA_UNKNOWN_MASK) str += UString(", Unknown"); - return str.mid(2); // Remove first comma and space + str.remove(0, 2); // Remove first comma and space + return str; } UString efiTimeToUString(const EFI_TIME & time) diff --git a/common/treeitem.cpp b/common/treeitem.cpp index a0fefe0..c8c3531 100644 --- a/common/treeitem.cpp +++ b/common/treeitem.cpp @@ -33,28 +33,35 @@ TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, itemCompressed(compressed), parentItem(parent) { - setFixed(fixed); +} + +TreeItem::~TreeItem() { + std::list::iterator begin = childItems.begin(); + while (begin != childItems.end()) { + delete *begin; + ++begin; + } } UINT8 TreeItem::insertChildBefore(TreeItem *item, TreeItem *newItem) { - int index = childItems.indexOf(item); - if (index == -1) + std::list::iterator found = std::find(std::begin(childItems), std::end(childItems), item); + if (found == std::end(childItems)) return U_ITEM_NOT_FOUND; - childItems.insert(index, newItem); + childItems.insert(found, newItem); return U_SUCCESS; } UINT8 TreeItem::insertChildAfter(TreeItem *item, TreeItem *newItem) { - int index = childItems.indexOf(item); - if (index == -1) + std::list::iterator found = std::find(std::begin(childItems), std::end(childItems), item); + if (found == std::end(childItems)) return U_ITEM_NOT_FOUND; - childItems.insert(index + 1, newItem); + childItems.insert(++found, newItem); return U_SUCCESS; } -QVariant TreeItem::data(int column) const +UString TreeItem::data(int column) const { switch (column) { @@ -69,14 +76,18 @@ QVariant TreeItem::data(int column) const case 4: // Text return itemText; default: - return QVariant(); + return UString(); } } int TreeItem::row() const { - if (parentItem) - return parentItem->childItems.indexOf(const_cast(this)); - + if (parentItem) { + std::list::const_iterator iter = parentItem->childItems.cbegin(); + for (int i = 0; i < (int)parentItem->childItems.size(); ++i, ++iter) { + if (const_cast(this) == *iter) + return i; + } + } return 0; } diff --git a/common/treeitem.h b/common/treeitem.h index 265d507..08b92af 100644 --- a/common/treeitem.h +++ b/common/treeitem.h @@ -14,8 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef TREEITEM_H #define TREEITEM_H -#include -#include +#include #include "ubytearray.h" #include "ustring.h" @@ -28,19 +27,19 @@ public: const UByteArray & header, const UByteArray & body, const UByteArray & tail, const BOOLEAN fixed, const BOOLEAN compressed, const UByteArray & parsingData, TreeItem *parent = 0); - ~TreeItem() { qDeleteAll(childItems); } + ~TreeItem(); // Non-trivial implementation in CPP file // Operations with items - void appendChild(TreeItem *item) { childItems.append(item); } - void prependChild(TreeItem *item) { childItems.prepend(item); }; + void appendChild(TreeItem *item) { childItems.push_back(item); } + void prependChild(TreeItem *item) { childItems.push_front(item); }; UINT8 insertChildBefore(TreeItem *item, TreeItem *newItem); // Non-trivial implementation in CPP file UINT8 insertChildAfter(TreeItem *item, TreeItem *newItem); // Non-trivial implementation in CPP file // Model support operations - TreeItem *child(int row) { return childItems.value(row, NULL); } - int childCount() const {return childItems.count(); } + TreeItem *child(int row) { return *std::next(childItems.begin(), row); } + int childCount() const {return childItems.size(); } int columnCount() const { return 5; } - QVariant data(int column) const; // Non-trivial implementation in CPP file + UString data(int column) const; // Non-trivial implementation in CPP file int row() const; // Non-trivial implementation in CPP file TreeItem *parent() { return parentItem; } @@ -71,7 +70,7 @@ public: void setParsingData(const UByteArray & data) { itemParsingData = data; } UString info() const { return itemInfo; } - void addInfo(const UString &info, const BOOLEAN append) { if (append) itemInfo.append(info); else itemInfo.prepend(info); } + void addInfo(const UString &info, const BOOLEAN append) { if (append) itemInfo += info; else itemInfo = info + itemInfo; } void setInfo(const UString &info) { itemInfo = info; } UINT8 action() const {return itemAction; } @@ -84,7 +83,7 @@ public: void setCompressed(const bool compressed) { itemCompressed = compressed; } private: - QList childItems; + std::list childItems; UINT8 itemAction; UINT8 itemType; UINT8 itemSubtype; diff --git a/common/treemodel.cpp b/common/treemodel.cpp index f4222f7..df0e03f 100644 --- a/common/treemodel.cpp +++ b/common/treemodel.cpp @@ -44,9 +44,9 @@ QVariant TreeModel::data(const UModelIndex &index, int role) const TreeItem *item = static_cast(index.internalPointer()); if (role == Qt::DisplayRole) - return item->data(index.column()); + return (const char*)item->data(index.column()); else - return item->info(); + return (const char*)item->info(); } Qt::ItemFlags TreeModel::flags(const UModelIndex &index) const diff --git a/common/ustring.cpp b/common/ustring.cpp index ccc0284..94b75fe 100644 --- a/common/ustring.cpp +++ b/common/ustring.cpp @@ -13,13 +13,84 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "ustring.h" #include +//TODO: modify properly + +#ifndef QT_CORE_LIB UString usprintf(const char* fmt, ...) { UString msg; va_list vl; va_start(vl, fmt); - msg = msg.vsprintf(fmt, vl); + msg.vsprintf(fmt, vl); va_end(vl); return msg; }; +#else +/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ +#if defined(__WATCOMC__) || defined(_MSC_VER) +#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} +#else +#ifdef BSTRLIB_NOVSNP +/* This is just a hack. If you are using a system without a vsnprintf, it is +not recommended that bformat be used at all. */ +#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} +#define START_VSNBUFF (256) +#else +#if defined (__GNUC__) && !defined (__PPC__) +/* Something is making gcc complain about this prototype not being here, so +I've just gone ahead and put it in. */ +extern "C" { + extern int vsnprintf(char *buf, size_t count, const char *format, va_list arg); +} +#endif + +#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);} +#endif +#endif + +#ifndef START_VSNBUFF +#define START_VSNBUFF (16) +#endif + +UString usprintf(const char* fmt, ...) +{ + UString msg; + bstring b; + va_list arglist; + int r, n; + + if (fmt == NULL) { + msg = ""; + } + else { + + if ((b = bfromcstr("")) == NULL) { + msg = ""; + } + else { + if ((n = (int)(2 * (strlen)(fmt))) < START_VSNBUFF) n = START_VSNBUFF; + for (;;) { + if (BSTR_OK != balloc(b, n + 2)) { + b = bformat(""); + break; + } + + va_start(arglist, fmt); + exvsnprintf(r, (char *)b->data, n + 1, fmt, arglist); + va_end(arglist); + + b->data[n] = '\0'; + b->slen = (int)(strlen)((char *)b->data); + + if (b->slen < n) break; + if (r > n) n = r; else n += n; + } + msg = *b; + bdestroy(b); + } + } + + return msg; +} +#endif diff --git a/common/ustring.h b/common/ustring.h index 635bf62..345917a 100644 --- a/common/ustring.h +++ b/common/ustring.h @@ -15,20 +15,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. //TODO: modify properly -#ifdef QT_CORE_LIB +#ifndef QT_CORE_LIB // Use Qt class, if Qt is available #include #define UString QString #else -// Use own implementation +// Use Bstrlib +#define BSTRLIB_DOESNT_THROW_EXCEPTIONS #include "../bstrlib/bstrwrap.h" -class UString : public CBString { -}; - +#define UString CBString #endif // QT_CORE_LIB UString usprintf(const char* fmt, ...); - - #endif // USTRING_H