From 197c24c5d331703b8b1d743f5699263cd623df38 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Sun, 28 Sep 2008 17:02:36 +0000 Subject: Completely rework the bootloader installation class: - create a base class and make derived classes for each installation type. - sort installations by type, not by player model. - remove duplicated code for iriver (de)scrambling functionality and use the functions inside of the tools folder directly -- we already do the same for rbspeex. - make bootloader file backup optional and allow choosing a target location. - clean up some wording and add some more guiding messages. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18657 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/rbutilqt/autodetection.cpp | 19 +- rbutil/rbutilqt/bootloaderinstallbase.cpp | 184 ++++ rbutil/rbutilqt/bootloaderinstallbase.h | 90 ++ rbutil/rbutilqt/bootloaderinstallfile.cpp | 145 +++ rbutil/rbutilqt/bootloaderinstallfile.h | 44 + rbutil/rbutilqt/bootloaderinstallhex.cpp | 244 +++++ rbutil/rbutilqt/bootloaderinstallhex.h | 57 ++ rbutil/rbutilqt/bootloaderinstallipod.cpp | 235 +++++ rbutil/rbutilqt/bootloaderinstallipod.h | 50 + rbutil/rbutilqt/bootloaderinstallmi4.cpp | 140 +++ rbutil/rbutilqt/bootloaderinstallmi4.h | 44 + rbutil/rbutilqt/bootloaderinstallsansa.cpp | 244 +++++ rbutil/rbutilqt/bootloaderinstallsansa.h | 48 + rbutil/rbutilqt/browseof.cpp | 68 -- rbutil/rbutilqt/browseof.h | 48 - rbutil/rbutilqt/browseoffrm.ui | 112 --- rbutil/rbutilqt/install.h | 4 +- rbutil/rbutilqt/installbootloader.cpp | 1449 --------------------------- rbutil/rbutilqt/installbootloader.h | 127 --- rbutil/rbutilqt/irivertools/checksums.h | 41 - rbutil/rbutilqt/irivertools/irivertools.cpp | 527 ---------- rbutil/rbutilqt/irivertools/irivertools.h | 55 - rbutil/rbutilqt/irivertools/md5sum.cpp | 295 ------ rbutil/rbutilqt/irivertools/md5sum.h | 52 - rbutil/rbutilqt/rbsettings.cpp | 6 + rbutil/rbutilqt/rbsettings.h | 1 + rbutil/rbutilqt/rbutil.ini | 104 +- rbutil/rbutilqt/rbutilqt.cpp | 279 ++++-- rbutil/rbutilqt/rbutilqt.h | 9 +- rbutil/rbutilqt/rbutilqt.pro | 38 +- 30 files changed, 1838 insertions(+), 2921 deletions(-) create mode 100644 rbutil/rbutilqt/bootloaderinstallbase.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallbase.h create mode 100644 rbutil/rbutilqt/bootloaderinstallfile.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallfile.h create mode 100644 rbutil/rbutilqt/bootloaderinstallhex.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallhex.h create mode 100644 rbutil/rbutilqt/bootloaderinstallipod.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallipod.h create mode 100644 rbutil/rbutilqt/bootloaderinstallmi4.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallmi4.h create mode 100644 rbutil/rbutilqt/bootloaderinstallsansa.cpp create mode 100644 rbutil/rbutilqt/bootloaderinstallsansa.h delete mode 100644 rbutil/rbutilqt/browseof.cpp delete mode 100644 rbutil/rbutilqt/browseof.h delete mode 100644 rbutil/rbutilqt/browseoffrm.ui delete mode 100644 rbutil/rbutilqt/installbootloader.cpp delete mode 100644 rbutil/rbutilqt/installbootloader.h delete mode 100644 rbutil/rbutilqt/irivertools/checksums.h delete mode 100644 rbutil/rbutilqt/irivertools/irivertools.cpp delete mode 100644 rbutil/rbutilqt/irivertools/irivertools.h delete mode 100644 rbutil/rbutilqt/irivertools/md5sum.cpp delete mode 100644 rbutil/rbutilqt/irivertools/md5sum.h diff --git a/rbutil/rbutilqt/autodetection.cpp b/rbutil/rbutilqt/autodetection.cpp index 7399907f15..7c830b17c2 100644 --- a/rbutil/rbutilqt/autodetection.cpp +++ b/rbutil/rbutilqt/autodetection.cpp @@ -64,9 +64,9 @@ bool Autodetection::detect() { // do the file checking QDir dir(mountpoints.at(i)); + qDebug() << "paths to check for player specific files:" << mountpoints; if(dir.exists()) { - qDebug() << "file checking:" << mountpoints.at(i); // check logfile first. if(QFile(mountpoints.at(i) + "/.rockbox/rbutil.log").exists()) { QSettings log(mountpoints.at(i) + "/.rockbox/rbutil.log", @@ -153,7 +153,10 @@ bool Autodetection::detect() } int n; - //try ipodpatcher + // try ipodpatcher + // initialize sector buffer. Needed. + ipod_sectorbuf = NULL; + ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE); struct ipod_t ipod; n = ipod_scan(&ipod); if(n == 1) { @@ -165,8 +168,13 @@ bool Autodetection::detect() else { qDebug() << "ipodpatcher: no Ipod found." << n; } + free(ipod_sectorbuf); + ipod_sectorbuf = NULL; - //try sansapatcher + // try sansapatcher + // initialize sector buffer. Needed. + sansa_sectorbuf = NULL; + sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE); struct sansa_t sansa; n = sansa_scan(&sansa); if(n == 1) { @@ -178,6 +186,8 @@ bool Autodetection::detect() else { qDebug() << "sansapatcher: no Sansa found." << n; } + free(sansa_sectorbuf); + sansa_sectorbuf = NULL; if(m_mountpoint.isEmpty() && m_device.isEmpty() && m_errdev.isEmpty() && m_incompat.isEmpty()) return false; @@ -288,7 +298,8 @@ QString Autodetection::resolveMountPoint(QString device) } } - return result + ":/"; + if(!result.isEmpty()) + return result + ":/"; #endif return QString(""); } diff --git a/rbutil/rbutilqt/bootloaderinstallbase.cpp b/rbutil/rbutilqt/bootloaderinstallbase.cpp new file mode 100644 index 0000000000..0af30c4e93 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallbase.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include + +#include "bootloaderinstallbase.h" +#include "utils.h" + +BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void) +{ + return BootloaderUnknown; +} + + +BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void) +{ + return 0; +} + + +void BootloaderInstallBase::downloadBlStart(QUrl source) +{ + m_http.setFile(&m_tempfile); + m_http.setCache(true); + connect(&m_http, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool))); + // connect the http read signal to our logProgess *signal* + // to immediately emit it without any helper function. + connect(&m_http, SIGNAL(dataReadProgress(int, int)), + this, SIGNAL(logProgress(int, int))); + m_http.getFile(source); +} + + +void BootloaderInstallBase::downloadReqFinished(int id, bool error) +{ + qDebug() << __FILE__ << "::" << __func__ << id << error; + qDebug() << "error:" << m_http.errorString(); + + downloadBlFinish(error); +} + + +void BootloaderInstallBase::downloadBlFinish(bool error) +{ + qDebug() << __FILE__ << "::" << __func__ << ": error =" << error; + + // update progress bar + emit logProgress(100, 100); + + if(m_http.httpResponse() != 200) { + emit logItem(tr("Download error: received HTTP error %1.") + .arg(m_http.errorString()), LOGERROR); + emit done(true); + return; + } + if(error) { + emit logItem(tr("Download error: %1") + .arg(m_http.error()), LOGERROR); + emit done(true); + return; + } + else if(m_http.isCached()) + emit logItem(tr("Download finished (cache used)."), LOGOK); + else + emit logItem(tr("Download finished."), LOGOK); + + m_blversion = m_http.timestamp(); + emit downloadDone(); +} + +void BootloaderInstallBase::installBlfile(void) +{ + qDebug() << __FILE__ << __func__; +} + + +//! @brief backup OF file. +//! @param to folder to write backup file to. Folder will get created. +//! @return true on success, false on error. + +bool BootloaderInstallBase::backup(QString to) +{ + qDebug() << __func__; + QDir targetDir("."); + emit logItem(tr("Creating backup of original firmware file."), LOGINFO); + if(!targetDir.mkpath(to)) { + emit logItem(tr("Creating backup folder failed"), LOGERROR); + return false; + } + QString tofile = to + "/" + QFileInfo(m_blfile).fileName(); + qDebug() << "trying to backup" << m_blfile << "to" << tofile; + if(!QFile::copy(resolvePathCase(m_blfile), tofile)) { + emit logItem(tr("Creating backup copy failed."), LOGERROR); + return false; + } + emit logItem(tr("Backup created."), LOGOK); + return true; +} + + +//! @brief log installation to logfile. +//! @param mode action to perform. 0: add to log, 1: remove from log. +//! @return 0 on success +int BootloaderInstallBase::logInstall(LogMode mode) +{ + int result = 0; + QString section = m_blurl.path().section('/', -1); + QSettings s(m_logfile, QSettings::IniFormat, this); + emit logItem(tr("Creating installation log"), LOGINFO); + + if(mode == LogAdd) { + s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate)); + qDebug() << m_blversion.toString(Qt::ISODate); + } + else { + s.remove("Bootloader/" + section); + } + s.sync(); + + return result; +} + + +//! @brief Return post install hints string. +//! @param model model string +//! @return hints. +QString BootloaderInstallBase::postinstallHints(QString model) +{ + bool hint = false; + QString msg = tr("Bootloader installation is almost complete. " + "Installation requires you to perform the " + "following steps manually:"); + + msg += tr("
    "); + msg += tr("
  1. Safely remove your player.
  2. "); + if(model == "h100" || model == "h120" || model == "h300") { + hint = true; + msg += tr("
  3. Reboot your player into the original firmware.
  4. " + "
  5. Perform a firmware upgrade using the update functionality " + "of the original firmware. Please refer to your player's manual " + "on details.
  6. " + "
  7. After the firmware has been updated reboot your player.
  8. "); + } + if(model == "iaudiox5" || model == "iaudiom5" + || model == "iaudiox5v" || model == "iaudiom3") { + hint = true; + msg += tr("
  9. Turn the player off
  10. " + "
  11. Insert the charger
  12. "); + } + if(model == "gigabeatf") { + hint = true; + msg += tr("
  13. Unplug USB and power adaptors
  14. " + "
  15. Hold Power to turn the player off
  16. " + "
  17. Toggle the battery switch on the player
  18. " + "
  19. Hold Power to boot into Rockbox
  20. "); + } + + msg += "
"; + msg += tr("

Note: You can safely install other parts first, but " + "the above steps are required to finish the installation!

"); + + if(hint) + return msg; + else + return QString(""); +} + diff --git a/rbutil/rbutilqt/bootloaderinstallbase.h b/rbutil/rbutilqt/bootloaderinstallbase.h new file mode 100644 index 0000000000..4f0d279229 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallbase.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef BOOTLOADERINSTALLBASE_H +#define BOOTLOADERINSTALLBASE_H + +#include +#include "progressloggerinterface.h" +#include "httpget.h" + + +class BootloaderInstallBase : public QObject +{ + Q_OBJECT + + public: + enum Capability + { Install = 0x01, Uninstall = 0x02, Backup = 0x04, + IsFile = 0x08, IsRaw = 0x10, NeedsFlashing = 0x20, + CanCheckInstalled = 0x40, CanCheckVersion = 0x80 }; + Q_DECLARE_FLAGS(Capabilities, Capability) + + enum BootloaderType + { BootloaderNone, BootloaderRockbox, BootloaderOther, BootloaderUnknown }; + + BootloaderInstallBase(QObject *parent = 0) : QObject(parent) + { } + + virtual bool install(void) + { return false; } + virtual bool uninstall(void) + { return false; } + virtual BootloaderType installed(void); + virtual Capabilities capabilities(void); + bool backup(QString to); + + void setBlFile(QString f) + { m_blfile = f; } + void setBlUrl(QUrl u) + { m_blurl = u; } + void setLogfile(QString f) + { m_logfile = f; } + + static QString postinstallHints(QString model); + + protected slots: + void downloadReqFinished(int id, bool error); + void downloadBlFinish(bool error); + void installBlfile(void); + protected: + enum LogMode + { LogAdd, LogRemove }; + + void downloadBlStart(QUrl source); + int logInstall(LogMode mode); + + HttpGet m_http; //! http download object + QString m_blfile; //! bootloader filename on player + QString m_logfile; //! file for installation log + QUrl m_blurl; //! bootloader download URL + QTemporaryFile m_tempfile; //! temporary file for download + QDateTime m_blversion; //! download timestamp used for version information + + signals: + void downloadDone(void); //! internal signal sent when download finished. + void done(bool); + void logItem(QString, int); //! set logger item + void logProgress(int, int); //! set progress bar. +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(BootloaderInstallBase::Capabilities) + +#endif + diff --git a/rbutil/rbutilqt/bootloaderinstallfile.cpp b/rbutil/rbutilqt/bootloaderinstallfile.cpp new file mode 100644 index 0000000000..7e4d6e81ea --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallfile.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "bootloaderinstallfile.h" +#include "utils.h" + + +BootloaderInstallFile::BootloaderInstallFile(QObject *parent) + : BootloaderInstallBase(parent) +{ +} + + +bool BootloaderInstallFile::install(void) +{ + emit logItem(tr("Downloading bootloader"), LOGINFO); + qDebug() << __func__; + downloadBlStart(m_blurl); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + return true; +} + +void BootloaderInstallFile::installStage2(void) +{ + emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); + + // if an old bootloader is present (Gigabeat) move it out of the way. + QString fwfile(resolvePathCase(m_blfile)); + if(!fwfile.isEmpty()) { + QString moved = resolvePathCase(m_blfile) + ".ORIG"; + qDebug() << "renaming" << fwfile << "->" << moved; + QFile::rename(fwfile, moved); + } + + // if no old file found resolve path without basename + QFileInfo fi(m_blfile); + QString absPath = resolvePathCase(fi.absolutePath()); + + // if it's not possible to locate the base path try to create it + if(absPath.isEmpty()) { + QStringList pathElements = m_blfile.split("/"); + // remove filename from list and save last path element + pathElements.removeLast(); + QString lastElement = pathElements.last(); + // remove last path element for base + pathElements.removeLast(); + QString basePath = pathElements.join("/"); + + // check for base and bail out if not found. Otherwise create folder. + absPath = resolvePathCase(basePath); + QDir d(absPath); + d.mkpath(lastElement); + absPath = resolvePathCase(fi.absolutePath()); + + if(absPath.isEmpty()) { + emit logItem(tr("Error accessing output folder"), LOGERROR); + emit done(true); + return; + } + } + fwfile = absPath + "/" + fi.fileName(); + + // place (new) bootloader + m_tempfile.open(); + qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile; + m_tempfile.close(); + m_tempfile.rename(fwfile); + + emit logItem(tr("Bootloader successful installed"), LOGOK); + logInstall(LogAdd); + + emit done(false); +} + + +bool BootloaderInstallFile::uninstall(void) +{ + qDebug() << __func__; + emit logItem(tr("Removing Rockbox bootloader"), LOGINFO); + // check if a .ORIG file is present, and allow moving it back. + QString origbl = resolvePathCase(m_blfile + ".ORIG"); + if(origbl.isEmpty()) { + emit logItem(tr("No original firmware file found."), LOGERROR); + emit done(true); + return false; + } + QString fwfile = resolvePathCase(m_blfile); + if(!QFile::remove(fwfile)) { + emit logItem(tr("Can't remove Rockbox bootloader file."), LOGERROR); + emit done(true); + return false; + } + if(!QFile::rename(origbl, fwfile)) { + emit logItem(tr("Can't restore bootloader file."), LOGERROR); + emit done(true); + return false; + } + emit logItem(tr("Original bootloader restored successfully."), LOGOK); + logInstall(LogRemove); + emit done(false); + + return true; +} + + +//! @brief check if bootloader is installed. +//! @return BootloaderRockbox, BootloaderOther or BootloaderUnknown. +BootloaderInstallBase::BootloaderType BootloaderInstallFile::installed(void) +{ + qDebug("%s()", __func__); + if(!resolvePathCase(m_blfile).isEmpty() + && !resolvePathCase(m_blfile + ".ORIG").isEmpty()) + return BootloaderRockbox; + else if(!resolvePathCase(m_blfile).isEmpty()) + return BootloaderOther; + else + return BootloaderUnknown; +} + + +BootloaderInstallBase::Capabilities BootloaderInstallFile::capabilities(void) +{ + qDebug() << __func__; + return Install | IsFile | CanCheckInstalled | Backup; +} + diff --git a/rbutil/rbutilqt/bootloaderinstallfile.h b/rbutil/rbutilqt/bootloaderinstallfile.h new file mode 100644 index 0000000000..6ffc03b037 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallfile.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "progressloggerinterface.h" +#include "bootloaderinstallbase.h" + +//! install a bootloader by putting a single file on the player. +// This installation method is used by Iaudio (firmware is flashed +// automatically) and Gigabeat (Firmware is a file, OF needs to get +// renamed). +class BootloaderInstallFile : public BootloaderInstallBase +{ + Q_OBJECT + + public: + BootloaderInstallFile(QObject *parent = 0); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + + private slots: + void installStage2(void); + + private: +}; + diff --git a/rbutil/rbutilqt/bootloaderinstallhex.cpp b/rbutil/rbutilqt/bootloaderinstallhex.cpp new file mode 100644 index 0000000000..e4cc4cc08a --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallhex.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "bootloaderinstallbase.h" +#include "bootloaderinstallhex.h" + +#include "../../tools/iriver.h" +#include "../../tools/mkboot.h" + +struct md5s { + const char* orig; + const char* patched; +}; + +struct md5s md5sums[] = { +#include "irivertools/h100sums.h" + { 0, 0 }, +#include "irivertools/h120sums.h" + { 0, 0 }, +#include "irivertools/h300sums.h" + { 0, 0 } +}; + + +BootloaderInstallHex::BootloaderInstallHex(QObject *parent) + : BootloaderInstallBase(parent) +{ +} + + +bool BootloaderInstallHex::install(void) +{ + if(m_hex.isEmpty()) + return false; + m_hashindex = -1; + + // md5sum hex file + emit logItem(tr("checking MD5 hash of input file ..."), LOGINFO); + QByteArray filedata; + // read hex file into QByteArray + QFile file(m_hex); + file.open(QIODevice::ReadOnly); + filedata = file.readAll(); + file.close(); + QString hash = QCryptographicHash::hash(filedata, + QCryptographicHash::Md5).toHex(); + qDebug() << "hexfile hash:" << hash; + if(file.error() != QFile::NoError) { + emit logItem(tr("Could not verify original firmware file"), LOGERROR); + emit done(true); + return false; + } + // check hash and figure model from md5sum + int i = sizeof(md5sums) / sizeof(struct md5s); + m_model = 4; + // 3: h300, 2: h120, 1: h100, 0:invalid + while(i--) { + if(md5sums[i].orig == 0) + m_model--; + if(!qstrcmp(md5sums[i].orig, hash.toAscii())) + break; + } + if(i < 0) { + emit logItem(tr("Firmware file not recognized."), LOGERROR); + return false; + } + else { + emit logItem(tr("MD5 hash ok"), LOGOK); + m_hashindex = i; + } + + // check model agains download link. + QString match[] = {"", "h100", "h120", "h300"}; + if(!m_blurl.path().contains(match[m_model])) { + emit logItem(tr("Firmware file doesn't match selected player."), + LOGERROR); + return false; + } + + emit logItem(tr("Descrambling file"), LOGINFO); + m_descrambled.open(); + int result; + result = iriver_decode(m_hex.toAscii().data(), + m_descrambled.fileName().toAscii().data(), FALSE, STRIP_NONE); + qDebug() << "iriver_decode" << result; + + if(result < 0) { + emit logItem(tr("Error in descramble: %1").arg(scrambleError(result)), LOGERROR); + return false; + } + + // download firmware from server + emit logItem(tr("Downloading bootloader file"), LOGINFO); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + + downloadBlStart(m_blurl); + return true; +} + + +void BootloaderInstallHex::installStage2(void) +{ + emit logItem(tr("Adding bootloader to firmware file"), LOGINFO); + + // local temp file + QTemporaryFile tempbin; + tempbin.open(); + QString tempbinName = tempbin.fileName(); + tempbin.close(); + // get temporary files filenames -- external tools need this. + m_descrambled.open(); + QString descrambledName = m_descrambled.fileName(); + m_descrambled.close(); + m_tempfile.open(); + QString tempfileName = m_tempfile.fileName(); + m_tempfile.close(); + + int origin = 0; + switch(m_model) { + case 3: + origin = 0x3f0000; + break; + case 2: + case 1: + origin = 0x1f0000; + break; + default: + origin = 0; + break; + } + + // iriver decode already done in stage 1 + int result; + if((result = mkboot(descrambledName.toLocal8Bit().constData(), + tempfileName.toLocal8Bit().constData(), + tempbinName.toLocal8Bit().constData(), origin)) < 0) + { + QString error; + switch(result) { + case -1: error = tr("could not open input file"); break; + case -2: error = tr("reading header failed"); break; + case -3: error = tr("reading firmware failed"); break; + case -4: error = tr("can't open bootloader file"); break; + case -5: error = tr("reading bootloader file failed"); break; + case -6: error = tr("can't open output file"); break; + case -7: error = tr("writing output file failed"); break; + } + emit logItem(tr("Error in patching: %1").arg(error), LOGERROR); + + emit done(true); + return; + } + QTemporaryFile targethex; + targethex.open(); + QString targethexName = targethex.fileName(); + if((result = iriver_encode(tempbinName.toLocal8Bit().constData(), + targethexName.toLocal8Bit().constData(), FALSE)) < 0) + { + emit logItem(tr("Error in scramble: %1").arg(scrambleError(result)), LOGERROR); + targethex.close(); + + emit done(true); + return; + } + + // finally check the md5sum of the created file + QByteArray filedata; + filedata = targethex.readAll(); + targethex.close(); + QString hash = QCryptographicHash::hash(filedata, + QCryptographicHash::Md5).toHex(); + qDebug() << "created hexfile hash:" << hash; + + emit logItem(tr("Checking modified firmware file"), LOGINFO); + if(hash != QString(md5sums[m_hashindex].patched)) { + emit logItem(tr("Error: modified file checksum wrong"), LOGERROR); + targethex.remove(); + emit done(true); + return; + } + // finally copy file to player + targethex.copy(m_blfile); + + emit logItem(tr("Success: modified firmware file created"), LOGINFO); + logInstall(LogAdd); + emit done(false); + + return; +} + + +bool BootloaderInstallHex::uninstall(void) +{ + emit logItem("Uninstallation not possible, only installation info removed", LOGINFO); + logInstall(LogRemove); + return false; +} + + +BootloaderInstallBase::BootloaderType BootloaderInstallHex::installed(void) +{ + return BootloaderUnknown; +} + + +BootloaderInstallBase::Capabilities BootloaderInstallHex::capabilities(void) +{ + return (Install | NeedsFlashing); +} + +QString BootloaderInstallHex::scrambleError(int err) +{ + QString error; + switch(err) { + case -1: error = tr("Can't open input file"); break; + case -2: error = tr("Can't open output file"); break; + case -3: error = tr("invalid file: header length wrong"); break; + case -4: error = tr("invalid file: unrecognized header"); break; + case -5: error = tr("invalid file: \"length\" field wrong"); break; + case -6: error = tr("invalid file: \"length2\" field wrong"); break; + case -7: error = tr("invalid file: internal checksum error"); break; + case -8: error = tr("invalid file: \"length3\" field wrong"); break; + default: error = tr("unknown"); break; + } + return error; +} + diff --git a/rbutil/rbutilqt/bootloaderinstallhex.h b/rbutil/rbutilqt/bootloaderinstallhex.h new file mode 100644 index 0000000000..2fa5246c7f --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallhex.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef BOOTLOADERINSTALLHEX_H +#define BOOTLOADERINSTALLHEX_H + +#include +#include "bootloaderinstallbase.h" + + +// bootloader installation derivate based on fwpatcher +// This will patch a given hex file using (de)scramble / mkboot +// and put it on the player. +class BootloaderInstallHex : public BootloaderInstallBase +{ + Q_OBJECT + + public: + BootloaderInstallHex(QObject *parent = 0); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + + void setHexfile(QString h) + { m_hex = h; } + + private: + QString m_hex; + int m_hashindex; + int m_model; + QTemporaryFile m_descrambled; + QString scrambleError(int); + + private slots: + void installStage2(void); +}; + + +#endif + diff --git a/rbutil/rbutilqt/bootloaderinstallipod.cpp b/rbutil/rbutilqt/bootloaderinstallipod.cpp new file mode 100644 index 0000000000..211b864b06 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallipod.cpp @@ -0,0 +1,235 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "bootloaderinstallbase.h" +#include "bootloaderinstallipod.h" + +#include "../ipodpatcher/ipodpatcher.h" + + +BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent) + : BootloaderInstallBase(parent) +{ + (void)parent; + // initialize sector buffer. ipod_sectorbuf is defined in ipodpatcher. + ipod_sectorbuf = NULL; + ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE); +} + + +BootloaderInstallIpod::~BootloaderInstallIpod() +{ + free(ipod_sectorbuf); +} + + +bool BootloaderInstallIpod::install(void) +{ + if(ipod_sectorbuf == NULL) { + emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); + emit done(true); + return false; + } + + struct ipod_t ipod; + + int n = ipod_scan(&ipod); + if(n == -1) { + emit logItem(tr("No Ipod detected\n" + "Permission for disc access denied!"), + LOGERROR); + emit done(true); + return false; + } + if(n == 0) { + emit logItem(tr("No Ipod detected!"), LOGERROR); + emit done(true); + return false; + } + + if(ipod.macpod) { + emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods.\n" + "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR); + emit done(true); + return false; + } + emit logItem(tr("Downloading bootloader file"), LOGINFO); + + downloadBlStart(m_blurl); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + return true; +} + + +void BootloaderInstallIpod::installStage2(void) +{ + struct ipod_t ipod; + + if(!ipodInitialize(&ipod)) { + emit done(true); + return; + } + + read_directory(&ipod); + + if(ipod.nimages <= 0) { + emit logItem(tr("Failed to read firmware directory"), LOGERROR); + emit done(true); + return; + } + if(getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) { + emit logItem(tr("Unknown version number in firmware (%1)").arg( + ipod.ipod_directory[0].vers), LOGERROR); + emit done(true); + return; + } + + if(ipod.macpod) { + emit logItem(tr("Warning: This is a MacPod. Rockbox only runs on WinPods.\n" + "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR); + emit done(true); + return; + } + + if(ipod_reopen_rw(&ipod) < 0) { + emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR); + emit done(true); + return; + } + + m_tempfile.open(); + QString blfile = m_tempfile.fileName(); + m_tempfile.close(); + if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) { + emit logItem(tr("Successfull added bootloader"), LOGOK); + logInstall(LogAdd); + emit done(false); + ipod_close(&ipod); + return; + } + else { + emit logItem(tr("Failed to add bootloader"), LOGERROR); + ipod_close(&ipod); + emit done(true); + return; + } + qDebug() << "version installed:" << m_blversion.toString(Qt::ISODate); +} + + +bool BootloaderInstallIpod::uninstall(void) +{ + struct ipod_t ipod; + + if(!ipodInitialize(&ipod)) { + emit done(true); + return false; + } + + read_directory(&ipod); + + if (ipod.nimages <= 0) { + emit logItem(tr("Failed to read firmware directory"),LOGERROR); + emit done(true); + return false; + } + if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) { + emit logItem(tr("Unknown version number in firmware (%1)").arg( + ipod.ipod_directory[0].vers), LOGERROR); + emit done(true); + return false; + } + + if (ipod_reopen_rw(&ipod) < 0) { + emit logItem(tr("Could not open Ipod in RW mode"), LOGERROR); + emit done(true); + return false; + } + + if (ipod.ipod_directory[0].entryOffset == 0) { + emit logItem(tr("No bootloader detected."), LOGERROR); + emit done(true); + return false; + } + + if (delete_bootloader(&ipod)==0) { + emit logItem(tr("Successfully removed Bootloader"), LOGOK); + logInstall(LogRemove); + emit done(false); + ipod_close(&ipod); + return true; + } + else { + emit logItem(tr("Removing the bootloader failed."), LOGERROR); + emit done(true); + ipod_close(&ipod); + return false; + } +} + + +BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void) +{ + struct ipod_t ipod; + BootloaderInstallBase::BootloaderType result = BootloaderRockbox; + + if(!ipodInitialize(&ipod)) { + qDebug() << "BootloaderInstallIpod::installed(): BootloaderUnknown"; + result = BootloaderUnknown; + } + + if (ipod.ipod_directory[0].entryOffset == 0) { + qDebug() << "BootloaderInstallIpod::installed(): BootloaderOther"; + result = BootloaderOther; + } + qDebug() << "BootloaderInstallIpod::installed(): BootloaderRockbox"; + ipod_close(&ipod); + + return result; +} + + +BootloaderInstallBase::Capabilities BootloaderInstallIpod::capabilities(void) +{ + return (Install | Uninstall | IsRaw); +} + + +bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod) +{ + ipod_scan(ipod); + if(ipod_open(ipod, 0) < 0) { + emit logItem(tr("Could not open Ipod"), LOGERROR); + return false; + } + + if(read_partinfo(ipod, 0) < 0) { + emit logItem(tr("Could not read partition table"), LOGERROR); + return false; + } + + if(ipod->pinfo[0].start == 0) { + emit logItem(tr("No firmware partition on disk"), LOGERROR); + + return false; + } + return true; +} + diff --git a/rbutil/rbutilqt/bootloaderinstallipod.h b/rbutil/rbutilqt/bootloaderinstallipod.h new file mode 100644 index 0000000000..1e464a228b --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallipod.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef BOOTLOADERINSTALLIPOD_H +#define BOOTLOADERINSTALLIPOD_H + +#include +#include "bootloaderinstallbase.h" +#include "../ipodpatcher/ipodpatcher.h" + +// installer class derivate for Ipod installation +// based on ipodpatcher. +class BootloaderInstallIpod : public BootloaderInstallBase +{ + Q_OBJECT + + public: + BootloaderInstallIpod(QObject *parent = 0); + ~BootloaderInstallIpod(); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + + private slots: + void installStage2(void); + + private: + bool ipodInitialize(struct ipod_t *); +}; + + +#endif + diff --git a/rbutil/rbutilqt/bootloaderinstallmi4.cpp b/rbutil/rbutilqt/bootloaderinstallmi4.cpp new file mode 100644 index 0000000000..b106836262 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallmi4.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "bootloaderinstallmi4.h" +#include "utils.h" + +BootloaderInstallMi4::BootloaderInstallMi4(QObject *parent) + : BootloaderInstallBase(parent) +{ +} + + +bool BootloaderInstallMi4::install(void) +{ + emit logItem(tr("Downloading bootloader"), LOGINFO); + qDebug() << __func__; + downloadBlStart(m_blurl); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + return true; +} + +void BootloaderInstallMi4::installStage2(void) +{ + emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); + + // move old bootloader out of the way + QString fwfile(resolvePathCase(m_blfile)); + QFile oldbl(fwfile); + QString moved = QFileInfo(resolvePathCase(m_blfile)).absolutePath() + + "/OF.mi4"; + qDebug() << "renaming" << fwfile << "->" << moved; + oldbl.rename(moved); + + // place new bootloader + m_tempfile.open(); + qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile; + m_tempfile.close(); + m_tempfile.rename(fwfile); + + emit logItem(tr("Bootloader successful installed"), LOGOK); + logInstall(LogAdd); + + emit done(true); +} + + +bool BootloaderInstallMi4::uninstall(void) +{ + qDebug() << __func__; + + // check if it's actually a Rockbox bootloader + emit logItem(tr("Checking for Rockbox bootloader"), LOGINFO); + if(installed() != BootloaderRockbox) { + emit logItem(tr("No Rockbox bootloader found"), LOGERROR); + return false; + } + + // check if OF file present + emit logItem(tr("Checking for original firmware file"), LOGINFO); + QString original = QFileInfo(resolvePathCase(m_blfile)).absolutePath() + + "/OF.mi4"; + + if(resolvePathCase(original).isEmpty()) { + emit logItem(tr("Error finding original firmware file"), LOGERROR); + return false; + } + + // finally remove RB bootloader + QString resolved = resolvePathCase(m_blfile); + QFile blfile(resolved); + blfile.remove(); + + QFile oldbl(resolvePathCase(original)); + oldbl.rename(m_blfile); + emit logItem(tr("Rockbox bootloader successful removed"), LOGINFO); + logInstall(LogRemove); + emit done(false); + + return true; +} + + +//! check if a bootloader is installed and return its state. +BootloaderInstallBase::BootloaderType BootloaderInstallMi4::installed(void) +{ + // for MI4 files we can check if we actually have a RB bootloader + // installed. + // RB bootloader has "RBBL" at 0x1f8 in the mi4 file. + + // make sure to resolve case to prevent case issues + QString resolved; + resolved = resolvePathCase(m_blfile); + if(resolved.isEmpty()) { + qDebug("%s: BootloaderNone", __func__); + return BootloaderNone; + } + + QFile f(resolved); + f.open(QIODevice::ReadOnly); + f.seek(0x1f8); + char magic[4]; + f.read(magic, 4); + f.close(); + + if(!memcmp(magic, "RBBL", 4)) { + qDebug("%s: BootloaderRockbox", __func__); + return BootloaderRockbox; + } + else { + qDebug("%s: BootloaderOther", __func__); + return BootloaderOther; + } +} + + +BootloaderInstallBase::Capabilities BootloaderInstallMi4::capabilities(void) +{ + qDebug() << __func__; + return Install | Uninstall | Backup | IsFile | CanCheckInstalled | CanCheckVersion; +} + diff --git a/rbutil/rbutilqt/bootloaderinstallmi4.h b/rbutil/rbutilqt/bootloaderinstallmi4.h new file mode 100644 index 0000000000..12529f2811 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallmi4.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "progressloggerinterface.h" +#include "bootloaderinstallbase.h" + + +// mi4 bootloader file based installation. +// Puts the bootloader file to the correct location and +// renames the OF to OF.mi4. +class BootloaderInstallMi4 : public BootloaderInstallBase +{ + Q_OBJECT + + public: + BootloaderInstallMi4(QObject *parent = 0); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + + private slots: + void installStage2(void); + + private: +}; + diff --git a/rbutil/rbutilqt/bootloaderinstallsansa.cpp b/rbutil/rbutilqt/bootloaderinstallsansa.cpp new file mode 100644 index 0000000000..170cfd5905 --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallsansa.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "bootloaderinstallbase.h" +#include "bootloaderinstallsansa.h" + +#include "../sansapatcher/sansapatcher.h" + +BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent) + : BootloaderInstallBase(parent) +{ + (void)parent; + // initialize sector buffer. sansa_sectorbuf is instantiated by + // sansapatcher. + sansa_sectorbuf = NULL; + sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE); +} + + +BootloaderInstallSansa::~BootloaderInstallSansa() +{ + free(sansa_sectorbuf); +} + + +/** Start bootloader installation. + */ +bool BootloaderInstallSansa::install(void) +{ + if(sansa_sectorbuf == NULL) { + emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); + return false; + emit done(true); + } + + emit logItem(tr("Searching for Sansa"), LOGINFO); + + struct sansa_t sansa; + + int n = sansa_scan(&sansa); + if(n == -1) { + emit logItem(tr("Permission for disc access denied!\n" + "This is required to install the bootloader"), + LOGERROR); + emit done(true); + return false; + } + if(n == 0) { + emit logItem(tr("No Sansa detected!"), LOGERROR); + emit done(true); + return false; + } + emit logItem(tr("Downloading bootloader file"), LOGINFO); + + downloadBlStart(m_blurl); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + return true; +} + + +/** Finish bootloader installation. + */ +void BootloaderInstallSansa::installStage2(void) +{ + struct sansa_t sansa; + sansa_scan(&sansa); + + if(sansa_open(&sansa, 0) < 0) { + emit logItem(tr("could not open Sansa"), LOGERROR); + emit done(true); + return; + } + + if(sansa_read_partinfo(&sansa, 0) < 0) + { + emit logItem(tr("could not read partitiontable"), LOGERROR); + emit done(true); + return; + } + + int i = is_sansa(&sansa); + if(i < 0) { + + emit logItem(tr("Disk is not a Sansa (Error: %1), aborting.").arg(i), LOGERROR); + emit done(true); + return; + } + + if(sansa.hasoldbootloader) { + emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" + "You must reinstall the original Sansa firmware before running\n" + "sansapatcher for the first time.\n" + "See http://www.rockbox.org/wiki/SansaE200Install\n"), + LOGERROR); + emit done(true); + return; + } + + if(sansa_reopen_rw(&sansa) < 0) { + emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR); + emit done(true); + return; + } + + m_tempfile.open(); + QString blfile = m_tempfile.fileName(); + m_tempfile.close(); + if(sansa_add_bootloader(&sansa, blfile.toLatin1().data(), + FILETYPE_MI4) == 0) { + emit logItem(tr("Successfully installed bootloader"), LOGOK); + logInstall(LogAdd); + emit done(false); + sansa_close(&sansa); + return; + } + else { + emit logItem(tr("Failed to install bootloader"), LOGERROR); + sansa_close(&sansa); + emit done(true); + return; + } + +} + + +/** Uninstall the bootloader. + */ +bool BootloaderInstallSansa::uninstall(void) +{ + struct sansa_t sansa; + + if(sansa_scan(&sansa) != 1) { + emit logItem(tr("Can't find Sansa"), LOGERROR); + emit done(true); + return false; + } + + if (sansa_open(&sansa, 0) < 0) { + emit logItem(tr("Could not open Sansa"), LOGERROR); + emit done(true); + return false; + } + + if (sansa_read_partinfo(&sansa,0) < 0) { + emit logItem(tr("Could not read partition table"), LOGERROR); + emit done(true); + return false; + } + + int i = is_sansa(&sansa); + if(i < 0) { + emit logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i), LOGERROR); + emit done(true); + return false; + } + + if (sansa.hasoldbootloader) { + emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" + "You must reinstall the original Sansa firmware before running\n" + "sansapatcher for the first time.\n" + "See http://www.rockbox.org/wiki/SansaE200Install\n"), + LOGERROR); + emit done(true); + return false; + } + + if (sansa_reopen_rw(&sansa) < 0) { + emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR); + emit done(true); + return false; + } + + if (sansa_delete_bootloader(&sansa)==0) { + emit logItem(tr("Successfully removed bootloader"), LOGOK); + logInstall(LogRemove); + emit done(false); + sansa_close(&sansa); + return true; + } + else { + emit logItem(tr("Removing bootloader failed."),LOGERROR); + emit done(true); + sansa_close(&sansa); + return false; + } + + return false; +} + + +/** Check if bootloader is already installed + */ +BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void) +{ + struct sansa_t sansa; + int num; + + if(sansa_scan(&sansa) != 1) { + return BootloaderUnknown; + } + if (sansa_open(&sansa, 0) < 0) { + return BootloaderUnknown; + } + if (sansa_read_partinfo(&sansa,0) < 0) { + return BootloaderUnknown; + } + if(is_sansa(&sansa) < 0) { + return BootloaderUnknown; + } + if((num = sansa_list_images(&sansa)) == 2) { + return BootloaderRockbox; + } + else if(num == 1) { + return BootloaderOther; + } + return BootloaderUnknown; + +} + + +/** Get capabilities of subclass installer. + */ +BootloaderInstallBase::Capabilities BootloaderInstallSansa::capabilities(void) +{ + return (Install | Uninstall | IsRaw | CanCheckInstalled); +} + diff --git a/rbutil/rbutilqt/bootloaderinstallsansa.h b/rbutil/rbutilqt/bootloaderinstallsansa.h new file mode 100644 index 0000000000..d8544cf01e --- /dev/null +++ b/rbutil/rbutilqt/bootloaderinstallsansa.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2008 by Dominik Riebeling + * $Id:$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef BOOTLOADERINSTALLSANSA_H +#define BOOTLOADERINSTALLSANSA_H + +#include +#include "bootloaderinstallbase.h" + + +// bootloader installation class for devices handled by sansapatcher. +class BootloaderInstallSansa : public BootloaderInstallBase +{ + Q_OBJECT + + public: + BootloaderInstallSansa(QObject *parent = 0); + ~BootloaderInstallSansa(); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + + private: + + private slots: + void installStage2(void); +}; + + +#endif + diff --git a/rbutil/rbutilqt/browseof.cpp b/rbutil/rbutilqt/browseof.cpp deleted file mode 100644 index 28cde9c6fe..0000000000 --- a/rbutil/rbutilqt/browseof.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include - -#include "browseof.h" -#include "browsedirtree.h" - - -BrowseOF::BrowseOF(QWidget *parent) : QDialog(parent) -{ - ui.setupUi(this); - this->setModal(true); - - connect(ui.browseOFButton,SIGNAL(clicked()),this,SLOT(onBrowse())); -} - -void BrowseOF::setFile(QString file) -{ - ui.OFlineEdit->setText(file); -} - -void BrowseOF::onBrowse() -{ - BrowseDirtree browser(this); - browser.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); - - if(QFileInfo(ui.OFlineEdit->text()).exists()) - { - browser.setDir(ui.OFlineEdit->text()); - } - - if(browser.exec() == QDialog::Accepted) - { - qDebug() << browser.getSelected(); - setFile(browser.getSelected()); - } -} - -QString BrowseOF::getFile() -{ - return ui.OFlineEdit->text(); -} - -void BrowseOF::accept() -{ - this->close(); - setResult(QDialog::Accepted); -} - - - diff --git a/rbutil/rbutilqt/browseof.h b/rbutil/rbutilqt/browseof.h deleted file mode 100644 index 6c23f402b1..0000000000 --- a/rbutil/rbutilqt/browseof.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef BROWSEOF_H -#define BROWSEOF_H - -#include -#include "ui_browseoffrm.h" - -class BrowseOF : public QDialog -{ - Q_OBJECT - - public: - BrowseOF(QWidget *parent = 0); - void setFile(QString file); - QString getFile(); - - - private slots: - void onBrowse(); - - private: - Ui::BrowseOFFrm ui; - - private slots: - void accept(void); -}; - -#endif diff --git a/rbutil/rbutilqt/browseoffrm.ui b/rbutil/rbutilqt/browseoffrm.ui deleted file mode 100644 index bd4f1dd380..0000000000 --- a/rbutil/rbutilqt/browseoffrm.ui +++ /dev/null @@ -1,112 +0,0 @@ - - BrowseOFFrm - - - - 0 - 0 - 460 - 97 - - - - Find original Firmware - - - - - - Browse for a downloaded copy of the original firmware - - - true - - - - - - - - - - Browse - - - - - - - Qt::Horizontal - - - - 241 - 28 - - - - - - - - - - &Ok - - - :/icons/go-next.png - - - - - - - &Cancel - - - :/icons/process-stop.png - - - - - - - - - - - - - buttonCancel - clicked() - BrowseOFFrm - reject() - - - 224 - 355 - - - 48 - 349 - - - - - buttonOk - clicked() - BrowseOFFrm - accept() - - - 146 - 358 - - - 74 - 357 - - - - - diff --git a/rbutil/rbutilqt/install.h b/rbutil/rbutilqt/install.h index 3ac30bd983..0df0f03499 100644 --- a/rbutil/rbutilqt/install.h +++ b/rbutil/rbutilqt/install.h @@ -51,13 +51,15 @@ class Install : public QDialog QMap version; QString m_backupName; + void changeBackupPath(QString); + private slots: void setCached(bool); void setDetailsCurrent(bool); void setDetailsStable(bool); void setDetailsArchived(bool); void done(bool); - void changeBackupPath(); + void changeBackupPath(void); void backupCheckboxChanged(int state); }; diff --git a/rbutil/rbutilqt/installbootloader.cpp b/rbutil/rbutilqt/installbootloader.cpp deleted file mode 100644 index 4e44284fcc..0000000000 --- a/rbutil/rbutilqt/installbootloader.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "installbootloader.h" -#include "irivertools/checksums.h" -#include "utils.h" - -BootloaderInstaller::BootloaderInstaller(QObject* parent): QObject(parent) -{ - -} - -void BootloaderInstaller::install(ProgressloggerInterface* dp) -{ - m_dp = dp; - m_install = true; - m_dp->addItem(tr("Starting bootloader installation"),LOGINFO); - connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool))); - - if(m_bootloadermethod == "gigabeatf") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare())); - connect(this,SIGNAL(finish()),this,SLOT(gigabeatFinish())); - } - else if(m_bootloadermethod == "iaudio") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(iaudioPrepare())); - connect(this,SIGNAL(finish()),this,SLOT(iaudioFinish())); - } - else if(m_bootloadermethod == "h10") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare())); - connect(this,SIGNAL(finish()),this,SLOT(h10Finish())); - } - else if(m_bootloadermethod == "ipodpatcher") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare())); - connect(this,SIGNAL(finish()),this,SLOT(ipodFinish())); - } - else if(m_bootloadermethod == "sansapatcher") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare())); - connect(this,SIGNAL(finish()),this,SLOT(sansaFinish())); - } - else if(m_bootloadermethod == "fwpatcher") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(iriverPrepare())); - connect(this,SIGNAL(finish()),this,SLOT(iriverFinish())); - } - else if(m_bootloadermethod == "mrobe100") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare())); - connect(this,SIGNAL(finish()),this,SLOT(mrobe100Finish())); - } - else - { - m_dp->addItem(tr("unsupported install Method"),LOGERROR); - emit done(true); - return; - } - - emit prepare(); -} - -void BootloaderInstaller::uninstall(ProgressloggerInterface* dp) -{ - m_dp = dp; - m_install = false; - m_dp->addItem(tr("Starting bootloader uninstallation"),LOGINFO); - connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool))); - - if(m_bootloadermethod == "gigabeatf") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare())); - } - else if(m_bootloadermethod == "iaudio") - { - m_dp->addItem(tr("No uninstallation possible"),LOGWARNING); - emit done(true); - return; - } - else if(m_bootloadermethod == "iaudio") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare())); - } - else if(m_bootloadermethod == "ipodpatcher") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare())); - } - else if(m_bootloadermethod == "sansapatcher") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare())); - } - else if(m_bootloadermethod == "h10") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare())); - } - else if(m_bootloadermethod == "mrobe100") - { - // connect internal signal - connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare())); - } - else if(m_bootloadermethod == "fwpatcher") - { - m_dp->addItem(tr("No uninstallation possible"),LOGWARNING); - emit done(true); - return; - } - else - { - m_dp->addItem(tr("unsupported install Method"),LOGERROR); - emit done(true); - return; - } - - emit prepare(); -} - -void BootloaderInstaller::downloadRequestFinished(int id, bool error) -{ - qDebug() << "BootloaderInstall::downloadRequestFinished" << id << error; - qDebug() << "error:" << getter->errorString(); - - downloadDone(error); -} - -void BootloaderInstaller::downloadDone(bool error) -{ - qDebug() << "Install::downloadDone, error:" << error; - - // update progress bar - - int max = m_dp->getProgressMax(); - if(max == 0) { - max = 100; - m_dp->setProgressMax(max); - } - m_dp->setProgressValue(max); - if(getter->httpResponse() != 200) { - m_dp->addItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR); - m_dp->abort(); - emit done(true); - return; - } - if(error) { - m_dp->addItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR); - m_dp->abort(); - emit done(true); - return; - } - else m_dp->addItem(tr("Download finished."),LOGOK); - - emit finish(); - -} - - -void BootloaderInstaller::installEnded(bool error) -{ - (void) error; - m_dp->abort(); -} - -bool BootloaderInstaller::downloadInfo() -{ - // try to get the current build information - infodownloader = new HttpGet(this); - - connect(infodownloader, SIGNAL(done(bool)), this, SLOT(infoDownloadDone(bool))); - connect(infodownloader, SIGNAL(requestFinished(int, bool)), this, SLOT(infoRequestFinished(int, bool))); - - qDebug() << "downloading bootloader info"; - infodownloader->setFile(&bootloaderInfo); - infodownloader->getFile(QUrl(m_bootloaderinfoUrl)); - - // block until its downloaded - qDebug() << "Waiting for Download finished"; - infoDownloaded=false; - infoError = false; - while(!infoDownloaded ) - QCoreApplication::processEvents(); - return !infoError; -} - -void BootloaderInstaller::infoDownloadDone(bool error) -{ - if(error) - { - qDebug() << "network error:" << infodownloader->error(); - return; - } - qDebug() << "network status:" << infodownloader->error(); - - infoDownloaded = true; -} - -void BootloaderInstaller::infoRequestFinished(int id, bool error) -{ - - if(error) - { - QString errorString; - errorString = tr("Network error: %1. Please check your network and proxy settings.") - .arg(infodownloader->errorString()); -#ifndef CONSOLE - if(error) QMessageBox::about(NULL, "Network Error", errorString); -#endif - qDebug() << "downloadDone:" << id << error; - - infoError = true; - infoDownloaded = true; - } - qDebug() << "infoRequestFinished:" << id << error; -} - - -void BootloaderInstaller::createInstallLog() -{ - m_dp->addItem(tr("Creating installation log"),LOGINFO); - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - - bootloaderInfo.open(); - QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this); - bootloaderInfo.close(); - info.beginGroup(m_device); - - installlog.beginGroup("Bootloader"); - installlog.setValue("md5sum",info.value("md5sum").toString()); - installlog.endGroup(); - installlog.sync(); -} - -void BootloaderInstaller::removeInstallLog() -{ - m_dp->addItem(tr("Editing installation log"),LOGINFO); - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - installlog.beginGroup("Bootloader"); - installlog.remove("md5sum"); - installlog.endGroup(); - installlog.sync(); -} - - -bool BootloaderInstaller::uptodate() -{ - QString installedMd5; - QString serverMd5; - - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - installlog.beginGroup("Bootloader"); - installedMd5 = installlog.value("md5sum").toString(); - installlog.endGroup(); - - if(installedMd5.isEmpty()) - return false; - bootloaderInfo.open(); - QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this); - bootloaderInfo.close(); - info.beginGroup(m_device); - serverMd5 = info.value("md5sum").toString(); - info.endGroup(); - - if(installedMd5 != serverMd5) - return false; - else - return true; -} - -/************************************************** -*** gigabeat secific code -***************************************************/ - -void BootloaderInstaller::gigabeatPrepare() -{ - if(m_install) // Installation - { - QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); - } - else //UnInstallation - { - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT"); - QString firmwareOrig = resolvePathCase(firmware.append(".ORIG")); - - QFileInfo firmwareOrigFI(firmwareOrig); - - // check if original firmware exists - if(!firmwareOrigFI.exists()) - { - m_dp->addItem(tr("Could not find the Original Firmware at: %1") - .arg(firmwareOrig),LOGERROR); - emit done(true); - return; - } - - QFile firmwareFile(firmware); - QFile firmwareOrigFile(firmwareOrig); - - //remove modified firmware - if(!firmwareFile.remove()) - { - m_dp->addItem(tr("Could not remove the Firmware at: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - // rename original firmware back - if(!firmwareOrigFile.rename(firmware)) - { - m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2") - .arg(firmwareOrig,firmware),LOGERROR); - emit done(true); - return; - } - - removeInstallLog(); - - emit done(false); //success - } - -} - -void BootloaderInstaller::gigabeatFinish() -{ - // this step is only need for installation, so no code for uninstall here - - m_dp->addItem(tr("Finishing bootloader install"),LOGINFO); - - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername); - - QFileInfo firmwareFI(firmware); - - // check if firmware exists - if(!firmwareFI.exists()) - { - m_dp->addItem(tr("Could not find the Firmware at: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - QString firmwareOrig = firmware; - firmwareOrig.append(".ORIG"); - QFileInfo firmwareOrigFI(firmwareOrig); - - // rename and backup the firmware, if there is no original firmware there - if(!firmwareOrigFI.exists()) - { - QFile firmwareFile(firmware); - //backup - QDir::home().mkdir("Gigabeat Original Firmware Backup"); - firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Gigabeat Original Firmware Backup/") + m_bootloadername); - firmwareFile.unsetError(); - //rename - if(!firmwareFile.rename(firmwareOrig)) - { - m_dp->addItem(tr("Could not rename: %1 to %2") - .arg(firmware,firmwareOrig),LOGERROR); - emit done(true); - return; - } - } - else // or remove the normal firmware, if the original is there - { - QFile firmwareFile(firmware); - firmwareFile.remove(); - } - - //copy the firmware - if(!downloadFile.copy(firmware)) - { - m_dp->addItem(tr("Could not copy: %1 to %2") - .arg(m_tempfilename,firmware),LOGERROR); - emit done(true); - return; - } - - downloadFile.remove(); - - createInstallLog(); - - m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK); - m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO); - m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO); - m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO); - m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO); - m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO); - m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO); - - - m_dp->abort(); - - emit done(false); // success - -} - -/************************************************** -*** iaudio secific code -***************************************************/ -void BootloaderInstaller::iaudioPrepare() -{ - - QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - getter->getFile(QUrl(url)); - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); -} - -void BootloaderInstaller::iaudioFinish() -{ - QString firmware; - QDir dir(m_mountpoint + "/FIRMWARE/"); - if(!dir.exists()) - { - dir.mkpath(m_mountpoint + "/FIRMWARE/"); - } - firmware = resolvePathCase(m_mountpoint + "/FIRMWARE/") + "/" + m_bootloadername; - - //copy the firmware - if(!downloadFile.copy(firmware)) - { - m_dp->addItem(tr("Could not copy: %1 to %2") - .arg(m_tempfilename,firmware),LOGERROR); - emit done(true); - return; - } - - downloadFile.remove(); - - createInstallLog(); - - m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK); - m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO); - m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO); - m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO); - m_dp->addItem(tr("3. Insert Charger."),LOGINFO); - - m_dp->abort(); - - emit done(false); // success - -} - - -/************************************************** -*** h10 secific code -***************************************************/ -void BootloaderInstaller::h10Prepare() -{ - if(m_install) // Installation - { - QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); - } - else // Uninstallation - { - - QString firmwarename = m_bootloadername.section('/', -1); - - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename); - QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4"); - - QFileInfo firmwareFI(firmware); - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - firmware = resolvePathCase(m_mountpoint + "/SYSTEM/H10EMP.mi4"); - //attempt other firmwarename - firmwareFI.setFile(firmware); - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - m_dp->addItem(tr("Firmware does not exist: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - } - - QFileInfo firmwareOrigFI(firmwareOrig); - if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player - { - m_dp->addItem(tr("Original Firmware does not exist: %1") - .arg(firmwareOrig),LOGERROR); - emit done(true); - return; - } - - QFile firmwareFile(firmware); - QFile firmwareOrigFile(firmwareOrig); - - //remove modified firmware - if(!firmwareFile.remove()) - { - m_dp->addItem(tr("Could not remove the Firmware at: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - // rename original firmware back - if(!firmwareOrigFile.rename(firmware)) - { - m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2") - .arg(firmwareOrig,firmware),LOGERROR); - emit done(true); - return; - } - - removeInstallLog(); - - emit done(false); //success - - } -} - -void BootloaderInstaller::h10Finish() -{ - QString firmwarename = m_bootloadername.section('/', -1); - - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename); - QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4"; - - QFileInfo firmwareFI(firmware); - - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - firmware = resolvePathCase(m_mountpoint + "/SYSTEM") +"/H10EMP.mi4"; - //attempt other firmwarename - firmwareFI.setFile(firmware); - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - m_dp->addItem(tr("Firmware does not exist: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - } - - QFileInfo firmwareOrigFI(firmwareOrig); - - if(!firmwareOrigFI.exists()) - { - QFile firmwareFile(firmware); - - //backup - QDir::home().mkdir("Iriver H10 Original Firmware Backup"); - firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Iriver H10 Original Firmware Backup/") + m_bootloadername); - firmwareFile.unsetError(); - - //rename - if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original - { - m_dp->addItem(tr("Could not rename: %1 to %2") - .arg(firmware,firmwareOrig),LOGERROR); - emit done(true); - return; - } - } - else //there is already a original firmware - { - QFile firmwareFile(firmware); - firmwareFile.remove(); - } - //copy the firmware - if(!downloadFile.copy(firmware)) - { - m_dp->addItem(tr("Could not copy: %1 to %2") - .arg(m_tempfilename,firmware),LOGERROR); - emit done(true); - return; - } - - downloadFile.remove(); - - createInstallLog(); - - m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK); - m_dp->abort(); - - emit done(false); // success - -} - - - -/************************************************** -*** mrobe100 secific code -***************************************************/ -void BootloaderInstaller::mrobe100Prepare() -{ - if(m_install) // Installation - { - QString url = m_bootloaderUrlBase + "/olympus/mrobe100/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); - } - else // Uninstallation - { - - QString firmwarename = m_bootloadername; - - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename); - QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4"); - - QFileInfo firmwareFI(firmware); - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - m_dp->addItem(tr("Firmware does not exist: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - QFileInfo firmwareOrigFI(firmwareOrig); - if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player - { - m_dp->addItem(tr("Original Firmware does not exist: %1") - .arg(firmwareOrig),LOGERROR); - emit done(true); - return; - } - - QFile firmwareFile(firmware); - QFile firmwareOrigFile(firmwareOrig); - - //remove modified firmware - if(!firmwareFile.remove()) - { - m_dp->addItem(tr("Could not remove the Firmware at: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - // move original firmware back - if(!firmwareOrigFile.rename(firmware)) - { - m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2") - .arg(firmwareOrig,firmware),LOGERROR); - emit done(true); - return; - } - - removeInstallLog(); - - emit done(false); //success - - } -} - -void BootloaderInstaller::mrobe100Finish() -{ - QString firmwarename = m_bootloadername; - - QString firmware; - firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename); - // NOTE: the filename for the OF may not exist yet, so resolve path only! - QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4"; - - QFileInfo firmwareFI(firmware); - - if(!firmwareFI.exists()) //Firmware dosent exists on player - { - m_dp->addItem(tr("Firmware does not exist: %1") - .arg(firmware),LOGERROR); - emit done(true); - return; - } - - QFileInfo firmwareOrigFI(firmwareOrig); - - if(!firmwareOrigFI.exists()) - { - QFile firmwareFile(firmware); - - //backup - QDir::home().mkdir("Olympus mrobe100 Original Firmware Backup"); - firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Olympus mrobe100 Original Firmware Backup/") + m_bootloadername); - firmwareFile.unsetError(); - //rename - if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original - { - m_dp->addItem(tr("Could not rename: %1 to %2") - .arg(firmware,firmwareOrig),LOGERROR); - emit done(true); - return; - } - } - else //there is already a original firmware - { - QFile firmwareFile(firmware); - firmwareFile.remove(); - } - //copy the firmware - if(!downloadFile.copy(firmware)) - { - m_dp->addItem(tr("Could not copy: %1 to %2") - .arg(m_tempfilename,firmware),LOGERROR); - emit done(true); - return; - } - - downloadFile.remove(); - - createInstallLog(); - - m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK); - m_dp->abort(); - - emit done(false); // success -} - - -/************************************************** -*** ipod secific code -***************************************************/ -int verbose =0; -// reserves memory for ipodpatcher -bool initIpodpatcher() -{ - if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) return true; - else return false; -} - -void BootloaderInstaller::ipodPrepare() -{ - m_dp->addItem(tr("Searching for ipods"),LOGINFO); - struct ipod_t ipod; - - int n = ipod_scan(&ipod); - if (n == 0) - { - m_dp->addItem(tr("No Ipods found"),LOGERROR); - emit done(true); - return; - } - if (n > 1) - { - m_dp->addItem(tr("Too many Ipods found"),LOGERROR); - emit done(true); - } - - if(m_install) // Installation - { - - QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod"; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); - } - else // Uninstallation - { - if (ipod_open(&ipod, 0) < 0) - { - m_dp->addItem(tr("could not open ipod"),LOGERROR); - emit done(true); - return; - } - - if (read_partinfo(&ipod,0) < 0) - { - m_dp->addItem(tr("could not read partitiontable"),LOGERROR); - emit done(true); - return; - } - - if (ipod.pinfo[0].start==0) - { - m_dp->addItem(tr("No partition 0 on disk"),LOGERROR); - - int i; - double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size; - m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO); - for ( i = 0; i < 4; i++ ) - { - if (ipod.pinfo[i].start != 0) - { - m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg( - i).arg( - ipod.pinfo[i].start).arg( - ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg( - ipod.pinfo[i].size/sectors_per_MB).arg( - get_parttype(ipod.pinfo[i].type)).arg( - ipod.pinfo[i].type),LOGINFO); - } - } - emit done(true); - return; - } - - read_directory(&ipod); - - if (ipod.nimages <= 0) - { - m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR); - emit done(true); - return; - } - if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) - { - m_dp->addItem(tr("Unknown version number in firmware (%1)").arg( - ipod.ipod_directory[0].vers),LOGERROR); - emit done(true); - return; - } - - if (ipod.macpod) - { - m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on " - "this. Convert it to WinPod\n" - "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), - LOGWARNING); - emit done(true); - return; - } - - if (ipod_reopen_rw(&ipod) < 0) - { - m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR); - emit done(true); - return; - } - - if (ipod.ipod_directory[0].entryOffset==0) { - m_dp->addItem(tr("No bootloader detected."),LOGERROR); - emit done(true); - return; - } - - if (delete_bootloader(&ipod)==0) - { - m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK); - removeInstallLog(); - emit done(false); - ipod_close(&ipod); - return; - } - else - { - m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR); - emit done(true); - ipod_close(&ipod); - return; - } - } -} - -void BootloaderInstaller::ipodFinish() -{ - struct ipod_t ipod; - ipod_scan(&ipod); - - if (ipod_open(&ipod, 0) < 0) - { - m_dp->addItem(tr("could not open ipod"),LOGERROR); - emit done(true); - return; - } - - if (read_partinfo(&ipod,0) < 0) - { - m_dp->addItem(tr("could not read partitiontable"),LOGERROR); - emit done(true); - return; - } - - if (ipod.pinfo[0].start==0) - { - m_dp->addItem(tr("No partition 0 on disk"),LOGERROR); - - int i; - double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size; - - m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO); - - for ( i = 0; i < 4; i++ ) - { - if (ipod.pinfo[i].start != 0) - { - m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg( - i).arg( - ipod.pinfo[i].start).arg( - ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg( - ipod.pinfo[i].size/sectors_per_MB).arg( - get_parttype(ipod.pinfo[i].type)).arg( - ipod.pinfo[i].type),LOGWARNING); - } - } - emit done(true); - return; - } - - read_directory(&ipod); - - if (ipod.nimages <= 0) - { - m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR); - emit done(true); - return; - } - if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) - { - m_dp->addItem(tr("Unknown version number in firmware (%1)").arg( - ipod.ipod_directory[0].vers),LOGERROR); - emit done(true); - return; - } - - if (ipod.macpod) - { - m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on " - "this. Convert it to WinPod\n" - "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), - LOGWARNING); - emit done(true); - return; - } - - if (ipod_reopen_rw(&ipod) < 0) - { - m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR); - emit done(true); - return; - } - - if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0) - { - m_dp->addItem(tr("Successfully added Bootloader"),LOGOK); - createInstallLog(); - emit done(false); - ipod_close(&ipod); - return; - } - else - { - m_dp->addItem(tr("failed to add Bootloader"),LOGERROR); - ipod_close(&ipod); - emit done(true); - return; - } -} - -/************************************************** -*** sansa secific code -***************************************************/ -// reserves memory for sansapatcher -bool initSansapatcher() -{ - if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) return true; - else return false; -} - - -void BootloaderInstaller::sansaPrepare() -{ - m_dp->addItem(tr("Searching for sansas"),LOGINFO); - struct sansa_t sansa; - - int n = sansa_scan(&sansa); - if (n == 0) - { - m_dp->addItem(tr("No Sansa found"),LOGERROR); - emit done(true); - return; - } - if (n > 1) - { - m_dp->addItem(tr("Too many Sansas found"),LOGERROR); - emit done(true); - } - - if(m_install) // Installation - { - QString url = m_bootloaderUrlBase + "/sandisk-sansa/" - + QString(sansa.targetname) + "/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); - } - else // Uninstallation - { - - if (sansa_open(&sansa, 0) < 0) - { - m_dp->addItem(tr("could not open Sansa"),LOGERROR); - emit done(true); - return; - } - - if (sansa_read_partinfo(&sansa,0) < 0) - { - m_dp->addItem(tr("could not read partitiontable"),LOGERROR); - emit done(true); - return; - } - - int i = is_sansa(&sansa); - if (i < 0) { - m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR); - emit done(true); - return; - } - - if (sansa.hasoldbootloader) - { - m_dp->addItem(tr("********************************************\n" - "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" - "You must reinstall the original Sansa firmware before running\n" - "sansapatcher for the first time.\n" - "See http://www.rockbox.org/wiki/SansaE200Install\n" - "*********************************************\n"),LOGERROR); - emit done(true); - return; - } - - - if (sansa_reopen_rw(&sansa) < 0) - { - m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR); - emit done(true); - return; - } - - if (sansa_delete_bootloader(&sansa)==0) - { - m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK); - removeInstallLog(); - emit done(false); - sansa_close(&sansa); - return; - } - else - { - m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR); - emit done(true); - sansa_close(&sansa); - return; - } - } -} - -void BootloaderInstaller::sansaFinish() -{ - struct sansa_t sansa; - sansa_scan(&sansa); - - if (sansa_open(&sansa, 0) < 0) - { - m_dp->addItem(tr("could not open Sansa"),LOGERROR); - emit done(true); - return; - } - - if (sansa_read_partinfo(&sansa,0) < 0) - { - m_dp->addItem(tr("could not read partitiontable"),LOGERROR); - emit done(true); - return; - } - - - int i = is_sansa(&sansa); - if (i < 0) { - - m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR); - emit done(true); - return; - } - - if (sansa.hasoldbootloader) - { - m_dp->addItem(tr("********************************************\n" - "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" - "You must reinstall the original Sansa firmware before running\n" - "sansapatcher for the first time.\n" - "See http://www.rockbox.org/wiki/SansaE200Install\n" - "*********************************************\n"),LOGERROR); - emit done(true); - return; - } - - if (sansa_reopen_rw(&sansa) < 0) - { - m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR); - emit done(true); - return; - } - - if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0) - { - m_dp->addItem(tr("Successfully added Bootloader"),LOGOK); - createInstallLog(); - emit done(false); - sansa_close(&sansa); - return; - } - else - { - m_dp->addItem(tr("failed to add Bootloader"),LOGERROR); - sansa_close(&sansa); - emit done(true); - return; - } - -} - -/************************************************** -*** iriver /fwpatcher secific code -***************************************************/ - -void BootloaderInstaller::iriverPrepare() -{ - char md5sum_str[32]; - if (!FileMD5(m_origfirmware, md5sum_str)) { - m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR); - emit done(true); - return; - } - - /* Check firmware against md5sums in h120sums and h100sums */ - series = 0; - table_entry = intable(md5sum_str, &h120pairs[0], - sizeof(h120pairs)/sizeof(struct sumpairs)); - if (table_entry >= 0) { - series = 120; - } - else - { - table_entry = intable(md5sum_str, &h100pairs[0], - sizeof(h100pairs)/sizeof(struct sumpairs)); - if (table_entry >= 0) - { - series = 100; - } - else - { - table_entry = intable(md5sum_str, &h300pairs[0], - sizeof(h300pairs)/sizeof(struct sumpairs)); - if (table_entry >= 0) - series = 300; - } - } - if (series == 0) - { - m_dp->addItem(tr("Could not detect firmware type"),LOGERROR); - emit done(true); - return; - } - - QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername; - - m_dp->addItem(tr("Downloading file %1.%2") - .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO); - - // temporary file needs to be opened to get the filename - downloadFile.open(); - m_tempfilename = downloadFile.fileName(); - downloadFile.close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(&downloadFile); - - // connect signals from HttpGet - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int))); - connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(QUrl(url)); -} - -void BootloaderInstaller::iriverFinish() -{ - // Patch firmware - char md5sum_str[32]; - struct sumpairs *sums = 0; - int origin = 0; - - /* get pointer to the correct bootloader.bin */ - switch(series) { - case 100: - sums = &h100pairs[0]; - origin = 0x1f0000; - break; - case 120: - sums = &h120pairs[0]; - origin = 0x1f0000; - break; - case 300: - sums = &h300pairs[0]; - origin = 0x3f0000; - break; - } - - // temporary files needs to be opened to get the filename - QTemporaryFile firmwareBin, newBin, newHex; - firmwareBin.open(); - newBin.open(); - newHex.open(); - QString firmwareBinName = firmwareBin.fileName(); - QString newBinName = newBin.fileName(); - QString newHexName = newHex.fileName(); - firmwareBin.close(); - newBin.close(); - newHex.close(); - - // iriver decode - int result; - if ((result = iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE)) < 0) - { - QString error; - switch(result) { - case -1: error = tr("Can't open input file"); break; - case -2: error = tr("Can't open output file"); break; - case -3: error = tr("invalid file: header length wrong"); break; - case -4: error = tr("invalid file: unrecognized header"); break; - case -5: error = tr("invalid file: \"length\" field wrong"); break; - case -6: error = tr("invalid file: \"length2\" field wrong"); break; - case -7: error = tr("invalid file: internal checksum error"); break; - case -8: error = tr("invalid file: \"length3\" field wrong"); break; - default: error = tr("unknown"); break; - } - m_dp->addItem(tr("Error in descramble: %1").arg(error), LOGERROR); - firmwareBin.remove(); - newBin.remove(); - newHex.remove(); - emit done(true); - return; - } - // mkboot - if((result = mkboot(firmwareBinName, newBinName, m_tempfilename, origin)) < 0) - { - QString error; - switch(result) { - case -1: error = tr("could not open input file"); break; - case -2: error = tr("reading header failed"); break; - case -3: error = tr("reading firmware failed"); break; - case -4: error = tr("can't open bootloader file"); break; - case -5: error = tr("reading bootloader file failed"); break; - case -6: error = tr("can't open output file"); break; - case -7: error = tr("writing output file failed"); break; - } - m_dp->addItem(tr("Error in patching: %1").arg(error), LOGERROR); - - firmwareBin.remove(); - newBin.remove(); - newHex.remove(); - emit done(true); - return; - } - // iriver_encode - if((result = iriver_encode(newBinName, newHexName, FALSE)) < 0) - { - QString error; - switch(result) { - case -1: error = tr("Can't open input file"); break; - case -2: error = tr("Can't open output file"); break; - case -3: error = tr("invalid file: header length wrong"); break; - case -4: error = tr("invalid file: unrecognized header"); break; - case -5: error = tr("invalid file: \"length\" field wrong"); break; - case -6: error = tr("invalid file: \"length2\" field wrong"); break; - case -7: error = tr("invalid file: internal checksum error"); break; - case -8: error = tr("invalid file: \"length3\" field wrong"); break; - default: error = tr("unknown"); break; - } - m_dp->addItem(tr("Error in scramble: %1").arg(error), LOGERROR); - - firmwareBin.remove(); - newBin.remove(); - newHex.remove(); - emit done(true); - return; - } - - /* now md5sum it */ - if (!FileMD5(newHexName, md5sum_str)) - { - m_dp->addItem(tr("Error in checksumming"),LOGERROR); - firmwareBin.remove(); - newBin.remove(); - newHex.remove(); - emit done(true); - return; - } - if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) { - /* delete temp files */ - firmwareBin.remove(); - newBin.remove(); - } - - // Load patched Firmware to player - QString dest; - if(series == 100) - dest = m_mountpoint + "/ihp_100.hex"; - else if(series == 120) - dest = m_mountpoint + "/ihp_120.hex"; - else if(series == 300) - dest = m_mountpoint + "/H300.hex"; - - // copy file - QFile destfile(dest); - if(destfile.exists()) destfile.remove(); - if(!newHex.copy(dest)) - { - m_dp->addItem(tr("Could not copy: %1 to %2") - .arg(newHexName,dest),LOGERROR); - emit done(true); - return; - } - - downloadFile.remove(); - newHex.remove(); - - createInstallLog(); - - m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK); - m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO); - m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO); - m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO); - m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO); - m_dp->addItem(tr("4. Reboot."),LOGINFO); - m_dp->abort(); - - emit done(false); // success -} - diff --git a/rbutil/rbutilqt/installbootloader.h b/rbutil/rbutilqt/installbootloader.h deleted file mode 100644 index f849361699..0000000000 --- a/rbutil/rbutilqt/installbootloader.h +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef INSTALLBOOTLOADER_H -#define INSTALLBOOTLOADER_H - -#ifndef CONSOLE -#include -#else -#include -#endif - -#include "progressloggerinterface.h" -#include "httpget.h" -#include "irivertools/irivertools.h" - -#include "../ipodpatcher/ipodpatcher.h" -#include "../sansapatcher/sansapatcher.h" - -bool initIpodpatcher(); -bool initSansapatcher(); - -class BootloaderInstaller : public QObject -{ - Q_OBJECT - -public: - BootloaderInstaller(QObject* parent); - ~BootloaderInstaller() {} - - void install(ProgressloggerInterface* dp); - void uninstall(ProgressloggerInterface* dp); - - void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;} - void setDevice(QString device) {m_device= device;} //!< the current plattform - void setBootloaderMethod(QString method) {m_bootloadermethod= method;} - void setBootloaderName(QString name){m_bootloadername= name;} - void setBootloaderBaseUrl(QString baseUrl){m_bootloaderUrlBase = baseUrl;} - void setOrigFirmwarePath(QString path) {m_origfirmware = path;} //!< for iriver original firmware - void setBootloaderInfoUrl(QString url) {m_bootloaderinfoUrl =url; } //!< the url for the info file - bool downloadInfo(); //!< should be called before install/uninstall, blocks until downloaded. - bool uptodate(); //!< returns wether the bootloader is uptodate - -signals: - void done(bool error); //installation finished. - -signals: // internal signals. Dont use this from out side. - void prepare(); - void finish(); - -private slots: - void createInstallLog(); // adds the bootloader entry to the log - void removeInstallLog(); // removes the bootloader entry from the log - - void downloadDone(bool); - void downloadRequestFinished(int, bool); - void infoDownloadDone(bool); - void infoRequestFinished(int, bool); - void installEnded(bool); - - // gigabeat specific routines - void gigabeatPrepare(); - void gigabeatFinish(); - - //iaudio specific routines - void iaudioPrepare(); - void iaudioFinish(); - - //h10 specific routines - void h10Prepare(); - void h10Finish(); - - //ipod specific routines - void ipodPrepare(); - void ipodFinish(); - - //sansa specific routines - void sansaPrepare(); - void sansaFinish(); - - //iriver specific routines - void iriverPrepare(); - void iriverFinish(); - - //mrobe100 specific routines - void mrobe100Prepare(); - void mrobe100Finish(); - -private: - - HttpGet *infodownloader; - QTemporaryFile bootloaderInfo; - volatile bool infoDownloaded; - volatile bool infoError; - - QString m_mountpoint, m_device,m_bootloadermethod,m_bootloadername; - QString m_bootloaderUrlBase,m_tempfilename,m_origfirmware; - QString m_bootloaderinfoUrl; - bool m_install; - - int series,table_entry; // for fwpatcher - - HttpGet *getter; - QTemporaryFile downloadFile; - - ProgressloggerInterface* m_dp; - -}; -#endif diff --git a/rbutil/rbutilqt/irivertools/checksums.h b/rbutil/rbutilqt/irivertools/checksums.h deleted file mode 100644 index 6b66455f1f..0000000000 --- a/rbutil/rbutilqt/irivertools/checksums.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * Module: rbutil - * File: irivertools.h - * - * Copyright (C) 2007 Dominik Wenger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef CHECKSUMS_H -#define CHECKSUMS_H - -/* precalculated checksums for H110/H115 */ -static struct sumpairs h100pairs[] = { -#include "h100sums.h" -}; - -/* precalculated checksums for H120/H140 */ -static struct sumpairs h120pairs[] = { -#include "h120sums.h" -}; - -/* precalculated checksums for H320/H340 */ -static struct sumpairs h300pairs[] = { -#include "h300sums.h" -}; - -#endif diff --git a/rbutil/rbutilqt/irivertools/irivertools.cpp b/rbutil/rbutilqt/irivertools/irivertools.cpp deleted file mode 100644 index 2bcd9ffb80..0000000000 --- a/rbutil/rbutilqt/irivertools/irivertools.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * Module: rbutil - * File: irivertools.cpp - * - * Copyright (C) 2007 Dominik Wenger - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include -#include "irivertools.h" - -const unsigned char munge[] = { - 0x7a, 0x36, 0xc4, 0x43, 0x49, 0x6b, 0x35, 0x4e, 0xa3, 0x46, 0x25, 0x84, - 0x4d, 0x73, 0x74, 0x61 -}; - -const unsigned char header_modify[] = "* IHPFIRM-DECODED "; - -const char * const models[] = { "iHP-100", "iHP-120/iHP-140", "H300 series", - NULL }; - -/* aligns with models array; expected min firmware size */ -const unsigned int firmware_minsize[] = { 0x100000, 0x100000, 0x200000 }; -/* aligns with models array; expected max firmware size */ -const unsigned int firmware_maxsize[] = { 0x200000, 0x200000, 0x400000 }; - -const unsigned char header[][16] = { - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, - { 0x20, 0x03, 0x08, 0x27, 0x24, 0x00, 0x02, 0x30, 0x19, 0x17, 0x65, 0x73, - 0x85, 0x32, 0x83, 0x22 }, - { 0x20, 0x04, 0x03, 0x27, 0x20, 0x50, 0x01, 0x70, 0x80, 0x30, 0x80, 0x06, - 0x30, 0x19, 0x17, 0x65 } -}; - -/* begin mkboot.c excerpt */ -unsigned char image[0x400000 + 0x220 + 0x400000/0x200]; - -int mkboot(QString infile, QString outfile, QString bootloader, int origin) -{ - int i; - int len,bllen; - int actual_length, total_length, binary_length, num_chksums; - - memset(image, 0xff, sizeof(image)); - - /* First, read the iriver original firmware into the image */ - QFile f(infile); - if(!f.open(QIODevice::ReadOnly)) - { - // can't open input file - return -1; - } - i = f.read((char*)image,16); - if(i < 16) { - // reading header failed - return -2; - } - - /* This is the length of the binary image without the scrambling - overhead (but including the ESTFBINR header) */ - binary_length = image[4] + (image[5] << 8) + - (image[6] << 16) + (image[7] << 24); - - /* Read the rest of the binary data, but not the checksum block */ - len = binary_length+0x200-16; - i = f.read((char*)image+16, len); - if(i < len) { - // reading firmware failed - return -3; - } - - f.close(); - /* Now, read the boot loader into the image */ - f.setFileName(bootloader); - if(!f.open(QIODevice::ReadOnly)) - { - // can't open bootloader file - return -4; - } - - bllen = f.size(); - - i = f.read((char*)image+0x220 + origin, bllen); - if(i < bllen) { - // reading bootloader file failed - return -5; - } - - f.close(); - f.setFileName(outfile); - if(!f.open(QIODevice::WriteOnly)) - { - // can't open output file - return -6; - } - - /* Patch the reset vector to start the boot loader */ - image[0x220 + 4] = image[origin + 0x220 + 4]; - image[0x220 + 5] = image[origin + 0x220 + 5]; - image[0x220 + 6] = image[origin + 0x220 + 6]; - image[0x220 + 7] = image[origin + 0x220 + 7]; - - /* This is the actual length of the binary, excluding all headers */ - actual_length = origin + bllen; - - /* Patch the ESTFBINR header */ - image[0x20c] = (actual_length >> 24) & 0xff; - image[0x20d] = (actual_length >> 16) & 0xff; - image[0x20e] = (actual_length >> 8) & 0xff; - image[0x20f] = actual_length & 0xff; - - image[0x21c] = (actual_length >> 24) & 0xff; - image[0x21d] = (actual_length >> 16) & 0xff; - image[0x21e] = (actual_length >> 8) & 0xff; - image[0x21f] = actual_length & 0xff; - - /* This is the length of the binary, including the ESTFBINR header and - rounded up to the nearest 0x200 boundary */ - binary_length = (actual_length + 0x20 + 0x1ff) & 0xfffffe00; - - /* The number of checksums, i.e number of 0x200 byte blocks */ - num_chksums = binary_length / 0x200; - - /* The total file length, including all headers and checksums */ - total_length = binary_length + num_chksums + 0x200; - - /* Patch the scrambler header with the new length info */ - image[0] = total_length & 0xff; - image[1] = (total_length >> 8) & 0xff; - image[2] = (total_length >> 16) & 0xff; - image[3] = (total_length >> 24) & 0xff; - - image[4] = binary_length & 0xff; - image[5] = (binary_length >> 8) & 0xff; - image[6] = (binary_length >> 16) & 0xff; - image[7] = (binary_length >> 24) & 0xff; - - image[8] = num_chksums & 0xff; - image[9] = (num_chksums >> 8) & 0xff; - image[10] = (num_chksums >> 16) & 0xff; - image[11] = (num_chksums >> 24) & 0xff; - - i = f.write((char*)image,total_length); - if(i < total_length) { - // writing bootloader file failed - return -7; - } - - f.close(); - - return 0; -} - -/* end mkboot.c excerpt */ - - -int intable(char *md5, struct sumpairs *table, int len) -{ - int i; - for (i = 0; i < len; i++) { - if (strncmp(md5, table[i].unpatched, 32) == 0) { - return i; - } - } - return -1; -} - - - - -static int testheader( const unsigned char * const data ) -{ - const unsigned char * const d = data+16; - const char * const * m = models; - int index = 0; - while( *m ) - { - if( memcmp( header[ index ], d, 16 ) == 0 ) - return index; - index++; - m++; - }; - return -1; -}; - -static void modifyheader( unsigned char * data ) -{ - const unsigned char * h = header_modify; - int i; - for( i=0; i<512; i++ ) - { - if( *h == '\0' ) - h = header_modify; - *data++ ^= *h++; - }; -}; - -int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify, - enum striptype stripmode) -{ - QFile infile(infile_name); - QFile outfile(outfile_name); - int i = -1; - unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; - unsigned char blockdata[16+16]; - unsigned char out[16]; - unsigned char newmunge; - signed long lenread; - int s = 0; - unsigned char * pChecksums, * ppChecksums = 0; - unsigned char ck; - - - if(!infile.open(QIODevice::ReadOnly)) - { - // can't open input file - return -1; - } - if(!outfile.open(QIODevice::WriteOnly)) - { - // can't open output file - return -2; - } - lenread = infile.read( (char*)headerdata, 512); - if( lenread != 512 ) - { - // header length doesn't match - infile.close(); - outfile.close(); - return -3; - }; - - i = testheader( headerdata ); - if( i == -1 ) - { - // header unknown - infile.close(); - outfile.close(); - return -4; - }; - fprintf( stderr, "Model %s\n", models[ i ] ); - - dwLength1 = headerdata[0] | (headerdata[1]<<8) | - (headerdata[2]<<16) | (headerdata[3]<<24); - dwLength2 = headerdata[4] | (headerdata[5]<<8) | - (headerdata[6]<<16) | (headerdata[7]<<24); - dwLength3 = headerdata[8] | (headerdata[9]<<8) | - (headerdata[10]<<16) | (headerdata[11]<<24); - - if( dwLength1 < firmware_minsize[ i ] || - dwLength1 > firmware_maxsize[ i ] || - dwLength2 < firmware_minsize[ i ] || - dwLength2 > dwLength1 || - dwLength3 > dwLength1 || - dwLength2>>9 != dwLength3 || - dwLength2+dwLength3+512 != dwLength1 ) - { - // file 'length' data is wrong - infile.close(); - outfile.close(); - return -5; - }; - - pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); - - if( modify ) - { - modifyheader( headerdata ); - }; - - if( stripmode == STRIP_NONE ) - outfile.write( (char*)headerdata, 512); - - memset( blockdata, 0, 16 ); - - ck = 0; - while( ( fp < dwLength2 ) && - ( lenread = infile.read( (char*)blockdata+16, 16) == 16) ) - { - fp += 16; - - for( i=0; i<16; ++i ) - { - newmunge = blockdata[16+i] ^ munge[i]; - out[i] = newmunge ^ blockdata[i]; - blockdata[i] = newmunge; - ck += out[i]; - } - - if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF ) - { - outfile.write( (char*)out+4, 12); - outfile.write( (char*)out, 4); - } - else - { - if( ESTF_SIZE - fp < 16 ) - { - memcpy( out+4, blockdata+16, 12 ); - memcpy( out, blockdata+28, 4 ); - outfile.write((char*) blockdata+16+ESTF_SIZE-fp, ESTF_SIZE-fp); - } - } - - - if( s == 496 ) - { - s = 0; - memset( blockdata, 0, 16 ); - *ppChecksums++ = ck; - ck = 0; - } - else - s+=16; - }; - - if( fp != dwLength2 ) - { - // 'length2' field mismatch - infile.close(); - outfile.close(); - return -6; - }; - - fp = 0; - ppChecksums = pChecksums; - while( ( fp < dwLength3 ) && - ( lenread = infile.read((char*) blockdata, 32 ) ) > 0 ) - { - fp += lenread; - if( stripmode == STRIP_NONE ) - outfile.write((char*) blockdata, lenread ); - if( memcmp( ppChecksums, blockdata, lenread ) != 0 ) - { - // file checksum wrong - infile.close(); - outfile.close(); - return -7; - }; - ppChecksums += lenread; - }; - - if( fp != dwLength3 ) - { - // 'length3' field mismatch - infile.close(); - outfile.close(); - return -8; - }; - - - fprintf( stderr, "File decoded correctly and all checksums matched!\n" ); - switch( stripmode ) - { - default: - case STRIP_NONE: - fprintf(stderr, "Output file contains all headers and " - "checksums\n"); - break; - case STRIP_HEADER_CHECKSUM: - fprintf( stderr, "NB: output file contains only ESTFBINR header" - " and decoded firmware code\n" ); - break; - case STRIP_HEADER_CHECKSUM_ESTF: - fprintf( stderr, "NB: output file contains only raw decoded " - "firmware code\n" ); - break; - }; - - infile.close(); - outfile.close(); - return 0; - -}; - -int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify) -{ - QFile infile(infile_name); - QFile outfile(outfile_name); - int i = -1; - unsigned char headerdata[512]; - unsigned long dwLength1, dwLength2, dwLength3, fp = 0; - unsigned char blockdata[16+16]; - unsigned char out[16]; - unsigned char newmunge; - signed long lenread; - int s = 0; - unsigned char * pChecksums, * ppChecksums; - unsigned char ck; - - if(!infile.open(QIODevice::ReadOnly)) - { - // can't open input file - return -1; - } - if(!outfile.open(QIODevice::WriteOnly)) - { - // can't open output file - infile.close(); - return -2; - } - - lenread = infile.read((char*) headerdata, 512 ); - if( lenread != 512 ) - { - // header length error - infile.close(); - outfile.close(); - return -3; - }; - - if( modify ) - { - modifyheader( headerdata ); /* reversible */ - }; - - i = testheader( headerdata ); - if( i == -1 ) - { - // header verification error - infile.close(); - outfile.close(); - return -4; - }; - fprintf( stderr, "Model %s\n", models[ i ] ); - - dwLength1 = headerdata[0] | (headerdata[1]<<8) | - (headerdata[2]<<16) | (headerdata[3]<<24); - dwLength2 = headerdata[4] | (headerdata[5]<<8) | - (headerdata[6]<<16) | (headerdata[7]<<24); - dwLength3 = headerdata[8] | (headerdata[9]<<8) | - (headerdata[10]<<16) | (headerdata[11]<<24); - - if( dwLength1 < firmware_minsize[i] || - dwLength1 > firmware_maxsize[i] || - dwLength2 < firmware_minsize[i] || - dwLength2 > dwLength1 || - dwLength3 > dwLength1 || - dwLength2+dwLength3+512 != dwLength1 ) - { - // file 'length' error - infile.close(); - outfile.close(); - return -5; - }; - - pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); - - outfile.write( (char*)headerdata, 512); - - memset( blockdata, 0, 16 ); - ck = 0; - while( ( fp < dwLength2 ) && - ( lenread = infile.read((char*) blockdata+16, 16) ) == 16 ) - { - fp += 16; - for( i=0; i<16; ++i ) - { - newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i]; - out[i] = newmunge ^ munge[i]; - ck += blockdata[16+i]; - blockdata[i] = newmunge; - }; - outfile.write( (char*)out, 16); - - if( s == 496 ) - { - s = 0; - memset( blockdata, 0, 16 ); - *ppChecksums++ = ck; - ck = 0; - } - else - s+=16; - }; - - if( fp != dwLength2 ) - { - // file 'length1' mismatch - infile.close(); - outfile.close(); - return -6; - }; - - /* write out remainder w/out applying descrambler */ - fp = 0; - lenread = dwLength3; - ppChecksums = pChecksums; - while( ( fp < dwLength3) && - ( lenread = outfile.write((char*) ppChecksums, lenread) ) > 0 ) - { - fp += lenread; - ppChecksums += lenread; - lenread = dwLength3 - fp; - }; - - if( fp != dwLength3 ) - { - // 'length2' field mismatch - infile.close(); - outfile.close(); - return -8; - }; - - fprintf( stderr, "File encoded successfully and checksum table built!\n" ); - - infile.close(); - outfile.close(); - return 0; - -}; - - - diff --git a/rbutil/rbutilqt/irivertools/irivertools.h b/rbutil/rbutilqt/irivertools/irivertools.h deleted file mode 100644 index 6d61300d79..0000000000 --- a/rbutil/rbutilqt/irivertools/irivertools.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * Module: rbutil - * File: irivertools.h - * - * Copyright (C) 2007 Dominik Wenger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#ifndef IRIVERTOOLS_H_INCLUDED -#define IRIVERTOOLS_H_INCLUDED - -#include - -#include "md5sum.h" - -#define ESTF_SIZE 32 - -struct sumpairs { - const char *unpatched; - const char *patched; -}; - - -enum striptype -{ - STRIP_NONE, - STRIP_HEADER_CHECKSUM, - STRIP_HEADER_CHECKSUM_ESTF -}; - -/* protos for iriver.c */ - -int intable(char *md5, struct sumpairs *table, int len); - -int mkboot(QString infile, QString outfile,QString bootloader,int origin); -int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify, - enum striptype stripmode); -int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify); - -#endif // IRIVERTOOLS_H_INCLUDED diff --git a/rbutil/rbutilqt/irivertools/md5sum.cpp b/rbutil/rbutilqt/irivertools/md5sum.cpp deleted file mode 100644 index f4d25e67ef..0000000000 --- a/rbutil/rbutilqt/irivertools/md5sum.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * Module: rbutil - * File: md5sum.cpp - * - * Copyright (C) 2007 Dominik Wenger - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2001-2003 Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "md5sum.h" - - -#define GET_UINT32(n,b,i) \ -{ \ - (n) = ( (uint32) (b)[(i) ] ) \ - | ( (uint32) (b)[(i) + 1] << 8 ) \ - | ( (uint32) (b)[(i) + 2] << 16 ) \ - | ( (uint32) (b)[(i) + 3] << 24 ); \ -} - -#define PUT_UINT32(n,b,i) \ -{ \ - (b)[(i) ] = (uint8) ( (n) ); \ - (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ - (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ - (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ -} - -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -void md5_process( md5_context *ctx, uint8 data[64] ) -{ - uint32 X[16], A, B, C, D; - - GET_UINT32( X[0], data, 0 ); - GET_UINT32( X[1], data, 4 ); - GET_UINT32( X[2], data, 8 ); - GET_UINT32( X[3], data, 12 ); - GET_UINT32( X[4], data, 16 ); - GET_UINT32( X[5], data, 20 ); - GET_UINT32( X[6], data, 24 ); - GET_UINT32( X[7], data, 28 ); - GET_UINT32( X[8], data, 32 ); - GET_UINT32( X[9], data, 36 ); - GET_UINT32( X[10], data, 40 ); - GET_UINT32( X[11], data, 44 ); - GET_UINT32( X[12], data, 48 ); - GET_UINT32( X[13], data, 52 ); - GET_UINT32( X[14], data, 56 ); - GET_UINT32( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F -#undef S -#undef P - - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -void md5_update( md5_context *ctx, uint8 *input, uint32 length ) -{ - uint32 left, fill; - - if( ! length ) return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += length; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < length ) - ctx->total[1]++; - - if( left && length >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - md5_process( ctx, ctx->buffer ); - length -= fill; - input += fill; - left = 0; - } - - while( length >= 64 ) - { - md5_process( ctx, input ); - length -= 64; - input += 64; - } - - if( length ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, length ); - } -} - -static uint8 md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void md5_finish( md5_context *ctx, uint8 digest[16] ) -{ - uint32 last, padn; - uint32 high, low; - uint8 msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32( low, msglen, 0 ); - PUT_UINT32( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_UINT32( ctx->state[0], digest, 0 ); - PUT_UINT32( ctx->state[1], digest, 4 ); - PUT_UINT32( ctx->state[2], digest, 8 ); - PUT_UINT32( ctx->state[3], digest, 12 ); -} - -int FileMD5(QString name, char *md5) -{ - int i, read; - md5_context ctx; - unsigned char md5sum[16]; - unsigned char block[32768]; - - QFile file(name); - - if (!file.open(QIODevice::ReadOnly)) { - return 0; - } - md5_starts(&ctx); - while ( !file.atEnd() ) { - read = file.read((char*)block, sizeof(block)); - md5_update(&ctx, block, read); - } - file.close(); - md5_finish(&ctx, md5sum); - for (i = 0; i < 16; ++i) - { - sprintf(md5 + 2*i, "%02x", md5sum[i]); - } - return 1; -} diff --git a/rbutil/rbutilqt/irivertools/md5sum.h b/rbutil/rbutilqt/irivertools/md5sum.h deleted file mode 100644 index 45cc734034..0000000000 --- a/rbutil/rbutilqt/irivertools/md5sum.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * Module: rbutil - * File: md5sum.h - * - * Copyright (C) 2007 Dominik Wenger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#ifndef MD5SUM_H_INCLUDED -#define MD5SUM_H_INCLUDED - -#ifndef uint8 -#define uint8 unsigned char -#endif - - -#ifndef uint32 -#define uint32 unsigned long int -#endif - -#include - -typedef struct -{ - uint32 total[2]; - uint32 state[4]; - uint8 buffer[64]; -} -md5_context; - -void md5_starts( md5_context *ctx ); -void md5_update( md5_context *ctx, uint8 *input, uint32 length ); -void md5_finish( md5_context *ctx, uint8 digest[16] ); - -int FileMD5(QString name, char *md5); - -#endif // MD5SUM_H_INCLUDED diff --git a/rbutil/rbutilqt/rbsettings.cpp b/rbutil/rbutilqt/rbsettings.cpp index d1f90ea7f6..6f8a6e69cc 100644 --- a/rbutil/rbutilqt/rbsettings.cpp +++ b/rbutil/rbutilqt/rbsettings.cpp @@ -245,6 +245,11 @@ QString RbSettings::curBootloaderName() return deviceSettingCurGet("bootloadername").toString(); } +QString RbSettings::curBootloaderFile() +{ + return deviceSettingCurGet("bootloaderfile").toString(); +} + QString RbSettings::curVoiceName() { return deviceSettingCurGet("voicename").toString(); @@ -623,3 +628,4 @@ void RbSettings::setEncoderNarrowband(QString enc,bool nb) { userSettingsGroupSet(enc,"narrowband",nb); } + diff --git a/rbutil/rbutilqt/rbsettings.h b/rbutil/rbutilqt/rbsettings.h index a3fcd2b00f..49bdb81a11 100644 --- a/rbutil/rbutilqt/rbsettings.h +++ b/rbutil/rbutilqt/rbsettings.h @@ -103,6 +103,7 @@ class RbSettings : public QObject QString curEncoder(); QString curTTS(); QString curResolution(); + QString curBootloaderFile(); int curTargetId(); //! Set Functions diff --git a/rbutil/rbutilqt/rbutil.ini b/rbutil/rbutilqt/rbutil.ini index f763a83f40..739bbb1ed2 100644 --- a/rbutil/rbutilqt/rbutil.ini +++ b/rbutil/rbutilqt/rbutil.ini @@ -167,8 +167,9 @@ name="iHP100 / iHP110" platform=h100 released=yes needsbootloader=yes -bootloadermethod=fwpatcher -bootloadername=bootloader-h100.bin +bootloadermethod=hex +bootloadername=/iriver/bootloader-h100.bin +bootloaderfile=/ihp_100.hex resolution=160x128x2 manualname=rockbox-h100 brand=Iriver @@ -182,8 +183,9 @@ name="iHP120 / iHP140 / H120 / H140" platform=h120 released=yes needsbootloader=yes -bootloadermethod=fwpatcher -bootloadername=bootloader-h120.bin +bootloadermethod=hex +bootloadername=/iriver/bootloader-h120.bin +bootloaderfile=/ihp_120.hex resolution=160x128x2 manualname=rockbox-h100 brand=Iriver @@ -197,8 +199,9 @@ name="H320 / H340" platform=h300 released=yes needsbootloader=yes -bootloadermethod=fwpatcher -bootloadername=bootloader-h300.bin +bootloadermethod=hex +bootloadername=/iriver/bootloader-h300.bin +bootloaderfile=/H300.hex resolution=220x176x16 manualname=rockbox-h300 brand=Iriver @@ -212,8 +215,9 @@ name="H10 (5 / 6GB) UMS" platform=h10_5gb released=yes needsbootloader=yes -bootloadermethod=h10 -bootloadername=H10.mi4 +bootloadermethod=mi4 +bootloadername=/iriver/H10.mi4 +bootloaderfile=/System/H10.mi4 resolution=128x128x16 manualname= brand=Iriver @@ -227,8 +231,9 @@ name="H10 (5 / 6GB) MTP" platform=h10_5gb released=yes needsbootloader=yes -bootloadermethod=h10 -bootloadername=H10_5GB-MTP/H10.mi4 +bootloadermethod=mi4 +bootloadername=/iriver/H10_5GB-MTP/H10.mi4 +bootloaderfile=/System/H10.mi4 resolution=128x128x16 manualname= brand=Iriver @@ -242,8 +247,9 @@ name="H10 (20GB)" platform=h10 released=yes needsbootloader=yes -bootloadermethod=h10 -bootloadername=H10_20GC.mi4 +bootloadermethod=mi4 +bootloadername=/iriver/H10_20GC.mi4 +bootloaderfile=/System/H10_20GC.mi4 resolution=160x128x16 manualname= brand=Iriver @@ -258,8 +264,8 @@ name="Ipod (1st / 2nd gen)" platform=ipod1g2g released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipod1g2g +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipod1g2g.ipod resolution=160x128x2 manualname= brand=Apple @@ -272,8 +278,8 @@ name="Ipod Colour / Photo / U2 (4th gen)" platform=ipodcolor released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodcolor +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodcolor.ipod resolution=220x176x16 manualname= brand=Apple @@ -286,8 +292,8 @@ name="Ipod Nano (1st gen)" platform=ipodnano released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodnano +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodnano.ipod resolution=176x132x16 manualname= brand=Apple @@ -301,8 +307,8 @@ name="Ipod (4th gen, greyscale)" platform=ipod4gray released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipod4g +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipod4g.ipod resolution=160x128x2 manualname= brand=Apple @@ -315,8 +321,8 @@ name="Ipod Video (5th gen) 30GB" platform=ipodvideo released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodvideo +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodvideo.ipod resolution=320x240x16 manualname= brand=Apple @@ -329,8 +335,8 @@ name="Ipod Video (5th gen) 60/80GB" platform=ipodvideo64mb released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodvideo +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodvideo.ipod resolution=320x240x16 manualname= brand=Apple @@ -344,8 +350,8 @@ name="Ipod (3rd gen)" platform=ipod3g released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipod3g +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipod3g.ipod resolution=160x128x2 manualname= brand=Apple @@ -359,8 +365,8 @@ name="Ipod Mini (1st gen)" platform=ipodmini1g released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodmini +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodmini.ipod resolution=138x110x2 manualname=rockbox-ipodmini2g brand=Apple @@ -373,8 +379,8 @@ name="Ipod Mini (2nd gen)" platform=ipodmini2g released=yes needsbootloader=yes -bootloadermethod=ipodpatcher -bootloadername=ipodmini2g +bootloadermethod=ipod +bootloadername=/ipod/bootloader-ipodmini2g.ipod resolution=138x110x2 manualname=rockbox-ipodmini2g brand=Apple @@ -387,8 +393,9 @@ name="iAudio X5 / X5L" platform=iaudiox5 released=yes needsbootloader=yes -bootloadermethod=iaudio -bootloadername=x5_fw.bin +bootloadermethod=file +bootloadername=/iaudio/x5_fw.bin +bootloaderfile=/FIRMWARE/x5_fw.bin resolution=160x128x16 manualname= brand=Cowon @@ -402,8 +409,9 @@ name="iAudio X5V" platform=iaudiox5 released=yes needsbootloader=yes -bootloadermethod=iaudio -bootloadername=x5v_fw.bin +bootloadermethod=file +bootloadername=/iaudio/x5v_fw.bin +bootloaderfile=/FIRMWARE/x5v_fw.bin resolution=160x128x2 manualname= brand=Cowon @@ -416,8 +424,9 @@ name="iAudio M5 / M5L" platform=iaudiom5 released=yes needsbootloader=yes -bootloadermethod=iaudio -bootloadername=m5_fw.bin +bootloadermethod=file +bootloadername=/iaudio/m5_fw.bin +bootloaderfile=/FIRMWARE/m5_fw.bin resolution=160x128x2 manualname= brand=Cowon @@ -431,8 +440,9 @@ name="iAudio M3 / M3L" platform=iaudiom3 released=no needsbootloader=yes -bootloadermethod=iaudio -bootloadername=cowon_m3.bin +bootloadermethod=file +bootloadername=/iaudio/cowon_m3.bin +bootloaderfile=/FIRMWARE/cowon_m3.bin resolution=128x96x2 manualname= brand=Cowon @@ -446,8 +456,9 @@ name="Gigabeat F / X" platform=gigabeatf released=yes needsbootloader=yes -bootloadermethod=gigabeatf -bootloadername=FWIMG01.DAT +bootloadermethod=file +bootloadername=/gigabeat/FWIMG01.DAT +bootloaderfile=/SYSTEM/FWIMG01.DAT resolution=240x320x16 manualname= brand=Toshiba @@ -461,8 +472,8 @@ name="Sansa E200" platform=sansae200 released=yes needsbootloader=yes -bootloadermethod=sansapatcher -bootloadername=PP5022.mi4 +bootloadermethod=sansa +bootloadername=/sandisk-sansa/e200/PP5022.mi4 resolution=176x220x16 manualname= brand=Sandisk @@ -478,8 +489,8 @@ name="Sansa C200" platform=sansac200 released=yes needsbootloader=yes -bootloadermethod=sansapatcher -bootloadername=firmware.mi4 +bootloadermethod=sansa +bootloadername=/sandisk-sansa/c200/firmware.mi4 resolution=132x80x16 manualname= brand=Sandisk @@ -493,8 +504,9 @@ name="m:robe100" platform=mrobe100 released=yes needsbootloader=yes -bootloadermethod=mrobe100 -bootloadername=pp5020.mi4 +bootloadermethod=mi4 +bootloadername=/olympus/mrobe100/pp5020.mi4 +bootloaderfile=/System/pp5020.mi4 resolution=160x128x1 manualname= brand=Olympus diff --git a/rbutil/rbutilqt/rbutilqt.cpp b/rbutil/rbutilqt/rbutilqt.cpp index ea1ec59de0..4f0e4b5994 100644 --- a/rbutil/rbutilqt/rbutilqt.cpp +++ b/rbutil/rbutilqt/rbutilqt.cpp @@ -28,15 +28,22 @@ #include "installtalkwindow.h" #include "createvoicewindow.h" #include "httpget.h" -#include "installbootloader.h" #include "installthemes.h" #include "uninstallwindow.h" -#include "browseof.h" #include "utils.h" #include "rbzip.h" #include "sysinfo.h" #include "detect.h" +#include "progressloggerinterface.h" + +#include "bootloaderinstallbase.h" +#include "bootloaderinstallmi4.h" +#include "bootloaderinstallhex.h" +#include "bootloaderinstallipod.h" +#include "bootloaderinstallsansa.h" +#include "bootloaderinstallfile.h" + #if defined(Q_OS_LINUX) #include #endif @@ -52,17 +59,19 @@ RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent) { absolutePath = qApp->applicationDirPath(); - - ui.setupUi(this); - + settings = new RbSettings(); settings->open(); HttpGet::setGlobalUserAgent("rbutil/"VERSION); + // init startup & autodetection + ui.setupUi(this); + updateSettings(); + downloadInfo(); m_gotInfo = false; - + m_auto = false; + // manual tab - updateSettings(); ui.radioPdf->setChecked(true); // info tab @@ -112,10 +121,6 @@ RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent) connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable())); #endif - initIpodpatcher(); - initSansapatcher(); - downloadInfo(); - } @@ -158,6 +163,8 @@ void RbUtilQt::downloadDone(bool error) { if(error) { qDebug() << "network error:" << daily->error(); + QMessageBox::critical(this, tr("Network error"), + tr("Can't get version information.")); return; } qDebug() << "network status:" << daily->error(); @@ -218,8 +225,9 @@ void RbUtilQt::downloadDone(int id, bool error) .arg(daily->errorString()); if(error) { QMessageBox::about(this, "Network Error", errorString); + m_networkerror = daily->errorString(); } - qDebug() << "downloadDone:" << id << error; + qDebug() << "downloadDone:" << id << "error:" << error; } @@ -428,6 +436,7 @@ bool RbUtilQt::smallInstallInner() { m_error = false; m_installed = false; + m_auto = true; if(!installBootloaderAuto()) return true; else @@ -436,6 +445,7 @@ bool RbUtilQt::smallInstallInner() while(!m_installed) QApplication::processEvents(); } + m_auto = false; if(m_error) return true; logger->undoAbort(); } @@ -452,6 +462,7 @@ bool RbUtilQt::smallInstallInner() QApplication::processEvents(); } + installBootloaderPost(false); return false; } @@ -580,82 +591,167 @@ void RbUtilQt::installBootloaderBtn() // create logger logger = new ProgressLoggerGui(this); - logger->show(); - + installBootloader(); } void RbUtilQt::installBootloader() { QString platform = settings->curPlatform(); + QString backupDestination = ""; + m_error = false; // create installer - blinstaller = new BootloaderInstaller(this); - - blinstaller->setMountPoint(settings->mountpoint()); - - blinstaller->setDevice(platform); - blinstaller->setBootloaderMethod(settings->curBootloaderMethod()); - blinstaller->setBootloaderName(settings->curBootloaderName()); - blinstaller->setBootloaderBaseUrl(settings->bootloaderUrl()); - blinstaller->setBootloaderInfoUrl(settings->bootloaderInfoUrl()); - if(!blinstaller->downloadInfo()) - { - logger->addItem(tr("Could not get the bootloader info file!"),LOGERROR); + BootloaderInstallBase *bl; + QString type = settings->curBootloaderMethod(); + if(type == "mi4") { + bl = new BootloaderInstallMi4(this); + } + else if(type == "hex") { + bl = new BootloaderInstallHex(this); + } + else if(type == "sansa") { + bl = new BootloaderInstallSansa(this); + } + else if(type == "ipod") { + bl = new BootloaderInstallIpod(this); + } + else if(type == "file") { + bl = new BootloaderInstallFile(this); + } + else { + logger->addItem(tr("No install method known."), LOGERROR); logger->abort(); - m_error = true; return; } - if(blinstaller->uptodate()) + // set bootloader filename. Do this now as installed() needs it. + QString blfile; + blfile = settings->mountpoint() + settings->curBootloaderFile(); + // special case for H10 pure: this player can have a different + // bootloader file filename. This is handled here to keep the install + // class clean, though having it here is also not the nicest solution. + if(settings->curPlatformName() == "h10_ums" + || settings->curPlatformName() == "h10_mtp") { + if(resolvePathCase(blfile).isEmpty()) + blfile = settings->mountpoint() + + settings->curBootloaderName().replace("H10", + "H10EMP", Qt::CaseInsensitive); + } + bl->setBlFile(blfile); + QUrl url(settings->bootloaderUrl() + settings->curBootloaderName()); + bl->setBlUrl(url); + bl->setLogfile(settings->mountpoint() + "/.rockbox/rbutil.log"); + + if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) { + if(QMessageBox::question(this, tr("Bootloader detected"), + tr("Bootloader already installed. Do you want to reinstall the bootloader?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + logger->close(); + m_error = true; + return; + } + } + else if(bl->installed() == BootloaderInstallBase::BootloaderOther + && bl->capabilities() & BootloaderInstallBase::Backup) { - int ret = QMessageBox::question(this, tr("Bootloader Installation"), - tr("The bootloader is already installed and up to date.\n" - "Do want to replace the current bootloader?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if(ret == QMessageBox::No) - { - logger->addItem(tr("Bootloader installation skipped!"), LOGINFO); - logger->abort(); - m_installed = true; - return; + QString targetFolder = settings->name(settings->curPlatform()) + + " Firmware Backup"; + // remove invalid character(s) + targetFolder.remove(QRegExp("[:/]")); + if(QMessageBox::question(this, tr("Create Bootloader backup"), + tr("You can create a backup of the original bootloader " + "file. Press \"Yes\" to select an output folder on your " + "computer to save the file to. The file will get placed " + "in a new folder \"%1\" created below the selected folder.\n" + "Press \"No\" to skip this step.").arg(targetFolder), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + BrowseDirtree tree(this, tr("Browse backup folder")); + tree.setDir(QDir::home()); + tree.exec(); + + backupDestination = tree.getSelected() + "/" + targetFolder; + qDebug() << backupDestination; + // backup needs to be done after the logger has been set up. } } - // if fwpatcher , ask for extra file - QString offirmware; - if(settings->curBootloaderMethod() == "fwpatcher") + if(bl->capabilities() & BootloaderInstallBase::NeedsFlashing) { - BrowseOF ofbrowser(this); - ofbrowser.setFile(settings->ofPath()); - if(ofbrowser.exec() == QDialog::Accepted) - { - offirmware = ofbrowser.getFile(); - qDebug() << offirmware; - if(!QFileInfo(offirmware).exists()) - { - logger->addItem(tr("Original Firmware Path is wrong!"),LOGERROR); - logger->abort(); - m_error = true; - return; - } - else - { - settings->setOfPath(offirmware); - settings->sync(); - } + int ret; + ret = QMessageBox::information(this, tr("Prerequisites"), + tr("Bootloader installation requires you to provide " + "a firmware file of the original firmware (hex file). " + "You need to download this file yourself due to legal " + "reasons. Please refer to the " + "manual and the " + "IriverBoot wiki page on " + "how to obtain this file.
" + "Press Ok to continue and browse your computer for the firmware " + "file."), + QMessageBox::Ok | QMessageBox::Abort); + if(ret != QMessageBox::Ok) { + m_error = true; + return; } - else - { - logger->addItem(tr("Original Firmware selection Canceled!"),LOGERROR); - logger->abort(); + // open dialog to browse to hex file + QString hexfile; + hexfile = QFileDialog::getOpenFileName(this, + tr("Select firmware file"), QDir::homePath(), "*.hex"); + if(!QFileInfo(hexfile).isReadable()) { + logger->addItem(tr("Error opening firmware file"), LOGERROR); m_error = true; return; } + ((BootloaderInstallHex*)bl)->setHexfile(hexfile); + } + + // the bootloader install class does NOT use any GUI stuff. + // All messages are passed via signals. + connect(bl, SIGNAL(done(bool)), logger, SLOT(abort())); + connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool))); + connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int))); + connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int))); + + // show logger and start install. + logger->show(); + if(!backupDestination.isEmpty()) { + if(!bl->backup(backupDestination)) { + if(QMessageBox::warning(this, tr("Backup error"), + tr("Could not create backup file. Continue?"), + QMessageBox::No | QMessageBox::Yes) + == QMessageBox::No) { + logger->abort(); + return; + } + } } - blinstaller->setOrigFirmwarePath(offirmware); - connect(blinstaller,SIGNAL(done(bool)),this,SLOT(installdone(bool))); - blinstaller->install(logger); + bl->install(); +} + +void RbUtilQt::installBootloaderPost(bool error) +{ + qDebug() << __func__ << error; + // if an error occured don't perform post install steps. + if(error) { + m_error = true; + return; + } + else + m_error = false; + + m_installed = true; + // end here if automated install + if(m_auto) + return; + + QString msg = BootloaderInstallBase::postinstallHints(settings->curPlatform()); + if(!msg.isEmpty()) { + QMessageBox::information(this, tr("Manual steps required"), msg); + logger->close(); + } + } void RbUtilQt::installFontsBtn() @@ -825,23 +921,52 @@ void RbUtilQt::uninstallBootloader(void) QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; // create logger ProgressLoggerGui* logger = new ProgressLoggerGui(this); + logger->setProgressVisible(false); logger->show(); - BootloaderInstaller blinstaller(this); - blinstaller.setMountPoint(settings->mountpoint()); - blinstaller.setDevice(settings->curPlatform()); - blinstaller.setBootloaderMethod(settings->curBootloaderMethod()); - blinstaller.setBootloaderName(settings->curBootloaderName()); - blinstaller.setBootloaderBaseUrl(settings->bootloaderUrl()); - blinstaller.setBootloaderInfoUrl(settings->bootloaderInfoUrl()); - if(!blinstaller.downloadInfo()) - { - logger->addItem(tr("Could not get the bootloader info file!"),LOGERROR); + QString platform = settings->curPlatform(); + + // create installer + BootloaderInstallBase *bl; + QString type = settings->curBootloaderMethod(); + if(type == "mi4") { + bl = new BootloaderInstallMi4(); + } + else if(type == "hex") { + bl = new BootloaderInstallHex(); + } + else if(type == "sansa") { + bl = new BootloaderInstallSansa(); + } + else if(type == "ipod") { + bl = new BootloaderInstallIpod(); + } + else if(type == "file") { + bl = new BootloaderInstallFile(); + } + else { + logger->addItem(tr("No uninstall method known."), LOGERROR); logger->abort(); return; } - blinstaller.uninstall(logger); + QString blfile = settings->mountpoint() + settings->curBootloaderFile(); + if(settings->curPlatformName() == "h10_ums" + || settings->curPlatformName() == "h10_mtp") { + if(resolvePathCase(blfile).isEmpty()) + blfile = settings->mountpoint() + + settings->curBootloaderName().replace("H10", + "H10EMP", Qt::CaseInsensitive); + } + bl->setBlFile(blfile); + + connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int))); + connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int))); + + int result; + result = bl->uninstall(); + + logger->abort(); } diff --git a/rbutil/rbutilqt/rbutilqt.h b/rbutil/rbutilqt/rbutilqt.h index 8eebe4318e..bf1f64e7b3 100644 --- a/rbutil/rbutilqt/rbutilqt.h +++ b/rbutil/rbutilqt/rbutilqt.h @@ -30,7 +30,7 @@ #include "httpget.h" #include "installzip.h" #include "progressloggergui.h" -#include "installbootloader.h" +#include "bootloaderinstallbase.h" #include "rbsettings.h" @@ -44,7 +44,7 @@ class RbUtilQt : public QMainWindow private: Ui::RbUtilQtFrm ui; RbSettings* settings; - + void initDeviceNames(void); QString deviceName(QString); QString platform; @@ -56,14 +56,15 @@ class RbUtilQt : public QMainWindow void updateManual(void); ProgressLoggerGui *logger; ZipInstaller *installer; - BootloaderInstaller* blinstaller; QUrl proxy(void); QMap versmap; bool chkConfig(bool); volatile bool m_installed; volatile bool m_error; + QString m_networkerror; bool m_gotInfo; + bool m_auto; private slots: void about(void); @@ -85,6 +86,7 @@ class RbUtilQt : public QMainWindow void installBootloaderBtn(void); bool installBootloaderAuto(void); void installBootloader(void); + void installBootloaderPost(bool error); void installFontsBtn(void); bool installFontsAuto(void); @@ -101,6 +103,7 @@ class RbUtilQt : public QMainWindow void downloadDone(int, bool); void downloadBleedingDone(bool); void downloadInfo(void); + void installVoice(void); void installThemes(void); void uninstall(void); diff --git a/rbutil/rbutilqt/rbutilqt.pro b/rbutil/rbutilqt/rbutilqt.pro index e989a35ef7..000ed07752 100644 --- a/rbutil/rbutilqt/rbutilqt.pro +++ b/rbutil/rbutilqt/rbutilqt.pro @@ -31,7 +31,7 @@ QMAKE_EXTRA_TARGETS += rbspeex PRE_TARGETDEPS += rbspeex # rule for creating ctags file -tags.commands = ctags -R --c++-kinds=+p --fields=+iaS --extra=+q $(SOURCES) +tags.commands = ctags -R --c++-kinds=+p --fields=+iaS --extra=+q $(SOURCES) tags.depends = $(SOURCES) QMAKE_EXTRA_TARGETS += tags @@ -51,21 +51,17 @@ SOURCES += rbutilqt.cpp \ zip/zip.cpp \ zip/unzip.cpp \ installzip.cpp \ - installbootloader.cpp \ progressloggergui.cpp \ installtalkwindow.cpp \ talkfile.cpp \ autodetection.cpp \ ../ipodpatcher/ipodpatcher.c \ ../sansapatcher/sansapatcher.c \ - irivertools/irivertools.cpp \ - irivertools/md5sum.cpp \ browsedirtree.cpp \ installthemes.cpp \ uninstall.cpp \ uninstallwindow.cpp \ utils.cpp \ - browseof.cpp \ preview.cpp \ encoders.cpp \ encodersgui.cpp \ @@ -78,9 +74,17 @@ SOURCES += rbutilqt.cpp \ rbsettings.cpp \ rbunzip.cpp \ rbzip.cpp \ + detect.cpp \ sysinfo.cpp \ - detect.cpp - + bootloaderinstallbase.cpp \ + bootloaderinstallmi4.cpp \ + bootloaderinstallhex.cpp \ + bootloaderinstallipod.cpp \ + bootloaderinstallsansa.cpp \ + bootloaderinstallfile.cpp \ + ../../tools/mkboot.c \ + ../../tools/iriver.c + HEADERS += rbutilqt.h \ install.h \ httpget.h \ @@ -92,7 +96,6 @@ HEADERS += rbutilqt.h \ zip/zip_p.h \ version.h \ installzip.h \ - installbootloader.h \ installtalkwindow.h \ talkfile.h \ autodetection.h \ @@ -103,18 +106,14 @@ HEADERS += rbutilqt.h \ ../ipodpatcher/parttypes.h \ ../sansapatcher/sansapatcher.h \ ../sansapatcher/sansaio.h \ - irivertools/irivertools.h \ - irivertools/md5sum.h \ irivertools/h100sums.h \ irivertools/h120sums.h \ irivertools/h300sums.h \ - irivertools/checksums.h \ browsedirtree.h \ installthemes.h \ uninstall.h \ uninstallwindow.h \ utils.h \ - browseof.h \ preview.h \ encoders.h \ encodersgui.h \ @@ -128,11 +127,19 @@ HEADERS += rbutilqt.h \ rbunzip.h \ rbzip.h \ sysinfo.h \ - detect.h - + detect.h \ + bootloaderinstallbase.h \ + bootloaderinstallmi4.h \ + bootloaderinstallhex.h \ + bootloaderinstallipod.h \ + bootloaderinstallsansa.h \ + bootloaderinstallfile.h \ + ../../tools/mkboot.h \ + ../../tools/iriver.h + # Needed by QT on Win INCLUDEPATH = . irivertools zip zlib ../ipodpatcher ../sansapatcher ../../tools/rbspeex ../../tools - + LIBS += -L../../tools/rbspeex -lrbspeex TEMPLATE = app @@ -158,7 +165,6 @@ FORMS += rbutilqtfrm.ui \ installtalkfrm.ui \ installthemesfrm.ui \ uninstallfrm.ui \ - browseoffrm.ui \ previewfrm.ui \ rbspeexcfgfrm.ui \ encexescfgfrm.ui \ -- cgit v1.2.3