From 3fe256448148044b7c4a6f70b7947ec51033cf86 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Wed, 20 Jul 2011 04:18:18 +1000 Subject: - Heimdall Frontend large font fixes. - Heimdall Frontend name collision resolution (over the top). - Attempt at resolving SGS2 failure to end session errors. (Needs testing) --- heimdall-frontend/Source/Alerts.cpp | 2 + heimdall-frontend/Source/FirmwareInfo.cpp | 17 +- heimdall-frontend/Source/FirmwareInfo.h | 2 +- heimdall-frontend/Source/Packaging.cpp | 321 ++++++++++++++++++++++++++-- heimdall-frontend/Source/Packaging.h | 5 +- heimdall-frontend/heimdall-frontend.vcxproj | 5 +- heimdall-frontend/mainwindow.ui | 74 +++---- 7 files changed, 358 insertions(+), 68 deletions(-) (limited to 'heimdall-frontend') diff --git a/heimdall-frontend/Source/Alerts.cpp b/heimdall-frontend/Source/Alerts.cpp index e8e8752..5dc0337 100644 --- a/heimdall-frontend/Source/Alerts.cpp +++ b/heimdall-frontend/Source/Alerts.cpp @@ -29,6 +29,7 @@ using namespace HeimdallFrontend; void Alerts::DisplayError(const QString& errorMessage) { QMessageBox messageBox; + messageBox.setModal(true); messageBox.setText(errorMessage); messageBox.setIcon(QMessageBox::Critical); messageBox.exec(); @@ -37,6 +38,7 @@ void Alerts::DisplayError(const QString& errorMessage) void Alerts::DisplayWarning(const QString& warningMessage) { QMessageBox messageBox; + messageBox.setModal(true); messageBox.setText(warningMessage); messageBox.setIcon(QMessageBox::Warning); messageBox.exec(); diff --git a/heimdall-frontend/Source/FirmwareInfo.cpp b/heimdall-frontend/Source/FirmwareInfo.cpp index aee9313..7870621 100644 --- a/heimdall-frontend/Source/FirmwareInfo.cpp +++ b/heimdall-frontend/Source/FirmwareInfo.cpp @@ -18,9 +18,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ +// Qt +#include "QRegExp" + // Heimdall Frontend #include "Alerts.h" #include "FirmwareInfo.h" +#include "Packaging.h" using namespace HeimdallFrontend; @@ -320,7 +324,7 @@ bool FileInfo::ParseXml(QXmlStreamReader& xml) return (false); } -void FileInfo::WriteXml(QXmlStreamWriter& xml) const +void FileInfo::WriteXml(QXmlStreamWriter& xml, const QString& filename) const { xml.writeStartElement("file"); @@ -329,14 +333,7 @@ void FileInfo::WriteXml(QXmlStreamWriter& xml) const xml.writeEndElement(); xml.writeStartElement("filename"); - - int lastSlash = filename.lastIndexOf('/'); - - if (lastSlash < 0) - lastSlash = filename.lastIndexOf('\\'); - - xml.writeCharacters(filename.mid(lastSlash + 1)); - + xml.writeCharacters(filename); xml.writeEndElement(); xml.writeEndElement(); @@ -775,7 +772,7 @@ void FirmwareInfo::WriteXml(QXmlStreamWriter& xml) const xml.writeStartElement("files"); for (int i = 0; i < fileInfos.length(); i++) - fileInfos[i].WriteXml(xml); + fileInfos[i].WriteXml(xml, Packaging::ClashlessFilename(fileInfos, i)); xml.writeEndElement(); diff --git a/heimdall-frontend/Source/FirmwareInfo.h b/heimdall-frontend/Source/FirmwareInfo.h index 64c73cb..5765199 100644 --- a/heimdall-frontend/Source/FirmwareInfo.h +++ b/heimdall-frontend/Source/FirmwareInfo.h @@ -126,7 +126,7 @@ namespace HeimdallFrontend FileInfo(unsigned int partitionId, const QString& filename); bool ParseXml(QXmlStreamReader& xml); - void WriteXml(QXmlStreamWriter& xml) const; + void WriteXml(QXmlStreamWriter& xml, const QString& filename) const; unsigned int GetPartitionId(void) const { diff --git a/heimdall-frontend/Source/Packaging.cpp b/heimdall-frontend/Source/Packaging.cpp index fc41ba6..6c3890b 100644 --- a/heimdall-frontend/Source/Packaging.cpp +++ b/heimdall-frontend/Source/Packaging.cpp @@ -221,12 +221,12 @@ bool Packaging::ExtractTar(QTemporaryFile& tarFile, PackageData *packageData) return (true); } -bool Packaging::WriteTarEntry(const QString& filename, QTemporaryFile *tarFile, bool firmwareXml) +bool Packaging::WriteTarEntry(const QString& filePath, QTemporaryFile *tarFile, const QString& entryFilename) { TarHeader tarHeader; memset(tarHeader.buffer, 0, TarHeader::kBlockLength); - QFile file(filename); + QFile file(filePath); if (!file.open(QFile::ReadOnly)) { @@ -243,19 +243,12 @@ bool Packaging::WriteTarEntry(const QString& filename, QTemporaryFile *tarFile, QFileInfo qtFileInfo(file); QByteArray utfFilename; - if (firmwareXml) - { - utfFilename = QString("firmware.xml").toUtf8(); - } - else - { - utfFilename = qtFileInfo.fileName().toUtf8(); + utfFilename = entryFilename.toUtf8(); - if (utfFilename.length() > 100) - { - Alerts::DisplayError(QString("File name is too long:\n%1").arg(qtFileInfo.fileName())); - return (false); - } + if (utfFilename.length() > 100) + { + Alerts::DisplayError(QString("File name is too long:\n%1").arg(qtFileInfo.fileName())); + return (false); } strcpy(tarHeader.fields.name, utfFilename.constData()); @@ -388,7 +381,15 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarF for (int i = 0; i < fileInfos.length(); i++) { - if (!WriteTarEntry(fileInfos[i].GetFilename(), tarFile)) + QString filename = ClashlessFilename(fileInfos, i); + + if (filename == "firmware.xml") + { + Alerts::DisplayError("You cannot name your partition files \"firmware.xml\".\nIt is a reserved name."); + return (false); + } + + if (!WriteTarEntry(fileInfos[i].GetFilename(), tarFile, ClashlessFilename(fileInfos, i))) { tarFile->resize(0); tarFile->close(); @@ -411,7 +412,20 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarF } } - if (!WriteTarEntry(firmwareInfo.GetPitFilename(), tarFile)) + int lastSlash = firmwareInfo.GetPitFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = firmwareInfo.GetPitFilename().lastIndexOf('\\'); + + QString pitFilename = ClashlessFilename(fileInfos, firmwareInfo.GetPitFilename().mid(lastSlash + 1)); + + if (pitFilename == "firmware.xml") + { + Alerts::DisplayError("You cannot name your PIT file \"firmware.xml\".\nIt is a reserved name."); + return (false); + } + + if (!WriteTarEntry(firmwareInfo.GetPitFilename(), tarFile, pitFilename)) { tarFile->resize(0); tarFile->close(); @@ -431,7 +445,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarF return (false); } - if (!WriteTarEntry(firmwareXmlFile.fileName(), tarFile, true)) + if (!WriteTarEntry(firmwareXmlFile.fileName(), tarFile, "firmware.xml")) { tarFile->resize(0); tarFile->close(); @@ -558,7 +572,12 @@ bool Packaging::BuildPackage(const QString& packagePath, const FirmwareInfo& fir QTemporaryFile tar("XXXXXX.tar"); if (!CreateTar(firmwareInfo, &tar)) + { + fclose(compressedPackageFile); + remove(packagePath.toStdString().c_str()); + return (false); + } if (!tar.open()) { @@ -626,3 +645,271 @@ bool Packaging::BuildPackage(const QString& packagePath, const FirmwareInfo& fir return (true); } + +QString Packaging::ClashlessFilename(const QList& fileInfos, int fileInfoIndex) +{ + int lastSlash = fileInfos[fileInfoIndex].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[fileInfoIndex].GetFilename().lastIndexOf('\\'); + + QString filename = fileInfos[fileInfoIndex].GetFilename().mid(lastSlash + 1); + unsigned int renameIndex = 0; + + // Check for name clashes + for (int i = 0; i < fileInfoIndex; i++) + { + lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1); + + if (filename == otherFilename) + renameIndex++; + } + + if (renameIndex > 0) + { + int lastPeriodIndex = filename.lastIndexOf(QChar('.')); + QString shortFilename; + QString fileType; + + if (lastPeriodIndex >= 0) + { + shortFilename = filename.left(lastPeriodIndex); + fileType = filename.mid(lastPeriodIndex); + } + else + { + shortFilename = filename; + } + + unsigned int renameIndexOffset = 0; + bool validIndexOffset = true; + + // Before we append a rename index we must ensure it doesn't produce further collisions. + for (int i = 0; i < fileInfos.length(); i++) + { + int lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1); + + if (otherFilename.length() > filename.length() + 1) + { + QString trimmedOtherFilename = otherFilename.left(shortFilename.length()); + + if (shortFilename == trimmedOtherFilename) + { + lastPeriodIndex = otherFilename.lastIndexOf(QChar('.')); + QString shortOtherFilename; + + if (lastPeriodIndex >= 0) + shortOtherFilename = otherFilename.left(lastPeriodIndex); + else + shortOtherFilename = otherFilename; + + QRegExp renameExp("-[0-9]+"); + + if (renameExp.lastIndexIn(shortOtherFilename) == shortFilename.length()) + { + unsigned int trailingInteger = shortOtherFilename.mid(shortFilename.length() + 1).toUInt(&validIndexOffset); + + if (!validIndexOffset) + break; + + if (trailingInteger > renameIndexOffset) + renameIndexOffset = trailingInteger; + } + } + } + } + + if (validIndexOffset) + { + // Ensure renaming won't involve integer overflow! + if (renameIndex > static_cast(-1) - renameIndexOffset) + validIndexOffset = false; + } + + if (validIndexOffset) + { + shortFilename.append(QChar('-')); + shortFilename.append(QString::number(renameIndexOffset + renameIndex)); + + return (shortFilename + fileType); + } + else + { + // Fallback behaviour... an absolutely terrible brute force implementation! + QString filename; + QString renamePrefix; + + for (;;) + { + renamePrefix.append(QChar('+')); + + for (unsigned int i = 0; i < static_cast(-1); i++) + { + filename = shortFilename + renamePrefix + QString::number(i) + fileType; + + bool valid = true; + + for (int i = 0; i < fileInfos.length(); i++) + { + int lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + if (filename == fileInfos[i].GetFilename().mid(lastSlash + 1)) + { + valid = false; + break; + } + } + + if (valid) + return (filename); + } + } + } + } + else + { + return (filename); + } +} + +QString Packaging::ClashlessFilename(const QList& fileInfos, const QString& filename) +{ + unsigned int renameIndex = 0; + + // Check for name clashes + for (int i = 0; i < fileInfos.length(); i++) + { + int lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1); + + if (filename == otherFilename) + renameIndex++; + } + + if (renameIndex > 0) + { + int lastPeriodIndex = filename.lastIndexOf(QChar('.')); + QString shortFilename; + QString fileType; + + if (lastPeriodIndex >= 0) + { + shortFilename = filename.left(lastPeriodIndex); + fileType = filename.mid(lastPeriodIndex); + } + else + { + shortFilename = filename; + } + + unsigned int renameIndexOffset = 0; + bool validIndexOffset = true; + + // Before we append a rename index we must ensure it doesn't produce further collisions. + for (int i = 0; i < fileInfos.length(); i++) + { + int lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1); + + if (otherFilename.length() > filename.length() + 1) + { + QString trimmedOtherFilename = otherFilename.left(filename.length()); + + if (filename == trimmedOtherFilename) + { + lastPeriodIndex = otherFilename.lastIndexOf(QChar('.')); + QString shortOtherFilename; + + if (lastPeriodIndex >= 0) + shortOtherFilename = otherFilename.left(lastPeriodIndex); + else + shortOtherFilename = otherFilename; + + QRegExp renameExp("-[0-9]+"); + + if (renameExp.lastIndexIn(shortOtherFilename) == shortFilename.length()) + { + unsigned int trailingInteger = shortOtherFilename.mid(shortFilename.length() + 1).toUInt(&validIndexOffset); + + if (!validIndexOffset) + break; + + if (trailingInteger > renameIndexOffset) + renameIndexOffset = trailingInteger; + } + } + } + } + + if (validIndexOffset) + { + // Ensure renaming won't involve integer overflow! + if (renameIndex > static_cast(-1) - renameIndexOffset) + validIndexOffset = false; + } + + if (validIndexOffset) + { + shortFilename.append(QChar('-')); + shortFilename.append(QString::number(renameIndexOffset + renameIndex)); + + return (shortFilename + fileType); + } + else + { + // Fallback behaviour, brute-force/semi-random. + bool valid; + QString filename; + + do + { + valid = true; + + filename = shortFilename + "-"; + for (int i = 0; i < 8; i++) + filename.append(QChar(qrand() % ('Z' - 'A' + 1) + 'A')); + + for (int i = 0; i < fileInfos.length(); i++) + { + int lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + + if (lastSlash < 0) + lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + + if (filename == fileInfos[i].GetFilename().mid(lastSlash + 1)) + { + valid = false; + break; + } + } + } while (!valid); + + return (filename); + } + } + else + { + return (filename); + } +} diff --git a/heimdall-frontend/Source/Packaging.h b/heimdall-frontend/Source/Packaging.h index 402f786..b6bac8d 100644 --- a/heimdall-frontend/Source/Packaging.h +++ b/heimdall-frontend/Source/Packaging.h @@ -103,7 +103,7 @@ namespace HeimdallFrontend // TODO: Add support for sparse files to both methods? static bool ExtractTar(QTemporaryFile& tarFile, PackageData *packageData); - static bool WriteTarEntry(const QString& filename, QTemporaryFile *tarFile, bool firmwareXml = false); + static bool WriteTarEntry(const QString& filePath, QTemporaryFile *tarFile, const QString& entryFilename); static bool CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarFile); // Uses original TAR format. public: @@ -112,6 +112,9 @@ namespace HeimdallFrontend static bool ExtractPackage(const QString& packagePath, PackageData *packageData); static bool BuildPackage(const QString& packagePath, const FirmwareInfo& firmwareInfo); + + static QString ClashlessFilename(const QList& fileInfos, int fileInfoIndex); + static QString ClashlessFilename(const QList& fileInfos, const QString& filename); }; } diff --git a/heimdall-frontend/heimdall-frontend.vcxproj b/heimdall-frontend/heimdall-frontend.vcxproj index 87be4e2..365e6e3 100644 --- a/heimdall-frontend/heimdall-frontend.vcxproj +++ b/heimdall-frontend/heimdall-frontend.vcxproj @@ -37,6 +37,9 @@ + + + <_ProjectFileVersion>10.0.30319.1 @@ -100,7 +103,6 @@ true - true @@ -110,7 +112,6 @@ true - true diff --git a/heimdall-frontend/mainwindow.ui b/heimdall-frontend/mainwindow.ui index 985fe10..984f4ba 100644 --- a/heimdall-frontend/mainwindow.ui +++ b/heimdall-frontend/mainwindow.ui @@ -130,9 +130,9 @@ - 350 + 340 80 - 151 + 161 61 @@ -147,7 +147,7 @@ 10 30 - 131 + 141 21 @@ -216,7 +216,7 @@ 10 80 - 221 + 211 61 @@ -231,7 +231,7 @@ 10 30 - 201 + 191 21 @@ -288,7 +288,7 @@ - 240 + 230 80 101 61 @@ -643,9 +643,9 @@ - 120 + 140 30 - 261 + 241 22 @@ -655,7 +655,7 @@ 10 30 - 101 + 121 16 @@ -668,7 +668,7 @@ 10 60 - 101 + 121 16 @@ -727,9 +727,9 @@ - 120 + 140 60 - 261 + 241 21 @@ -885,7 +885,7 @@ 0 230 - 491 + 471 231 @@ -897,7 +897,7 @@ 10 30 - 471 + 451 161 @@ -908,9 +908,9 @@ - 350 + 320 200 - 131 + 141 23 @@ -1024,9 +1024,9 @@ - 550 + 560 20 - 191 + 181 81 @@ -1034,7 +1034,7 @@ - 300 + 310 20 241 101 @@ -1048,7 +1048,7 @@ 10 30 - 41 + 51 16 @@ -1062,9 +1062,9 @@ - 60 + 70 30 - 171 + 161 21 @@ -1110,7 +1110,7 @@ 10 20 - 281 + 291 101 @@ -1122,7 +1122,7 @@ 10 60 - 71 + 81 16 @@ -1135,7 +1135,7 @@ 10 30 - 71 + 81 16 @@ -1149,7 +1149,7 @@ - 90 + 100 30 181 21 @@ -1165,7 +1165,7 @@ - 90 + 100 60 181 21 @@ -1209,9 +1209,9 @@ - 500 + 480 240 - 271 + 291 151 @@ -1223,7 +1223,7 @@ 10 60 - 91 + 111 16 @@ -1237,7 +1237,7 @@ - 110 + 130 60 151 21 @@ -1252,7 +1252,7 @@ 10 30 - 91 + 111 16 @@ -1266,7 +1266,7 @@ - 110 + 130 30 151 21 @@ -1281,7 +1281,7 @@ 10 90 - 91 + 111 16 @@ -1295,7 +1295,7 @@ - 110 + 130 90 151 21 @@ -1311,9 +1311,9 @@ - 150 + 160 120 - 111 + 121 23 -- cgit v1.1