summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2008-09-28 17:02:36 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2008-09-28 17:02:36 +0000
commit197c24c5d331703b8b1d743f5699263cd623df38 (patch)
tree9c054f54f43b0c788b0760adf08595fe48643afb
parent063d37b08f6110a250c1f1a70883c4c45705f7b8 (diff)
downloadrockbox-197c24c5d331703b8b1d743f5699263cd623df38.tar.gz
rockbox-197c24c5d331703b8b1d743f5699263cd623df38.zip
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
-rw-r--r--rbutil/rbutilqt/autodetection.cpp19
-rw-r--r--rbutil/rbutilqt/bootloaderinstallbase.cpp184
-rw-r--r--rbutil/rbutilqt/bootloaderinstallbase.h90
-rw-r--r--rbutil/rbutilqt/bootloaderinstallfile.cpp145
-rw-r--r--rbutil/rbutilqt/bootloaderinstallfile.h44
-rw-r--r--rbutil/rbutilqt/bootloaderinstallhex.cpp244
-rw-r--r--rbutil/rbutilqt/bootloaderinstallhex.h57
-rw-r--r--rbutil/rbutilqt/bootloaderinstallipod.cpp235
-rw-r--r--rbutil/rbutilqt/bootloaderinstallipod.h50
-rw-r--r--rbutil/rbutilqt/bootloaderinstallmi4.cpp140
-rw-r--r--rbutil/rbutilqt/bootloaderinstallmi4.h (renamed from rbutil/rbutilqt/browseof.h)38
-rw-r--r--rbutil/rbutilqt/bootloaderinstallsansa.cpp244
-rw-r--r--rbutil/rbutilqt/bootloaderinstallsansa.h48
-rw-r--r--rbutil/rbutilqt/browseof.cpp68
-rw-r--r--rbutil/rbutilqt/browseoffrm.ui112
-rw-r--r--rbutil/rbutilqt/install.h4
-rw-r--r--rbutil/rbutilqt/installbootloader.cpp1449
-rw-r--r--rbutil/rbutilqt/installbootloader.h127
-rw-r--r--rbutil/rbutilqt/irivertools/checksums.h41
-rw-r--r--rbutil/rbutilqt/irivertools/irivertools.cpp527
-rw-r--r--rbutil/rbutilqt/irivertools/irivertools.h55
-rw-r--r--rbutil/rbutilqt/irivertools/md5sum.cpp295
-rw-r--r--rbutil/rbutilqt/irivertools/md5sum.h52
-rw-r--r--rbutil/rbutilqt/rbsettings.cpp6
-rw-r--r--rbutil/rbutilqt/rbsettings.h1
-rw-r--r--rbutil/rbutilqt/rbutil.ini104
-rw-r--r--rbutil/rbutilqt/rbutilqt.cpp279
-rw-r--r--rbutil/rbutilqt/rbutilqt.h9
-rw-r--r--rbutil/rbutilqt/rbutilqt.pro38
29 files changed, 1811 insertions, 2894 deletions
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()
64 { 64 {
65 // do the file checking 65 // do the file checking
66 QDir dir(mountpoints.at(i)); 66 QDir dir(mountpoints.at(i));
67 qDebug() << "paths to check for player specific files:" << mountpoints;
67 if(dir.exists()) 68 if(dir.exists())
68 { 69 {
69 qDebug() << "file checking:" << mountpoints.at(i);
70 // check logfile first. 70 // check logfile first.
71 if(QFile(mountpoints.at(i) + "/.rockbox/rbutil.log").exists()) { 71 if(QFile(mountpoints.at(i) + "/.rockbox/rbutil.log").exists()) {
72 QSettings log(mountpoints.at(i) + "/.rockbox/rbutil.log", 72 QSettings log(mountpoints.at(i) + "/.rockbox/rbutil.log",
@@ -153,7 +153,10 @@ bool Autodetection::detect()
153 } 153 }
154 154
155 int n; 155 int n;
156 //try ipodpatcher 156 // try ipodpatcher
157 // initialize sector buffer. Needed.
158 ipod_sectorbuf = NULL;
159 ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE);
157 struct ipod_t ipod; 160 struct ipod_t ipod;
158 n = ipod_scan(&ipod); 161 n = ipod_scan(&ipod);
159 if(n == 1) { 162 if(n == 1) {
@@ -165,8 +168,13 @@ bool Autodetection::detect()
165 else { 168 else {
166 qDebug() << "ipodpatcher: no Ipod found." << n; 169 qDebug() << "ipodpatcher: no Ipod found." << n;
167 } 170 }
171 free(ipod_sectorbuf);
172 ipod_sectorbuf = NULL;
168 173
169 //try sansapatcher 174 // try sansapatcher
175 // initialize sector buffer. Needed.
176 sansa_sectorbuf = NULL;
177 sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
170 struct sansa_t sansa; 178 struct sansa_t sansa;
171 n = sansa_scan(&sansa); 179 n = sansa_scan(&sansa);
172 if(n == 1) { 180 if(n == 1) {
@@ -178,6 +186,8 @@ bool Autodetection::detect()
178 else { 186 else {
179 qDebug() << "sansapatcher: no Sansa found." << n; 187 qDebug() << "sansapatcher: no Sansa found." << n;
180 } 188 }
189 free(sansa_sectorbuf);
190 sansa_sectorbuf = NULL;
181 191
182 if(m_mountpoint.isEmpty() && m_device.isEmpty() && m_errdev.isEmpty() && m_incompat.isEmpty()) 192 if(m_mountpoint.isEmpty() && m_device.isEmpty() && m_errdev.isEmpty() && m_incompat.isEmpty())
183 return false; 193 return false;
@@ -288,7 +298,8 @@ QString Autodetection::resolveMountPoint(QString device)
288 } 298 }
289 299
290 } 300 }
291 return result + ":/"; 301 if(!result.isEmpty())
302 return result + ":/";
292#endif 303#endif
293 return QString(""); 304 return QString("");
294} 305}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20
21#include <QtCore>
22
23#include "bootloaderinstallbase.h"
24#include "utils.h"
25
26BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void)
27{
28 return BootloaderUnknown;
29}
30
31
32BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void)
33{
34 return 0;
35}
36
37
38void BootloaderInstallBase::downloadBlStart(QUrl source)
39{
40 m_http.setFile(&m_tempfile);
41 m_http.setCache(true);
42 connect(&m_http, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool)));
43 // connect the http read signal to our logProgess *signal*
44 // to immediately emit it without any helper function.
45 connect(&m_http, SIGNAL(dataReadProgress(int, int)),
46 this, SIGNAL(logProgress(int, int)));
47 m_http.getFile(source);
48}
49
50
51void BootloaderInstallBase::downloadReqFinished(int id, bool error)
52{
53 qDebug() << __FILE__ << "::" << __func__ << id << error;
54 qDebug() << "error:" << m_http.errorString();
55
56 downloadBlFinish(error);
57}
58
59
60void BootloaderInstallBase::downloadBlFinish(bool error)
61{
62 qDebug() << __FILE__ << "::" << __func__ << ": error =" << error;
63
64 // update progress bar
65 emit logProgress(100, 100);
66
67 if(m_http.httpResponse() != 200) {
68 emit logItem(tr("Download error: received HTTP error %1.")
69 .arg(m_http.errorString()), LOGERROR);
70 emit done(true);
71 return;
72 }
73 if(error) {
74 emit logItem(tr("Download error: %1")
75 .arg(m_http.error()), LOGERROR);
76 emit done(true);
77 return;
78 }
79 else if(m_http.isCached())
80 emit logItem(tr("Download finished (cache used)."), LOGOK);
81 else
82 emit logItem(tr("Download finished."), LOGOK);
83
84 m_blversion = m_http.timestamp();
85 emit downloadDone();
86}
87
88void BootloaderInstallBase::installBlfile(void)
89{
90 qDebug() << __FILE__ << __func__;
91}
92
93
94//! @brief backup OF file.
95//! @param to folder to write backup file to. Folder will get created.
96//! @return true on success, false on error.
97
98bool BootloaderInstallBase::backup(QString to)
99{
100 qDebug() << __func__;
101 QDir targetDir(".");
102 emit logItem(tr("Creating backup of original firmware file."), LOGINFO);
103 if(!targetDir.mkpath(to)) {
104 emit logItem(tr("Creating backup folder failed"), LOGERROR);
105 return false;
106 }
107 QString tofile = to + "/" + QFileInfo(m_blfile).fileName();
108 qDebug() << "trying to backup" << m_blfile << "to" << tofile;
109 if(!QFile::copy(resolvePathCase(m_blfile), tofile)) {
110 emit logItem(tr("Creating backup copy failed."), LOGERROR);
111 return false;
112 }
113 emit logItem(tr("Backup created."), LOGOK);
114 return true;
115}
116
117
118//! @brief log installation to logfile.
119//! @param mode action to perform. 0: add to log, 1: remove from log.
120//! @return 0 on success
121int BootloaderInstallBase::logInstall(LogMode mode)
122{
123 int result = 0;
124 QString section = m_blurl.path().section('/', -1);
125 QSettings s(m_logfile, QSettings::IniFormat, this);
126 emit logItem(tr("Creating installation log"), LOGINFO);
127
128 if(mode == LogAdd) {
129 s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate));
130 qDebug() << m_blversion.toString(Qt::ISODate);
131 }
132 else {
133 s.remove("Bootloader/" + section);
134 }
135 s.sync();
136
137 return result;
138}
139
140
141//! @brief Return post install hints string.
142//! @param model model string
143//! @return hints.
144QString BootloaderInstallBase::postinstallHints(QString model)
145{
146 bool hint = false;
147 QString msg = tr("Bootloader installation is almost complete. "
148 "Installation <b>requires</b> you to perform the "
149 "following steps manually:");
150
151 msg += tr("<ol>");
152 msg += tr("<li>Safely remove your player.</li>");
153 if(model == "h100" || model == "h120" || model == "h300") {
154 hint = true;
155 msg += tr("<li>Reboot your player into the original firmware.</li>"
156 "<li>Perform a firmware upgrade using the update functionality "
157 "of the original firmware. Please refer to your player's manual "
158 "on details.</li>"
159 "<li>After the firmware has been updated reboot your player.</li>");
160 }
161 if(model == "iaudiox5" || model == "iaudiom5"
162 || model == "iaudiox5v" || model == "iaudiom3") {
163 hint = true;
164 msg += tr("<li>Turn the player off</li>"
165 "<li>Insert the charger</li>");
166 }
167 if(model == "gigabeatf") {
168 hint = true;
169 msg += tr("<li>Unplug USB and power adaptors</li>"
170 "<li>Hold <i>Power</i> to turn the player off</li>"
171 "<li>Toggle the battery switch on the player</li>"
172 "<li>Hold <i>Power</i> to boot into Rockbox</li>");
173 }
174
175 msg += "</ol>";
176 msg += tr("<p><b>Note:</b> You can safely install other parts first, but "
177 "the above steps are <b>required</b> to finish the installation!</p>");
178
179 if(hint)
180 return msg;
181 else
182 return QString("");
183}
184
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef BOOTLOADERINSTALLBASE_H
21#define BOOTLOADERINSTALLBASE_H
22
23#include <QtCore>
24#include "progressloggerinterface.h"
25#include "httpget.h"
26
27
28class BootloaderInstallBase : public QObject
29{
30 Q_OBJECT
31
32 public:
33 enum Capability
34 { Install = 0x01, Uninstall = 0x02, Backup = 0x04,
35 IsFile = 0x08, IsRaw = 0x10, NeedsFlashing = 0x20,
36 CanCheckInstalled = 0x40, CanCheckVersion = 0x80 };
37 Q_DECLARE_FLAGS(Capabilities, Capability)
38
39 enum BootloaderType
40 { BootloaderNone, BootloaderRockbox, BootloaderOther, BootloaderUnknown };
41
42 BootloaderInstallBase(QObject *parent = 0) : QObject(parent)
43 { }
44
45 virtual bool install(void)
46 { return false; }
47 virtual bool uninstall(void)
48 { return false; }
49 virtual BootloaderType installed(void);
50 virtual Capabilities capabilities(void);
51 bool backup(QString to);
52
53 void setBlFile(QString f)
54 { m_blfile = f; }
55 void setBlUrl(QUrl u)
56 { m_blurl = u; }
57 void setLogfile(QString f)
58 { m_logfile = f; }
59
60 static QString postinstallHints(QString model);
61
62 protected slots:
63 void downloadReqFinished(int id, bool error);
64 void downloadBlFinish(bool error);
65 void installBlfile(void);
66 protected:
67 enum LogMode
68 { LogAdd, LogRemove };
69
70 void downloadBlStart(QUrl source);
71 int logInstall(LogMode mode);
72
73 HttpGet m_http; //! http download object
74 QString m_blfile; //! bootloader filename on player
75 QString m_logfile; //! file for installation log
76 QUrl m_blurl; //! bootloader download URL
77 QTemporaryFile m_tempfile; //! temporary file for download
78 QDateTime m_blversion; //! download timestamp used for version information
79
80 signals:
81 void downloadDone(void); //! internal signal sent when download finished.
82 void done(bool);
83 void logItem(QString, int); //! set logger item
84 void logProgress(int, int); //! set progress bar.
85};
86
87Q_DECLARE_OPERATORS_FOR_FLAGS(BootloaderInstallBase::Capabilities)
88
89#endif
90
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include <QtDebug>
22#include <QtDebug>
23#include "bootloaderinstallfile.h"
24#include "utils.h"
25
26
27BootloaderInstallFile::BootloaderInstallFile(QObject *parent)
28 : BootloaderInstallBase(parent)
29{
30}
31
32
33bool BootloaderInstallFile::install(void)
34{
35 emit logItem(tr("Downloading bootloader"), LOGINFO);
36 qDebug() << __func__;
37 downloadBlStart(m_blurl);
38 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
39 return true;
40}
41
42void BootloaderInstallFile::installStage2(void)
43{
44 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
45
46 // if an old bootloader is present (Gigabeat) move it out of the way.
47 QString fwfile(resolvePathCase(m_blfile));
48 if(!fwfile.isEmpty()) {
49 QString moved = resolvePathCase(m_blfile) + ".ORIG";
50 qDebug() << "renaming" << fwfile << "->" << moved;
51 QFile::rename(fwfile, moved);
52 }
53
54 // if no old file found resolve path without basename
55 QFileInfo fi(m_blfile);
56 QString absPath = resolvePathCase(fi.absolutePath());
57
58 // if it's not possible to locate the base path try to create it
59 if(absPath.isEmpty()) {
60 QStringList pathElements = m_blfile.split("/");
61 // remove filename from list and save last path element
62 pathElements.removeLast();
63 QString lastElement = pathElements.last();
64 // remove last path element for base
65 pathElements.removeLast();
66 QString basePath = pathElements.join("/");
67
68 // check for base and bail out if not found. Otherwise create folder.
69 absPath = resolvePathCase(basePath);
70 QDir d(absPath);
71 d.mkpath(lastElement);
72 absPath = resolvePathCase(fi.absolutePath());
73
74 if(absPath.isEmpty()) {
75 emit logItem(tr("Error accessing output folder"), LOGERROR);
76 emit done(true);
77 return;
78 }
79 }
80 fwfile = absPath + "/" + fi.fileName();
81
82 // place (new) bootloader
83 m_tempfile.open();
84 qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile;
85 m_tempfile.close();
86 m_tempfile.rename(fwfile);
87
88 emit logItem(tr("Bootloader successful installed"), LOGOK);
89 logInstall(LogAdd);
90
91 emit done(false);
92}
93
94
95bool BootloaderInstallFile::uninstall(void)
96{
97 qDebug() << __func__;
98 emit logItem(tr("Removing Rockbox bootloader"), LOGINFO);
99 // check if a .ORIG file is present, and allow moving it back.
100 QString origbl = resolvePathCase(m_blfile + ".ORIG");
101 if(origbl.isEmpty()) {
102 emit logItem(tr("No original firmware file found."), LOGERROR);
103 emit done(true);
104 return false;
105 }
106 QString fwfile = resolvePathCase(m_blfile);
107 if(!QFile::remove(fwfile)) {
108 emit logItem(tr("Can't remove Rockbox bootloader file."), LOGERROR);
109 emit done(true);
110 return false;
111 }
112 if(!QFile::rename(origbl, fwfile)) {
113 emit logItem(tr("Can't restore bootloader file."), LOGERROR);
114 emit done(true);
115 return false;
116 }
117 emit logItem(tr("Original bootloader restored successfully."), LOGOK);
118 logInstall(LogRemove);
119 emit done(false);
120
121 return true;
122}
123
124
125//! @brief check if bootloader is installed.
126//! @return BootloaderRockbox, BootloaderOther or BootloaderUnknown.
127BootloaderInstallBase::BootloaderType BootloaderInstallFile::installed(void)
128{
129 qDebug("%s()", __func__);
130 if(!resolvePathCase(m_blfile).isEmpty()
131 && !resolvePathCase(m_blfile + ".ORIG").isEmpty())
132 return BootloaderRockbox;
133 else if(!resolvePathCase(m_blfile).isEmpty())
134 return BootloaderOther;
135 else
136 return BootloaderUnknown;
137}
138
139
140BootloaderInstallBase::Capabilities BootloaderInstallFile::capabilities(void)
141{
142 qDebug() << __func__;
143 return Install | IsFile | CanCheckInstalled | Backup;
144}
145
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include "progressloggerinterface.h"
22#include "bootloaderinstallbase.h"
23
24//! install a bootloader by putting a single file on the player.
25// This installation method is used by Iaudio (firmware is flashed
26// automatically) and Gigabeat (Firmware is a file, OF needs to get
27// renamed).
28class BootloaderInstallFile : public BootloaderInstallBase
29{
30 Q_OBJECT
31
32 public:
33 BootloaderInstallFile(QObject *parent = 0);
34 bool install(void);
35 bool uninstall(void);
36 BootloaderInstallBase::BootloaderType installed(void);
37 Capabilities capabilities(void);
38
39 private slots:
40 void installStage2(void);
41
42 private:
43};
44
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallhex.h"
23
24#include "../../tools/iriver.h"
25#include "../../tools/mkboot.h"
26
27struct md5s {
28 const char* orig;
29 const char* patched;
30};
31
32struct md5s md5sums[] = {
33#include "irivertools/h100sums.h"
34 { 0, 0 },
35#include "irivertools/h120sums.h"
36 { 0, 0 },
37#include "irivertools/h300sums.h"
38 { 0, 0 }
39};
40
41
42BootloaderInstallHex::BootloaderInstallHex(QObject *parent)
43 : BootloaderInstallBase(parent)
44{
45}
46
47
48bool BootloaderInstallHex::install(void)
49{
50 if(m_hex.isEmpty())
51 return false;
52 m_hashindex = -1;
53
54 // md5sum hex file
55 emit logItem(tr("checking MD5 hash of input file ..."), LOGINFO);
56 QByteArray filedata;
57 // read hex file into QByteArray
58 QFile file(m_hex);
59 file.open(QIODevice::ReadOnly);
60 filedata = file.readAll();
61 file.close();
62 QString hash = QCryptographicHash::hash(filedata,
63 QCryptographicHash::Md5).toHex();
64 qDebug() << "hexfile hash:" << hash;
65 if(file.error() != QFile::NoError) {
66 emit logItem(tr("Could not verify original firmware file"), LOGERROR);
67 emit done(true);
68 return false;
69 }
70 // check hash and figure model from md5sum
71 int i = sizeof(md5sums) / sizeof(struct md5s);
72 m_model = 4;
73 // 3: h300, 2: h120, 1: h100, 0:invalid
74 while(i--) {
75 if(md5sums[i].orig == 0)
76 m_model--;
77 if(!qstrcmp(md5sums[i].orig, hash.toAscii()))
78 break;
79 }
80 if(i < 0) {
81 emit logItem(tr("Firmware file not recognized."), LOGERROR);
82 return false;
83 }
84 else {
85 emit logItem(tr("MD5 hash ok"), LOGOK);
86 m_hashindex = i;
87 }
88
89 // check model agains download link.
90 QString match[] = {"", "h100", "h120", "h300"};
91 if(!m_blurl.path().contains(match[m_model])) {
92 emit logItem(tr("Firmware file doesn't match selected player."),
93 LOGERROR);
94 return false;
95 }
96
97 emit logItem(tr("Descrambling file"), LOGINFO);
98 m_descrambled.open();
99 int result;
100 result = iriver_decode(m_hex.toAscii().data(),
101 m_descrambled.fileName().toAscii().data(), FALSE, STRIP_NONE);
102 qDebug() << "iriver_decode" << result;
103
104 if(result < 0) {
105 emit logItem(tr("Error in descramble: %1").arg(scrambleError(result)), LOGERROR);
106 return false;
107 }
108
109 // download firmware from server
110 emit logItem(tr("Downloading bootloader file"), LOGINFO);
111 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
112
113 downloadBlStart(m_blurl);
114 return true;
115}
116
117
118void BootloaderInstallHex::installStage2(void)
119{
120 emit logItem(tr("Adding bootloader to firmware file"), LOGINFO);
121
122 // local temp file
123 QTemporaryFile tempbin;
124 tempbin.open();
125 QString tempbinName = tempbin.fileName();
126 tempbin.close();
127 // get temporary files filenames -- external tools need this.
128 m_descrambled.open();
129 QString descrambledName = m_descrambled.fileName();
130 m_descrambled.close();
131 m_tempfile.open();
132 QString tempfileName = m_tempfile.fileName();
133 m_tempfile.close();
134
135 int origin = 0;
136 switch(m_model) {
137 case 3:
138 origin = 0x3f0000;
139 break;
140 case 2:
141 case 1:
142 origin = 0x1f0000;
143 break;
144 default:
145 origin = 0;
146 break;
147 }
148
149 // iriver decode already done in stage 1
150 int result;
151 if((result = mkboot(descrambledName.toLocal8Bit().constData(),
152 tempfileName.toLocal8Bit().constData(),
153 tempbinName.toLocal8Bit().constData(), origin)) < 0)
154 {
155 QString error;
156 switch(result) {
157 case -1: error = tr("could not open input file"); break;
158 case -2: error = tr("reading header failed"); break;
159 case -3: error = tr("reading firmware failed"); break;
160 case -4: error = tr("can't open bootloader file"); break;
161 case -5: error = tr("reading bootloader file failed"); break;
162 case -6: error = tr("can't open output file"); break;
163 case -7: error = tr("writing output file failed"); break;
164 }
165 emit logItem(tr("Error in patching: %1").arg(error), LOGERROR);
166
167 emit done(true);
168 return;
169 }
170 QTemporaryFile targethex;
171 targethex.open();
172 QString targethexName = targethex.fileName();
173 if((result = iriver_encode(tempbinName.toLocal8Bit().constData(),
174 targethexName.toLocal8Bit().constData(), FALSE)) < 0)
175 {
176 emit logItem(tr("Error in scramble: %1").arg(scrambleError(result)), LOGERROR);
177 targethex.close();
178
179 emit done(true);
180 return;
181 }
182
183 // finally check the md5sum of the created file
184 QByteArray filedata;
185 filedata = targethex.readAll();
186 targethex.close();
187 QString hash = QCryptographicHash::hash(filedata,
188 QCryptographicHash::Md5).toHex();
189 qDebug() << "created hexfile hash:" << hash;
190
191 emit logItem(tr("Checking modified firmware file"), LOGINFO);
192 if(hash != QString(md5sums[m_hashindex].patched)) {
193 emit logItem(tr("Error: modified file checksum wrong"), LOGERROR);
194 targethex.remove();
195 emit done(true);
196 return;
197 }
198 // finally copy file to player
199 targethex.copy(m_blfile);
200
201 emit logItem(tr("Success: modified firmware file created"), LOGINFO);
202 logInstall(LogAdd);
203 emit done(false);
204
205 return;
206}
207
208
209bool BootloaderInstallHex::uninstall(void)
210{
211 emit logItem("Uninstallation not possible, only installation info removed", LOGINFO);
212 logInstall(LogRemove);
213 return false;
214}
215
216
217BootloaderInstallBase::BootloaderType BootloaderInstallHex::installed(void)
218{
219 return BootloaderUnknown;
220}
221
222
223BootloaderInstallBase::Capabilities BootloaderInstallHex::capabilities(void)
224{
225 return (Install | NeedsFlashing);
226}
227
228QString BootloaderInstallHex::scrambleError(int err)
229{
230 QString error;
231 switch(err) {
232 case -1: error = tr("Can't open input file"); break;
233 case -2: error = tr("Can't open output file"); break;
234 case -3: error = tr("invalid file: header length wrong"); break;
235 case -4: error = tr("invalid file: unrecognized header"); break;
236 case -5: error = tr("invalid file: \"length\" field wrong"); break;
237 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
238 case -7: error = tr("invalid file: internal checksum error"); break;
239 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
240 default: error = tr("unknown"); break;
241 }
242 return error;
243}
244
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef BOOTLOADERINSTALLHEX_H
21#define BOOTLOADERINSTALLHEX_H
22
23#include <QtCore>
24#include "bootloaderinstallbase.h"
25
26
27// bootloader installation derivate based on fwpatcher
28// This will patch a given hex file using (de)scramble / mkboot
29// and put it on the player.
30class BootloaderInstallHex : public BootloaderInstallBase
31{
32 Q_OBJECT
33
34 public:
35 BootloaderInstallHex(QObject *parent = 0);
36 bool install(void);
37 bool uninstall(void);
38 BootloaderInstallBase::BootloaderType installed(void);
39 Capabilities capabilities(void);
40
41 void setHexfile(QString h)
42 { m_hex = h; }
43
44 private:
45 QString m_hex;
46 int m_hashindex;
47 int m_model;
48 QTemporaryFile m_descrambled;
49 QString scrambleError(int);
50
51 private slots:
52 void installStage2(void);
53};
54
55
56#endif
57
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallipod.h"
23
24#include "../ipodpatcher/ipodpatcher.h"
25
26
27BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent)
28 : BootloaderInstallBase(parent)
29{
30 (void)parent;
31 // initialize sector buffer. ipod_sectorbuf is defined in ipodpatcher.
32 ipod_sectorbuf = NULL;
33 ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE);
34}
35
36
37BootloaderInstallIpod::~BootloaderInstallIpod()
38{
39 free(ipod_sectorbuf);
40}
41
42
43bool BootloaderInstallIpod::install(void)
44{
45 if(ipod_sectorbuf == NULL) {
46 emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
47 emit done(true);
48 return false;
49 }
50
51 struct ipod_t ipod;
52
53 int n = ipod_scan(&ipod);
54 if(n == -1) {
55 emit logItem(tr("No Ipod detected\n"
56 "Permission for disc access denied!"),
57 LOGERROR);
58 emit done(true);
59 return false;
60 }
61 if(n == 0) {
62 emit logItem(tr("No Ipod detected!"), LOGERROR);
63 emit done(true);
64 return false;
65 }
66
67 if(ipod.macpod) {
68 emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods.\n"
69 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR);
70 emit done(true);
71 return false;
72 }
73 emit logItem(tr("Downloading bootloader file"), LOGINFO);
74
75 downloadBlStart(m_blurl);
76 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
77 return true;
78}
79
80
81void BootloaderInstallIpod::installStage2(void)
82{
83 struct ipod_t ipod;
84
85 if(!ipodInitialize(&ipod)) {
86 emit done(true);
87 return;
88 }
89
90 read_directory(&ipod);
91
92 if(ipod.nimages <= 0) {
93 emit logItem(tr("Failed to read firmware directory"), LOGERROR);
94 emit done(true);
95 return;
96 }
97 if(getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) {
98 emit logItem(tr("Unknown version number in firmware (%1)").arg(
99 ipod.ipod_directory[0].vers), LOGERROR);
100 emit done(true);
101 return;
102 }
103
104 if(ipod.macpod) {
105 emit logItem(tr("Warning: This is a MacPod. Rockbox only runs on WinPods.\n"
106 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR);
107 emit done(true);
108 return;
109 }
110
111 if(ipod_reopen_rw(&ipod) < 0) {
112 emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR);
113 emit done(true);
114 return;
115 }
116
117 m_tempfile.open();
118 QString blfile = m_tempfile.fileName();
119 m_tempfile.close();
120 if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) {
121 emit logItem(tr("Successfull added bootloader"), LOGOK);
122 logInstall(LogAdd);
123 emit done(false);
124 ipod_close(&ipod);
125 return;
126 }
127 else {
128 emit logItem(tr("Failed to add bootloader"), LOGERROR);
129 ipod_close(&ipod);
130 emit done(true);
131 return;
132 }
133 qDebug() << "version installed:" << m_blversion.toString(Qt::ISODate);
134}
135
136
137bool BootloaderInstallIpod::uninstall(void)
138{
139 struct ipod_t ipod;
140
141 if(!ipodInitialize(&ipod)) {
142 emit done(true);
143 return false;
144 }
145
146 read_directory(&ipod);
147
148 if (ipod.nimages <= 0) {
149 emit logItem(tr("Failed to read firmware directory"),LOGERROR);
150 emit done(true);
151 return false;
152 }
153 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) {
154 emit logItem(tr("Unknown version number in firmware (%1)").arg(
155 ipod.ipod_directory[0].vers), LOGERROR);
156 emit done(true);
157 return false;
158 }
159
160 if (ipod_reopen_rw(&ipod) < 0) {
161 emit logItem(tr("Could not open Ipod in RW mode"), LOGERROR);
162 emit done(true);
163 return false;
164 }
165
166 if (ipod.ipod_directory[0].entryOffset == 0) {
167 emit logItem(tr("No bootloader detected."), LOGERROR);
168 emit done(true);
169 return false;
170 }
171
172 if (delete_bootloader(&ipod)==0) {
173 emit logItem(tr("Successfully removed Bootloader"), LOGOK);
174 logInstall(LogRemove);
175 emit done(false);
176 ipod_close(&ipod);
177 return true;
178 }
179 else {
180 emit logItem(tr("Removing the bootloader failed."), LOGERROR);
181 emit done(true);
182 ipod_close(&ipod);
183 return false;
184 }
185}
186
187
188BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void)
189{
190 struct ipod_t ipod;
191 BootloaderInstallBase::BootloaderType result = BootloaderRockbox;
192
193 if(!ipodInitialize(&ipod)) {
194 qDebug() << "BootloaderInstallIpod::installed(): BootloaderUnknown";
195 result = BootloaderUnknown;
196 }
197
198 if (ipod.ipod_directory[0].entryOffset == 0) {
199 qDebug() << "BootloaderInstallIpod::installed(): BootloaderOther";
200 result = BootloaderOther;
201 }
202 qDebug() << "BootloaderInstallIpod::installed(): BootloaderRockbox";
203 ipod_close(&ipod);
204
205 return result;
206}
207
208
209BootloaderInstallBase::Capabilities BootloaderInstallIpod::capabilities(void)
210{
211 return (Install | Uninstall | IsRaw);
212}
213
214
215bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod)
216{
217 ipod_scan(ipod);
218 if(ipod_open(ipod, 0) < 0) {
219 emit logItem(tr("Could not open Ipod"), LOGERROR);
220 return false;
221 }
222
223 if(read_partinfo(ipod, 0) < 0) {
224 emit logItem(tr("Could not read partition table"), LOGERROR);
225 return false;
226 }
227
228 if(ipod->pinfo[0].start == 0) {
229 emit logItem(tr("No firmware partition on disk"), LOGERROR);
230
231 return false;
232 }
233 return true;
234}
235
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef BOOTLOADERINSTALLIPOD_H
21#define BOOTLOADERINSTALLIPOD_H
22
23#include <QtCore>
24#include "bootloaderinstallbase.h"
25#include "../ipodpatcher/ipodpatcher.h"
26
27// installer class derivate for Ipod installation
28// based on ipodpatcher.
29class BootloaderInstallIpod : public BootloaderInstallBase
30{
31 Q_OBJECT
32
33 public:
34 BootloaderInstallIpod(QObject *parent = 0);
35 ~BootloaderInstallIpod();
36 bool install(void);
37 bool uninstall(void);
38 BootloaderInstallBase::BootloaderType installed(void);
39 Capabilities capabilities(void);
40
41 private slots:
42 void installStage2(void);
43
44 private:
45 bool ipodInitialize(struct ipod_t *);
46};
47
48
49#endif
50
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include <QtDebug>
22#include <QtDebug>
23#include "bootloaderinstallmi4.h"
24#include "utils.h"
25
26BootloaderInstallMi4::BootloaderInstallMi4(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29}
30
31
32bool BootloaderInstallMi4::install(void)
33{
34 emit logItem(tr("Downloading bootloader"), LOGINFO);
35 qDebug() << __func__;
36 downloadBlStart(m_blurl);
37 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
38 return true;
39}
40
41void BootloaderInstallMi4::installStage2(void)
42{
43 emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
44
45 // move old bootloader out of the way
46 QString fwfile(resolvePathCase(m_blfile));
47 QFile oldbl(fwfile);
48 QString moved = QFileInfo(resolvePathCase(m_blfile)).absolutePath()
49 + "/OF.mi4";
50 qDebug() << "renaming" << fwfile << "->" << moved;
51 oldbl.rename(moved);
52
53 // place new bootloader
54 m_tempfile.open();
55 qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile;
56 m_tempfile.close();
57 m_tempfile.rename(fwfile);
58
59 emit logItem(tr("Bootloader successful installed"), LOGOK);
60 logInstall(LogAdd);
61
62 emit done(true);
63}
64
65
66bool BootloaderInstallMi4::uninstall(void)
67{
68 qDebug() << __func__;
69
70 // check if it's actually a Rockbox bootloader
71 emit logItem(tr("Checking for Rockbox bootloader"), LOGINFO);
72 if(installed() != BootloaderRockbox) {
73 emit logItem(tr("No Rockbox bootloader found"), LOGERROR);
74 return false;
75 }
76
77 // check if OF file present
78 emit logItem(tr("Checking for original firmware file"), LOGINFO);
79 QString original = QFileInfo(resolvePathCase(m_blfile)).absolutePath()
80 + "/OF.mi4";
81
82 if(resolvePathCase(original).isEmpty()) {
83 emit logItem(tr("Error finding original firmware file"), LOGERROR);
84 return false;
85 }
86
87 // finally remove RB bootloader
88 QString resolved = resolvePathCase(m_blfile);
89 QFile blfile(resolved);
90 blfile.remove();
91
92 QFile oldbl(resolvePathCase(original));
93 oldbl.rename(m_blfile);
94 emit logItem(tr("Rockbox bootloader successful removed"), LOGINFO);
95 logInstall(LogRemove);
96 emit done(false);
97
98 return true;
99}
100
101
102//! check if a bootloader is installed and return its state.
103BootloaderInstallBase::BootloaderType BootloaderInstallMi4::installed(void)
104{
105 // for MI4 files we can check if we actually have a RB bootloader
106 // installed.
107 // RB bootloader has "RBBL" at 0x1f8 in the mi4 file.
108
109 // make sure to resolve case to prevent case issues
110 QString resolved;
111 resolved = resolvePathCase(m_blfile);
112 if(resolved.isEmpty()) {
113 qDebug("%s: BootloaderNone", __func__);
114 return BootloaderNone;
115 }
116
117 QFile f(resolved);
118 f.open(QIODevice::ReadOnly);
119 f.seek(0x1f8);
120 char magic[4];
121 f.read(magic, 4);
122 f.close();
123
124 if(!memcmp(magic, "RBBL", 4)) {
125 qDebug("%s: BootloaderRockbox", __func__);
126 return BootloaderRockbox;
127 }
128 else {
129 qDebug("%s: BootloaderOther", __func__);
130 return BootloaderOther;
131 }
132}
133
134
135BootloaderInstallBase::Capabilities BootloaderInstallMi4::capabilities(void)
136{
137 qDebug() << __func__;
138 return Install | Uninstall | Backup | IsFile | CanCheckInstalled | CanCheckVersion;
139}
140
diff --git a/rbutil/rbutilqt/browseof.h b/rbutil/rbutilqt/bootloaderinstallmi4.h
index 6c23f402b1..12529f2811 100644
--- a/rbutil/rbutilqt/browseof.h
+++ b/rbutil/rbutilqt/bootloaderinstallmi4.h
@@ -6,43 +6,39 @@
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * 8 *
9 * Copyright (C) 2007 by Dominik Wenger 9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id$ 10 * $Id:$
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * All files in this archive are subject to the GNU General Public License.
13 * modify it under the terms of the GNU General Public License 13 * See the file COPYING in the source tree root for full license agreement.
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 * 14 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied. 16 * KIND, either express or implied.
19 * 17 *
20 ****************************************************************************/ 18 ****************************************************************************/
21 19
22#ifndef BROWSEOF_H 20#include <QtCore>
23#define BROWSEOF_H 21#include "progressloggerinterface.h"
22#include "bootloaderinstallbase.h"
24 23
25#include <QtGui>
26#include "ui_browseoffrm.h"
27 24
28class BrowseOF : public QDialog 25// mi4 bootloader file based installation.
26// Puts the bootloader file to the correct location and
27// renames the OF to OF.mi4.
28class BootloaderInstallMi4 : public BootloaderInstallBase
29{ 29{
30 Q_OBJECT 30 Q_OBJECT
31 31
32 public: 32 public:
33 BrowseOF(QWidget *parent = 0); 33 BootloaderInstallMi4(QObject *parent = 0);
34 void setFile(QString file); 34 bool install(void);
35 QString getFile(); 35 bool uninstall(void);
36 36 BootloaderInstallBase::BootloaderType installed(void);
37 Capabilities capabilities(void);
37 38
38 private slots: 39 private slots:
39 void onBrowse(); 40 void installStage2(void);
40 41
41 private: 42 private:
42 Ui::BrowseOFFrm ui;
43
44 private slots:
45 void accept(void);
46}; 43};
47 44
48#endif
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtCore>
21#include "bootloaderinstallbase.h"
22#include "bootloaderinstallsansa.h"
23
24#include "../sansapatcher/sansapatcher.h"
25
26BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent)
27 : BootloaderInstallBase(parent)
28{
29 (void)parent;
30 // initialize sector buffer. sansa_sectorbuf is instantiated by
31 // sansapatcher.
32 sansa_sectorbuf = NULL;
33 sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
34}
35
36
37BootloaderInstallSansa::~BootloaderInstallSansa()
38{
39 free(sansa_sectorbuf);
40}
41
42
43/** Start bootloader installation.
44 */
45bool BootloaderInstallSansa::install(void)
46{
47 if(sansa_sectorbuf == NULL) {
48 emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
49 return false;
50 emit done(true);
51 }
52
53 emit logItem(tr("Searching for Sansa"), LOGINFO);
54
55 struct sansa_t sansa;
56
57 int n = sansa_scan(&sansa);
58 if(n == -1) {
59 emit logItem(tr("Permission for disc access denied!\n"
60 "This is required to install the bootloader"),
61 LOGERROR);
62 emit done(true);
63 return false;
64 }
65 if(n == 0) {
66 emit logItem(tr("No Sansa detected!"), LOGERROR);
67 emit done(true);
68 return false;
69 }
70 emit logItem(tr("Downloading bootloader file"), LOGINFO);
71
72 downloadBlStart(m_blurl);
73 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
74 return true;
75}
76
77
78/** Finish bootloader installation.
79 */
80void BootloaderInstallSansa::installStage2(void)
81{
82 struct sansa_t sansa;
83 sansa_scan(&sansa);
84
85 if(sansa_open(&sansa, 0) < 0) {
86 emit logItem(tr("could not open Sansa"), LOGERROR);
87 emit done(true);
88 return;
89 }
90
91 if(sansa_read_partinfo(&sansa, 0) < 0)
92 {
93 emit logItem(tr("could not read partitiontable"), LOGERROR);
94 emit done(true);
95 return;
96 }
97
98 int i = is_sansa(&sansa);
99 if(i < 0) {
100
101 emit logItem(tr("Disk is not a Sansa (Error: %1), aborting.").arg(i), LOGERROR);
102 emit done(true);
103 return;
104 }
105
106 if(sansa.hasoldbootloader) {
107 emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
108 "You must reinstall the original Sansa firmware before running\n"
109 "sansapatcher for the first time.\n"
110 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
111 LOGERROR);
112 emit done(true);
113 return;
114 }
115
116 if(sansa_reopen_rw(&sansa) < 0) {
117 emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
118 emit done(true);
119 return;
120 }
121
122 m_tempfile.open();
123 QString blfile = m_tempfile.fileName();
124 m_tempfile.close();
125 if(sansa_add_bootloader(&sansa, blfile.toLatin1().data(),
126 FILETYPE_MI4) == 0) {
127 emit logItem(tr("Successfully installed bootloader"), LOGOK);
128 logInstall(LogAdd);
129 emit done(false);
130 sansa_close(&sansa);
131 return;
132 }
133 else {
134 emit logItem(tr("Failed to install bootloader"), LOGERROR);
135 sansa_close(&sansa);
136 emit done(true);
137 return;
138 }
139
140}
141
142
143/** Uninstall the bootloader.
144 */
145bool BootloaderInstallSansa::uninstall(void)
146{
147 struct sansa_t sansa;
148
149 if(sansa_scan(&sansa) != 1) {
150 emit logItem(tr("Can't find Sansa"), LOGERROR);
151 emit done(true);
152 return false;
153 }
154
155 if (sansa_open(&sansa, 0) < 0) {
156 emit logItem(tr("Could not open Sansa"), LOGERROR);
157 emit done(true);
158 return false;
159 }
160
161 if (sansa_read_partinfo(&sansa,0) < 0) {
162 emit logItem(tr("Could not read partition table"), LOGERROR);
163 emit done(true);
164 return false;
165 }
166
167 int i = is_sansa(&sansa);
168 if(i < 0) {
169 emit logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i), LOGERROR);
170 emit done(true);
171 return false;
172 }
173
174 if (sansa.hasoldbootloader) {
175 emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
176 "You must reinstall the original Sansa firmware before running\n"
177 "sansapatcher for the first time.\n"
178 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
179 LOGERROR);
180 emit done(true);
181 return false;
182 }
183
184 if (sansa_reopen_rw(&sansa) < 0) {
185 emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
186 emit done(true);
187 return false;
188 }
189
190 if (sansa_delete_bootloader(&sansa)==0) {
191 emit logItem(tr("Successfully removed bootloader"), LOGOK);
192 logInstall(LogRemove);
193 emit done(false);
194 sansa_close(&sansa);
195 return true;
196 }
197 else {
198 emit logItem(tr("Removing bootloader failed."),LOGERROR);
199 emit done(true);
200 sansa_close(&sansa);
201 return false;
202 }
203
204 return false;
205}
206
207
208/** Check if bootloader is already installed
209 */
210BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void)
211{
212 struct sansa_t sansa;
213 int num;
214
215 if(sansa_scan(&sansa) != 1) {
216 return BootloaderUnknown;
217 }
218 if (sansa_open(&sansa, 0) < 0) {
219 return BootloaderUnknown;
220 }
221 if (sansa_read_partinfo(&sansa,0) < 0) {
222 return BootloaderUnknown;
223 }
224 if(is_sansa(&sansa) < 0) {
225 return BootloaderUnknown;
226 }
227 if((num = sansa_list_images(&sansa)) == 2) {
228 return BootloaderRockbox;
229 }
230 else if(num == 1) {
231 return BootloaderOther;
232 }
233 return BootloaderUnknown;
234
235}
236
237
238/** Get capabilities of subclass installer.
239 */
240BootloaderInstallBase::Capabilities BootloaderInstallSansa::capabilities(void)
241{
242 return (Install | Uninstall | IsRaw | CanCheckInstalled);
243}
244
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
10 * $Id:$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef BOOTLOADERINSTALLSANSA_H
21#define BOOTLOADERINSTALLSANSA_H
22
23#include <QtCore>
24#include "bootloaderinstallbase.h"
25
26
27// bootloader installation class for devices handled by sansapatcher.
28class BootloaderInstallSansa : public BootloaderInstallBase
29{
30 Q_OBJECT
31
32 public:
33 BootloaderInstallSansa(QObject *parent = 0);
34 ~BootloaderInstallSansa();
35 bool install(void);
36 bool uninstall(void);
37 BootloaderInstallBase::BootloaderType installed(void);
38 Capabilities capabilities(void);
39
40 private:
41
42 private slots:
43 void installStage2(void);
44};
45
46
47#endif
48
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <QtGui>
21
22#include "browseof.h"
23#include "browsedirtree.h"
24
25
26BrowseOF::BrowseOF(QWidget *parent) : QDialog(parent)
27{
28 ui.setupUi(this);
29 this->setModal(true);
30
31 connect(ui.browseOFButton,SIGNAL(clicked()),this,SLOT(onBrowse()));
32}
33
34void BrowseOF::setFile(QString file)
35{
36 ui.OFlineEdit->setText(file);
37}
38
39void BrowseOF::onBrowse()
40{
41 BrowseDirtree browser(this);
42 browser.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
43
44 if(QFileInfo(ui.OFlineEdit->text()).exists())
45 {
46 browser.setDir(ui.OFlineEdit->text());
47 }
48
49 if(browser.exec() == QDialog::Accepted)
50 {
51 qDebug() << browser.getSelected();
52 setFile(browser.getSelected());
53 }
54}
55
56QString BrowseOF::getFile()
57{
58 return ui.OFlineEdit->text();
59}
60
61void BrowseOF::accept()
62{
63 this->close();
64 setResult(QDialog::Accepted);
65}
66
67
68
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 @@
1<ui version="4.0" >
2 <class>BrowseOFFrm</class>
3 <widget class="QDialog" name="BrowseOFFrm" >
4 <property name="geometry" >
5 <rect>
6 <x>0</x>
7 <y>0</y>
8 <width>460</width>
9 <height>97</height>
10 </rect>
11 </property>
12 <property name="windowTitle" >
13 <string>Find original Firmware</string>
14 </property>
15 <layout class="QGridLayout" >
16 <item row="0" column="0" colspan="3" >
17 <widget class="QLabel" name="label" >
18 <property name="text" >
19 <string>Browse for a downloaded copy of the original firmware</string>
20 </property>
21 <property name="wordWrap" >
22 <bool>true</bool>
23 </property>
24 </widget>
25 </item>
26 <item row="1" column="0" colspan="2" >
27 <widget class="QLineEdit" name="OFlineEdit" />
28 </item>
29 <item row="1" column="2" >
30 <widget class="QPushButton" name="browseOFButton" >
31 <property name="text" >
32 <string>Browse</string>
33 </property>
34 </widget>
35 </item>
36 <item row="2" column="0" >
37 <spacer>
38 <property name="orientation" >
39 <enum>Qt::Horizontal</enum>
40 </property>
41 <property name="sizeHint" >
42 <size>
43 <width>241</width>
44 <height>28</height>
45 </size>
46 </property>
47 </spacer>
48 </item>
49 <item row="2" column="1" colspan="2" >
50 <layout class="QHBoxLayout" >
51 <item>
52 <widget class="QPushButton" name="buttonOk" >
53 <property name="text" >
54 <string>&amp;Ok</string>
55 </property>
56 <property name="icon" >
57 <iconset resource="rbutilqt.qrc" >:/icons/go-next.png</iconset>
58 </property>
59 </widget>
60 </item>
61 <item>
62 <widget class="QPushButton" name="buttonCancel" >
63 <property name="text" >
64 <string>&amp;Cancel</string>
65 </property>
66 <property name="icon" >
67 <iconset resource="rbutilqt.qrc" >:/icons/process-stop.png</iconset>
68 </property>
69 </widget>
70 </item>
71 </layout>
72 </item>
73 </layout>
74 </widget>
75 <resources>
76 <include location="rbutilqt.qrc" />
77 </resources>
78 <connections>
79 <connection>
80 <sender>buttonCancel</sender>
81 <signal>clicked()</signal>
82 <receiver>BrowseOFFrm</receiver>
83 <slot>reject()</slot>
84 <hints>
85 <hint type="sourcelabel" >
86 <x>224</x>
87 <y>355</y>
88 </hint>
89 <hint type="destinationlabel" >
90 <x>48</x>
91 <y>349</y>
92 </hint>
93 </hints>
94 </connection>
95 <connection>
96 <sender>buttonOk</sender>
97 <signal>clicked()</signal>
98 <receiver>BrowseOFFrm</receiver>
99 <slot>accept()</slot>
100 <hints>
101 <hint type="sourcelabel" >
102 <x>146</x>
103 <y>358</y>
104 </hint>
105 <hint type="destinationlabel" >
106 <x>74</x>
107 <y>357</y>
108 </hint>
109 </hints>
110 </connection>
111 </connections>
112</ui>
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
51 QMap<QString, QString> version; 51 QMap<QString, QString> version;
52 QString m_backupName; 52 QString m_backupName;
53 53
54 void changeBackupPath(QString);
55
54 private slots: 56 private slots:
55 void setCached(bool); 57 void setCached(bool);
56 void setDetailsCurrent(bool); 58 void setDetailsCurrent(bool);
57 void setDetailsStable(bool); 59 void setDetailsStable(bool);
58 void setDetailsArchived(bool); 60 void setDetailsArchived(bool);
59 void done(bool); 61 void done(bool);
60 void changeBackupPath(); 62 void changeBackupPath(void);
61 void backupCheckboxChanged(int state); 63 void backupCheckboxChanged(int state);
62 64
63}; 65};
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "installbootloader.h"
21#include "irivertools/checksums.h"
22#include "utils.h"
23
24BootloaderInstaller::BootloaderInstaller(QObject* parent): QObject(parent)
25{
26
27}
28
29void BootloaderInstaller::install(ProgressloggerInterface* dp)
30{
31 m_dp = dp;
32 m_install = true;
33 m_dp->addItem(tr("Starting bootloader installation"),LOGINFO);
34 connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool)));
35
36 if(m_bootloadermethod == "gigabeatf")
37 {
38 // connect internal signal
39 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
40 connect(this,SIGNAL(finish()),this,SLOT(gigabeatFinish()));
41 }
42 else if(m_bootloadermethod == "iaudio")
43 {
44 // connect internal signal
45 connect(this,SIGNAL(prepare()),this,SLOT(iaudioPrepare()));
46 connect(this,SIGNAL(finish()),this,SLOT(iaudioFinish()));
47 }
48 else if(m_bootloadermethod == "h10")
49 {
50 // connect internal signal
51 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
52 connect(this,SIGNAL(finish()),this,SLOT(h10Finish()));
53 }
54 else if(m_bootloadermethod == "ipodpatcher")
55 {
56 // connect internal signal
57 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
58 connect(this,SIGNAL(finish()),this,SLOT(ipodFinish()));
59 }
60 else if(m_bootloadermethod == "sansapatcher")
61 {
62 // connect internal signal
63 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
64 connect(this,SIGNAL(finish()),this,SLOT(sansaFinish()));
65 }
66 else if(m_bootloadermethod == "fwpatcher")
67 {
68 // connect internal signal
69 connect(this,SIGNAL(prepare()),this,SLOT(iriverPrepare()));
70 connect(this,SIGNAL(finish()),this,SLOT(iriverFinish()));
71 }
72 else if(m_bootloadermethod == "mrobe100")
73 {
74 // connect internal signal
75 connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare()));
76 connect(this,SIGNAL(finish()),this,SLOT(mrobe100Finish()));
77 }
78 else
79 {
80 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
81 emit done(true);
82 return;
83 }
84
85 emit prepare();
86}
87
88void BootloaderInstaller::uninstall(ProgressloggerInterface* dp)
89{
90 m_dp = dp;
91 m_install = false;
92 m_dp->addItem(tr("Starting bootloader uninstallation"),LOGINFO);
93 connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool)));
94
95 if(m_bootloadermethod == "gigabeatf")
96 {
97 // connect internal signal
98 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
99 }
100 else if(m_bootloadermethod == "iaudio")
101 {
102 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
103 emit done(true);
104 return;
105 }
106 else if(m_bootloadermethod == "iaudio")
107 {
108 // connect internal signal
109 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
110 }
111 else if(m_bootloadermethod == "ipodpatcher")
112 {
113 // connect internal signal
114 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
115 }
116 else if(m_bootloadermethod == "sansapatcher")
117 {
118 // connect internal signal
119 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
120 }
121 else if(m_bootloadermethod == "h10")
122 {
123 // connect internal signal
124 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
125 }
126 else if(m_bootloadermethod == "mrobe100")
127 {
128 // connect internal signal
129 connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare()));
130 }
131 else if(m_bootloadermethod == "fwpatcher")
132 {
133 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
134 emit done(true);
135 return;
136 }
137 else
138 {
139 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
140 emit done(true);
141 return;
142 }
143
144 emit prepare();
145}
146
147void BootloaderInstaller::downloadRequestFinished(int id, bool error)
148{
149 qDebug() << "BootloaderInstall::downloadRequestFinished" << id << error;
150 qDebug() << "error:" << getter->errorString();
151
152 downloadDone(error);
153}
154
155void BootloaderInstaller::downloadDone(bool error)
156{
157 qDebug() << "Install::downloadDone, error:" << error;
158
159 // update progress bar
160
161 int max = m_dp->getProgressMax();
162 if(max == 0) {
163 max = 100;
164 m_dp->setProgressMax(max);
165 }
166 m_dp->setProgressValue(max);
167 if(getter->httpResponse() != 200) {
168 m_dp->addItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR);
169 m_dp->abort();
170 emit done(true);
171 return;
172 }
173 if(error) {
174 m_dp->addItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR);
175 m_dp->abort();
176 emit done(true);
177 return;
178 }
179 else m_dp->addItem(tr("Download finished."),LOGOK);
180
181 emit finish();
182
183}
184
185
186void BootloaderInstaller::installEnded(bool error)
187{
188 (void) error;
189 m_dp->abort();
190}
191
192bool BootloaderInstaller::downloadInfo()
193{
194 // try to get the current build information
195 infodownloader = new HttpGet(this);
196
197 connect(infodownloader, SIGNAL(done(bool)), this, SLOT(infoDownloadDone(bool)));
198 connect(infodownloader, SIGNAL(requestFinished(int, bool)), this, SLOT(infoRequestFinished(int, bool)));
199
200 qDebug() << "downloading bootloader info";
201 infodownloader->setFile(&bootloaderInfo);
202 infodownloader->getFile(QUrl(m_bootloaderinfoUrl));
203
204 // block until its downloaded
205 qDebug() << "Waiting for Download finished";
206 infoDownloaded=false;
207 infoError = false;
208 while(!infoDownloaded )
209 QCoreApplication::processEvents();
210 return !infoError;
211}
212
213void BootloaderInstaller::infoDownloadDone(bool error)
214{
215 if(error)
216 {
217 qDebug() << "network error:" << infodownloader->error();
218 return;
219 }
220 qDebug() << "network status:" << infodownloader->error();
221
222 infoDownloaded = true;
223}
224
225void BootloaderInstaller::infoRequestFinished(int id, bool error)
226{
227
228 if(error)
229 {
230 QString errorString;
231 errorString = tr("Network error: %1. Please check your network and proxy settings.")
232 .arg(infodownloader->errorString());
233#ifndef CONSOLE
234 if(error) QMessageBox::about(NULL, "Network Error", errorString);
235#endif
236 qDebug() << "downloadDone:" << id << error;
237
238 infoError = true;
239 infoDownloaded = true;
240 }
241 qDebug() << "infoRequestFinished:" << id << error;
242}
243
244
245void BootloaderInstaller::createInstallLog()
246{
247 m_dp->addItem(tr("Creating installation log"),LOGINFO);
248 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
249
250 bootloaderInfo.open();
251 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
252 bootloaderInfo.close();
253 info.beginGroup(m_device);
254
255 installlog.beginGroup("Bootloader");
256 installlog.setValue("md5sum",info.value("md5sum").toString());
257 installlog.endGroup();
258 installlog.sync();
259}
260
261void BootloaderInstaller::removeInstallLog()
262{
263 m_dp->addItem(tr("Editing installation log"),LOGINFO);
264 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
265 installlog.beginGroup("Bootloader");
266 installlog.remove("md5sum");
267 installlog.endGroup();
268 installlog.sync();
269}
270
271
272bool BootloaderInstaller::uptodate()
273{
274 QString installedMd5;
275 QString serverMd5;
276
277 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
278 installlog.beginGroup("Bootloader");
279 installedMd5 = installlog.value("md5sum").toString();
280 installlog.endGroup();
281
282 if(installedMd5.isEmpty())
283 return false;
284 bootloaderInfo.open();
285 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
286 bootloaderInfo.close();
287 info.beginGroup(m_device);
288 serverMd5 = info.value("md5sum").toString();
289 info.endGroup();
290
291 if(installedMd5 != serverMd5)
292 return false;
293 else
294 return true;
295}
296
297/**************************************************
298*** gigabeat secific code
299***************************************************/
300
301void BootloaderInstaller::gigabeatPrepare()
302{
303 if(m_install) // Installation
304 {
305 QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername;
306
307 m_dp->addItem(tr("Downloading file %1.%2")
308 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
309
310 // temporary file needs to be opened to get the filename
311 downloadFile.open();
312 m_tempfilename = downloadFile.fileName();
313 downloadFile.close();
314 // get the real file.
315 getter = new HttpGet(this);
316 getter->setFile(&downloadFile);
317 // connect signals from HttpGet
318 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
319 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
320 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
321
322 getter->getFile(QUrl(url));
323 }
324 else //UnInstallation
325 {
326 QString firmware;
327 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT");
328 QString firmwareOrig = resolvePathCase(firmware.append(".ORIG"));
329
330 QFileInfo firmwareOrigFI(firmwareOrig);
331
332 // check if original firmware exists
333 if(!firmwareOrigFI.exists())
334 {
335 m_dp->addItem(tr("Could not find the Original Firmware at: %1")
336 .arg(firmwareOrig),LOGERROR);
337 emit done(true);
338 return;
339 }
340
341 QFile firmwareFile(firmware);
342 QFile firmwareOrigFile(firmwareOrig);
343
344 //remove modified firmware
345 if(!firmwareFile.remove())
346 {
347 m_dp->addItem(tr("Could not remove the Firmware at: %1")
348 .arg(firmware),LOGERROR);
349 emit done(true);
350 return;
351 }
352
353 // rename original firmware back
354 if(!firmwareOrigFile.rename(firmware))
355 {
356 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
357 .arg(firmwareOrig,firmware),LOGERROR);
358 emit done(true);
359 return;
360 }
361
362 removeInstallLog();
363
364 emit done(false); //success
365 }
366
367}
368
369void BootloaderInstaller::gigabeatFinish()
370{
371 // this step is only need for installation, so no code for uninstall here
372
373 m_dp->addItem(tr("Finishing bootloader install"),LOGINFO);
374
375 QString firmware;
376 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername);
377
378 QFileInfo firmwareFI(firmware);
379
380 // check if firmware exists
381 if(!firmwareFI.exists())
382 {
383 m_dp->addItem(tr("Could not find the Firmware at: %1")
384 .arg(firmware),LOGERROR);
385 emit done(true);
386 return;
387 }
388
389 QString firmwareOrig = firmware;
390 firmwareOrig.append(".ORIG");
391 QFileInfo firmwareOrigFI(firmwareOrig);
392
393 // rename and backup the firmware, if there is no original firmware there
394 if(!firmwareOrigFI.exists())
395 {
396 QFile firmwareFile(firmware);
397 //backup
398 QDir::home().mkdir("Gigabeat Original Firmware Backup");
399 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Gigabeat Original Firmware Backup/") + m_bootloadername);
400 firmwareFile.unsetError();
401 //rename
402 if(!firmwareFile.rename(firmwareOrig))
403 {
404 m_dp->addItem(tr("Could not rename: %1 to %2")
405 .arg(firmware,firmwareOrig),LOGERROR);
406 emit done(true);
407 return;
408 }
409 }
410 else // or remove the normal firmware, if the original is there
411 {
412 QFile firmwareFile(firmware);
413 firmwareFile.remove();
414 }
415
416 //copy the firmware
417 if(!downloadFile.copy(firmware))
418 {
419 m_dp->addItem(tr("Could not copy: %1 to %2")
420 .arg(m_tempfilename,firmware),LOGERROR);
421 emit done(true);
422 return;
423 }
424
425 downloadFile.remove();
426
427 createInstallLog();
428
429 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
430 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
431 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
432 m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO);
433 m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO);
434 m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO);
435 m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO);
436
437
438 m_dp->abort();
439
440 emit done(false); // success
441
442}
443
444/**************************************************
445*** iaudio secific code
446***************************************************/
447void BootloaderInstaller::iaudioPrepare()
448{
449
450 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
451
452 m_dp->addItem(tr("Downloading file %1.%2")
453 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
454
455 // temporary file needs to be opened to get the filename
456 downloadFile.open();
457 m_tempfilename = downloadFile.fileName();
458 downloadFile.close();
459 // get the real file.
460 getter = new HttpGet(this);
461 getter->setFile(&downloadFile);
462 getter->getFile(QUrl(url));
463 // connect signals from HttpGet
464 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
465 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
466 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
467}
468
469void BootloaderInstaller::iaudioFinish()
470{
471 QString firmware;
472 QDir dir(m_mountpoint + "/FIRMWARE/");
473 if(!dir.exists())
474 {
475 dir.mkpath(m_mountpoint + "/FIRMWARE/");
476 }
477 firmware = resolvePathCase(m_mountpoint + "/FIRMWARE/") + "/" + m_bootloadername;
478
479 //copy the firmware
480 if(!downloadFile.copy(firmware))
481 {
482 m_dp->addItem(tr("Could not copy: %1 to %2")
483 .arg(m_tempfilename,firmware),LOGERROR);
484 emit done(true);
485 return;
486 }
487
488 downloadFile.remove();
489
490 createInstallLog();
491
492 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
493 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
494 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
495 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
496 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
497
498 m_dp->abort();
499
500 emit done(false); // success
501
502}
503
504
505/**************************************************
506*** h10 secific code
507***************************************************/
508void BootloaderInstaller::h10Prepare()
509{
510 if(m_install) // Installation
511 {
512 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
513
514 m_dp->addItem(tr("Downloading file %1.%2")
515 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
516
517 // temporary file needs to be opened to get the filename
518 downloadFile.open();
519 m_tempfilename = downloadFile.fileName();
520 downloadFile.close();
521 // get the real file.
522 getter = new HttpGet(this);
523 getter->setFile(&downloadFile);
524 // connect signals from HttpGet
525 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
526 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
527 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
528
529 getter->getFile(QUrl(url));
530 }
531 else // Uninstallation
532 {
533
534 QString firmwarename = m_bootloadername.section('/', -1);
535
536 QString firmware;
537 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
538 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
539
540 QFileInfo firmwareFI(firmware);
541 if(!firmwareFI.exists()) //Firmware dosent exists on player
542 {
543 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/H10EMP.mi4");
544 //attempt other firmwarename
545 firmwareFI.setFile(firmware);
546 if(!firmwareFI.exists()) //Firmware dosent exists on player
547 {
548 m_dp->addItem(tr("Firmware does not exist: %1")
549 .arg(firmware),LOGERROR);
550 emit done(true);
551 return;
552 }
553 }
554
555 QFileInfo firmwareOrigFI(firmwareOrig);
556 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
557 {
558 m_dp->addItem(tr("Original Firmware does not exist: %1")
559 .arg(firmwareOrig),LOGERROR);
560 emit done(true);
561 return;
562 }
563
564 QFile firmwareFile(firmware);
565 QFile firmwareOrigFile(firmwareOrig);
566
567 //remove modified firmware
568 if(!firmwareFile.remove())
569 {
570 m_dp->addItem(tr("Could not remove the Firmware at: %1")
571 .arg(firmware),LOGERROR);
572 emit done(true);
573 return;
574 }
575
576 // rename original firmware back
577 if(!firmwareOrigFile.rename(firmware))
578 {
579 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
580 .arg(firmwareOrig,firmware),LOGERROR);
581 emit done(true);
582 return;
583 }
584
585 removeInstallLog();
586
587 emit done(false); //success
588
589 }
590}
591
592void BootloaderInstaller::h10Finish()
593{
594 QString firmwarename = m_bootloadername.section('/', -1);
595
596 QString firmware;
597 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
598 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
599
600 QFileInfo firmwareFI(firmware);
601
602 if(!firmwareFI.exists()) //Firmware dosent exists on player
603 {
604 firmware = resolvePathCase(m_mountpoint + "/SYSTEM") +"/H10EMP.mi4";
605 //attempt other firmwarename
606 firmwareFI.setFile(firmware);
607 if(!firmwareFI.exists()) //Firmware dosent exists on player
608 {
609 m_dp->addItem(tr("Firmware does not exist: %1")
610 .arg(firmware),LOGERROR);
611 emit done(true);
612 return;
613 }
614 }
615
616 QFileInfo firmwareOrigFI(firmwareOrig);
617
618 if(!firmwareOrigFI.exists())
619 {
620 QFile firmwareFile(firmware);
621
622 //backup
623 QDir::home().mkdir("Iriver H10 Original Firmware Backup");
624 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Iriver H10 Original Firmware Backup/") + m_bootloadername);
625 firmwareFile.unsetError();
626
627 //rename
628 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
629 {
630 m_dp->addItem(tr("Could not rename: %1 to %2")
631 .arg(firmware,firmwareOrig),LOGERROR);
632 emit done(true);
633 return;
634 }
635 }
636 else //there is already a original firmware
637 {
638 QFile firmwareFile(firmware);
639 firmwareFile.remove();
640 }
641 //copy the firmware
642 if(!downloadFile.copy(firmware))
643 {
644 m_dp->addItem(tr("Could not copy: %1 to %2")
645 .arg(m_tempfilename,firmware),LOGERROR);
646 emit done(true);
647 return;
648 }
649
650 downloadFile.remove();
651
652 createInstallLog();
653
654 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
655 m_dp->abort();
656
657 emit done(false); // success
658
659}
660
661
662
663/**************************************************
664*** mrobe100 secific code
665***************************************************/
666void BootloaderInstaller::mrobe100Prepare()
667{
668 if(m_install) // Installation
669 {
670 QString url = m_bootloaderUrlBase + "/olympus/mrobe100/" + m_bootloadername;
671
672 m_dp->addItem(tr("Downloading file %1.%2")
673 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
674
675 // temporary file needs to be opened to get the filename
676 downloadFile.open();
677 m_tempfilename = downloadFile.fileName();
678 downloadFile.close();
679 // get the real file.
680 getter = new HttpGet(this);
681 getter->setFile(&downloadFile);
682
683 // connect signals from HttpGet
684 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
685 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
686 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
687
688 getter->getFile(QUrl(url));
689 }
690 else // Uninstallation
691 {
692
693 QString firmwarename = m_bootloadername;
694
695 QString firmware;
696 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
697 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
698
699 QFileInfo firmwareFI(firmware);
700 if(!firmwareFI.exists()) //Firmware dosent exists on player
701 {
702 m_dp->addItem(tr("Firmware does not exist: %1")
703 .arg(firmware),LOGERROR);
704 emit done(true);
705 return;
706 }
707
708 QFileInfo firmwareOrigFI(firmwareOrig);
709 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
710 {
711 m_dp->addItem(tr("Original Firmware does not exist: %1")
712 .arg(firmwareOrig),LOGERROR);
713 emit done(true);
714 return;
715 }
716
717 QFile firmwareFile(firmware);
718 QFile firmwareOrigFile(firmwareOrig);
719
720 //remove modified firmware
721 if(!firmwareFile.remove())
722 {
723 m_dp->addItem(tr("Could not remove the Firmware at: %1")
724 .arg(firmware),LOGERROR);
725 emit done(true);
726 return;
727 }
728
729 // move original firmware back
730 if(!firmwareOrigFile.rename(firmware))
731 {
732 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
733 .arg(firmwareOrig,firmware),LOGERROR);
734 emit done(true);
735 return;
736 }
737
738 removeInstallLog();
739
740 emit done(false); //success
741
742 }
743}
744
745void BootloaderInstaller::mrobe100Finish()
746{
747 QString firmwarename = m_bootloadername;
748
749 QString firmware;
750 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
751 // NOTE: the filename for the OF may not exist yet, so resolve path only!
752 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
753
754 QFileInfo firmwareFI(firmware);
755
756 if(!firmwareFI.exists()) //Firmware dosent exists on player
757 {
758 m_dp->addItem(tr("Firmware does not exist: %1")
759 .arg(firmware),LOGERROR);
760 emit done(true);
761 return;
762 }
763
764 QFileInfo firmwareOrigFI(firmwareOrig);
765
766 if(!firmwareOrigFI.exists())
767 {
768 QFile firmwareFile(firmware);
769
770 //backup
771 QDir::home().mkdir("Olympus mrobe100 Original Firmware Backup");
772 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Olympus mrobe100 Original Firmware Backup/") + m_bootloadername);
773 firmwareFile.unsetError();
774 //rename
775 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
776 {
777 m_dp->addItem(tr("Could not rename: %1 to %2")
778 .arg(firmware,firmwareOrig),LOGERROR);
779 emit done(true);
780 return;
781 }
782 }
783 else //there is already a original firmware
784 {
785 QFile firmwareFile(firmware);
786 firmwareFile.remove();
787 }
788 //copy the firmware
789 if(!downloadFile.copy(firmware))
790 {
791 m_dp->addItem(tr("Could not copy: %1 to %2")
792 .arg(m_tempfilename,firmware),LOGERROR);
793 emit done(true);
794 return;
795 }
796
797 downloadFile.remove();
798
799 createInstallLog();
800
801 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
802 m_dp->abort();
803
804 emit done(false); // success
805}
806
807
808/**************************************************
809*** ipod secific code
810***************************************************/
811int verbose =0;
812// reserves memory for ipodpatcher
813bool initIpodpatcher()
814{
815 if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) return true;
816 else return false;
817}
818
819void BootloaderInstaller::ipodPrepare()
820{
821 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
822 struct ipod_t ipod;
823
824 int n = ipod_scan(&ipod);
825 if (n == 0)
826 {
827 m_dp->addItem(tr("No Ipods found"),LOGERROR);
828 emit done(true);
829 return;
830 }
831 if (n > 1)
832 {
833 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
834 emit done(true);
835 }
836
837 if(m_install) // Installation
838 {
839
840 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
841
842 m_dp->addItem(tr("Downloading file %1.%2")
843 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
844
845 // temporary file needs to be opened to get the filename
846 downloadFile.open();
847 m_tempfilename = downloadFile.fileName();
848 downloadFile.close();
849 // get the real file.
850 getter = new HttpGet(this);
851 getter->setFile(&downloadFile);
852
853 // connect signals from HttpGet
854 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
855 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
856 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
857
858 getter->getFile(QUrl(url));
859 }
860 else // Uninstallation
861 {
862 if (ipod_open(&ipod, 0) < 0)
863 {
864 m_dp->addItem(tr("could not open ipod"),LOGERROR);
865 emit done(true);
866 return;
867 }
868
869 if (read_partinfo(&ipod,0) < 0)
870 {
871 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
872 emit done(true);
873 return;
874 }
875
876 if (ipod.pinfo[0].start==0)
877 {
878 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
879
880 int i;
881 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
882 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
883 for ( i = 0; i < 4; i++ )
884 {
885 if (ipod.pinfo[i].start != 0)
886 {
887 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
888 i).arg(
889 ipod.pinfo[i].start).arg(
890 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
891 ipod.pinfo[i].size/sectors_per_MB).arg(
892 get_parttype(ipod.pinfo[i].type)).arg(
893 ipod.pinfo[i].type),LOGINFO);
894 }
895 }
896 emit done(true);
897 return;
898 }
899
900 read_directory(&ipod);
901
902 if (ipod.nimages <= 0)
903 {
904 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
905 emit done(true);
906 return;
907 }
908 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
909 {
910 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
911 ipod.ipod_directory[0].vers),LOGERROR);
912 emit done(true);
913 return;
914 }
915
916 if (ipod.macpod)
917 {
918 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
919 "this. Convert it to WinPod\n"
920 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
921 LOGWARNING);
922 emit done(true);
923 return;
924 }
925
926 if (ipod_reopen_rw(&ipod) < 0)
927 {
928 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
929 emit done(true);
930 return;
931 }
932
933 if (ipod.ipod_directory[0].entryOffset==0) {
934 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
935 emit done(true);
936 return;
937 }
938
939 if (delete_bootloader(&ipod)==0)
940 {
941 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
942 removeInstallLog();
943 emit done(false);
944 ipod_close(&ipod);
945 return;
946 }
947 else
948 {
949 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
950 emit done(true);
951 ipod_close(&ipod);
952 return;
953 }
954 }
955}
956
957void BootloaderInstaller::ipodFinish()
958{
959 struct ipod_t ipod;
960 ipod_scan(&ipod);
961
962 if (ipod_open(&ipod, 0) < 0)
963 {
964 m_dp->addItem(tr("could not open ipod"),LOGERROR);
965 emit done(true);
966 return;
967 }
968
969 if (read_partinfo(&ipod,0) < 0)
970 {
971 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
972 emit done(true);
973 return;
974 }
975
976 if (ipod.pinfo[0].start==0)
977 {
978 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
979
980 int i;
981 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
982
983 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
984
985 for ( i = 0; i < 4; i++ )
986 {
987 if (ipod.pinfo[i].start != 0)
988 {
989 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
990 i).arg(
991 ipod.pinfo[i].start).arg(
992 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
993 ipod.pinfo[i].size/sectors_per_MB).arg(
994 get_parttype(ipod.pinfo[i].type)).arg(
995 ipod.pinfo[i].type),LOGWARNING);
996 }
997 }
998 emit done(true);
999 return;
1000 }
1001
1002 read_directory(&ipod);
1003
1004 if (ipod.nimages <= 0)
1005 {
1006 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
1007 emit done(true);
1008 return;
1009 }
1010 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
1011 {
1012 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
1013 ipod.ipod_directory[0].vers),LOGERROR);
1014 emit done(true);
1015 return;
1016 }
1017
1018 if (ipod.macpod)
1019 {
1020 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
1021 "this. Convert it to WinPod\n"
1022 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
1023 LOGWARNING);
1024 emit done(true);
1025 return;
1026 }
1027
1028 if (ipod_reopen_rw(&ipod) < 0)
1029 {
1030 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
1031 emit done(true);
1032 return;
1033 }
1034
1035 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
1036 {
1037 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1038 createInstallLog();
1039 emit done(false);
1040 ipod_close(&ipod);
1041 return;
1042 }
1043 else
1044 {
1045 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1046 ipod_close(&ipod);
1047 emit done(true);
1048 return;
1049 }
1050}
1051
1052/**************************************************
1053*** sansa secific code
1054***************************************************/
1055// reserves memory for sansapatcher
1056bool initSansapatcher()
1057{
1058 if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) return true;
1059 else return false;
1060}
1061
1062
1063void BootloaderInstaller::sansaPrepare()
1064{
1065 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
1066 struct sansa_t sansa;
1067
1068 int n = sansa_scan(&sansa);
1069 if (n == 0)
1070 {
1071 m_dp->addItem(tr("No Sansa found"),LOGERROR);
1072 emit done(true);
1073 return;
1074 }
1075 if (n > 1)
1076 {
1077 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
1078 emit done(true);
1079 }
1080
1081 if(m_install) // Installation
1082 {
1083 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
1084 + QString(sansa.targetname) + "/" + m_bootloadername;
1085
1086 m_dp->addItem(tr("Downloading file %1.%2")
1087 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1088
1089 // temporary file needs to be opened to get the filename
1090 downloadFile.open();
1091 m_tempfilename = downloadFile.fileName();
1092 downloadFile.close();
1093 // get the real file.
1094 getter = new HttpGet(this);
1095 getter->setFile(&downloadFile);
1096
1097 // connect signals from HttpGet
1098 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1099 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
1100 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1101
1102 getter->getFile(QUrl(url));
1103 }
1104 else // Uninstallation
1105 {
1106
1107 if (sansa_open(&sansa, 0) < 0)
1108 {
1109 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1110 emit done(true);
1111 return;
1112 }
1113
1114 if (sansa_read_partinfo(&sansa,0) < 0)
1115 {
1116 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1117 emit done(true);
1118 return;
1119 }
1120
1121 int i = is_sansa(&sansa);
1122 if (i < 0) {
1123 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1124 emit done(true);
1125 return;
1126 }
1127
1128 if (sansa.hasoldbootloader)
1129 {
1130 m_dp->addItem(tr("********************************************\n"
1131 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1132 "You must reinstall the original Sansa firmware before running\n"
1133 "sansapatcher for the first time.\n"
1134 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1135 "*********************************************\n"),LOGERROR);
1136 emit done(true);
1137 return;
1138 }
1139
1140
1141 if (sansa_reopen_rw(&sansa) < 0)
1142 {
1143 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1144 emit done(true);
1145 return;
1146 }
1147
1148 if (sansa_delete_bootloader(&sansa)==0)
1149 {
1150 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
1151 removeInstallLog();
1152 emit done(false);
1153 sansa_close(&sansa);
1154 return;
1155 }
1156 else
1157 {
1158 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
1159 emit done(true);
1160 sansa_close(&sansa);
1161 return;
1162 }
1163 }
1164}
1165
1166void BootloaderInstaller::sansaFinish()
1167{
1168 struct sansa_t sansa;
1169 sansa_scan(&sansa);
1170
1171 if (sansa_open(&sansa, 0) < 0)
1172 {
1173 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1174 emit done(true);
1175 return;
1176 }
1177
1178 if (sansa_read_partinfo(&sansa,0) < 0)
1179 {
1180 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1181 emit done(true);
1182 return;
1183 }
1184
1185
1186 int i = is_sansa(&sansa);
1187 if (i < 0) {
1188
1189 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1190 emit done(true);
1191 return;
1192 }
1193
1194 if (sansa.hasoldbootloader)
1195 {
1196 m_dp->addItem(tr("********************************************\n"
1197 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1198 "You must reinstall the original Sansa firmware before running\n"
1199 "sansapatcher for the first time.\n"
1200 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1201 "*********************************************\n"),LOGERROR);
1202 emit done(true);
1203 return;
1204 }
1205
1206 if (sansa_reopen_rw(&sansa) < 0)
1207 {
1208 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1209 emit done(true);
1210 return;
1211 }
1212
1213 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1214 {
1215 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1216 createInstallLog();
1217 emit done(false);
1218 sansa_close(&sansa);
1219 return;
1220 }
1221 else
1222 {
1223 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1224 sansa_close(&sansa);
1225 emit done(true);
1226 return;
1227 }
1228
1229}
1230
1231/**************************************************
1232*** iriver /fwpatcher secific code
1233***************************************************/
1234
1235void BootloaderInstaller::iriverPrepare()
1236{
1237 char md5sum_str[32];
1238 if (!FileMD5(m_origfirmware, md5sum_str)) {
1239 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
1240 emit done(true);
1241 return;
1242 }
1243
1244 /* Check firmware against md5sums in h120sums and h100sums */
1245 series = 0;
1246 table_entry = intable(md5sum_str, &h120pairs[0],
1247 sizeof(h120pairs)/sizeof(struct sumpairs));
1248 if (table_entry >= 0) {
1249 series = 120;
1250 }
1251 else
1252 {
1253 table_entry = intable(md5sum_str, &h100pairs[0],
1254 sizeof(h100pairs)/sizeof(struct sumpairs));
1255 if (table_entry >= 0)
1256 {
1257 series = 100;
1258 }
1259 else
1260 {
1261 table_entry = intable(md5sum_str, &h300pairs[0],
1262 sizeof(h300pairs)/sizeof(struct sumpairs));
1263 if (table_entry >= 0)
1264 series = 300;
1265 }
1266 }
1267 if (series == 0)
1268 {
1269 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1270 emit done(true);
1271 return;
1272 }
1273
1274 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1275
1276 m_dp->addItem(tr("Downloading file %1.%2")
1277 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1278
1279 // temporary file needs to be opened to get the filename
1280 downloadFile.open();
1281 m_tempfilename = downloadFile.fileName();
1282 downloadFile.close();
1283 // get the real file.
1284 getter = new HttpGet(this);
1285 getter->setFile(&downloadFile);
1286
1287 // connect signals from HttpGet
1288 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1289 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
1290 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1291
1292 getter->getFile(QUrl(url));
1293}
1294
1295void BootloaderInstaller::iriverFinish()
1296{
1297 // Patch firmware
1298 char md5sum_str[32];
1299 struct sumpairs *sums = 0;
1300 int origin = 0;
1301
1302 /* get pointer to the correct bootloader.bin */
1303 switch(series) {
1304 case 100:
1305 sums = &h100pairs[0];
1306 origin = 0x1f0000;
1307 break;
1308 case 120:
1309 sums = &h120pairs[0];
1310 origin = 0x1f0000;
1311 break;
1312 case 300:
1313 sums = &h300pairs[0];
1314 origin = 0x3f0000;
1315 break;
1316 }
1317
1318 // temporary files needs to be opened to get the filename
1319 QTemporaryFile firmwareBin, newBin, newHex;
1320 firmwareBin.open();
1321 newBin.open();
1322 newHex.open();
1323 QString firmwareBinName = firmwareBin.fileName();
1324 QString newBinName = newBin.fileName();
1325 QString newHexName = newHex.fileName();
1326 firmwareBin.close();
1327 newBin.close();
1328 newHex.close();
1329
1330 // iriver decode
1331 int result;
1332 if ((result = iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE)) < 0)
1333 {
1334 QString error;
1335 switch(result) {
1336 case -1: error = tr("Can't open input file"); break;
1337 case -2: error = tr("Can't open output file"); break;
1338 case -3: error = tr("invalid file: header length wrong"); break;
1339 case -4: error = tr("invalid file: unrecognized header"); break;
1340 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1341 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1342 case -7: error = tr("invalid file: internal checksum error"); break;
1343 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1344 default: error = tr("unknown"); break;
1345 }
1346 m_dp->addItem(tr("Error in descramble: %1").arg(error), LOGERROR);
1347 firmwareBin.remove();
1348 newBin.remove();
1349 newHex.remove();
1350 emit done(true);
1351 return;
1352 }
1353 // mkboot
1354 if((result = mkboot(firmwareBinName, newBinName, m_tempfilename, origin)) < 0)
1355 {
1356 QString error;
1357 switch(result) {
1358 case -1: error = tr("could not open input file"); break;
1359 case -2: error = tr("reading header failed"); break;
1360 case -3: error = tr("reading firmware failed"); break;
1361 case -4: error = tr("can't open bootloader file"); break;
1362 case -5: error = tr("reading bootloader file failed"); break;
1363 case -6: error = tr("can't open output file"); break;
1364 case -7: error = tr("writing output file failed"); break;
1365 }
1366 m_dp->addItem(tr("Error in patching: %1").arg(error), LOGERROR);
1367
1368 firmwareBin.remove();
1369 newBin.remove();
1370 newHex.remove();
1371 emit done(true);
1372 return;
1373 }
1374 // iriver_encode
1375 if((result = iriver_encode(newBinName, newHexName, FALSE)) < 0)
1376 {
1377 QString error;
1378 switch(result) {
1379 case -1: error = tr("Can't open input file"); break;
1380 case -2: error = tr("Can't open output file"); break;
1381 case -3: error = tr("invalid file: header length wrong"); break;
1382 case -4: error = tr("invalid file: unrecognized header"); break;
1383 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1384 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1385 case -7: error = tr("invalid file: internal checksum error"); break;
1386 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1387 default: error = tr("unknown"); break;
1388 }
1389 m_dp->addItem(tr("Error in scramble: %1").arg(error), LOGERROR);
1390
1391 firmwareBin.remove();
1392 newBin.remove();
1393 newHex.remove();
1394 emit done(true);
1395 return;
1396 }
1397
1398 /* now md5sum it */
1399 if (!FileMD5(newHexName, md5sum_str))
1400 {
1401 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1402 firmwareBin.remove();
1403 newBin.remove();
1404 newHex.remove();
1405 emit done(true);
1406 return;
1407 }
1408 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1409 /* delete temp files */
1410 firmwareBin.remove();
1411 newBin.remove();
1412 }
1413
1414 // Load patched Firmware to player
1415 QString dest;
1416 if(series == 100)
1417 dest = m_mountpoint + "/ihp_100.hex";
1418 else if(series == 120)
1419 dest = m_mountpoint + "/ihp_120.hex";
1420 else if(series == 300)
1421 dest = m_mountpoint + "/H300.hex";
1422
1423 // copy file
1424 QFile destfile(dest);
1425 if(destfile.exists()) destfile.remove();
1426 if(!newHex.copy(dest))
1427 {
1428 m_dp->addItem(tr("Could not copy: %1 to %2")
1429 .arg(newHexName,dest),LOGERROR);
1430 emit done(true);
1431 return;
1432 }
1433
1434 downloadFile.remove();
1435 newHex.remove();
1436
1437 createInstallLog();
1438
1439 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1440 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1441 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1442 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1443 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1444 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1445 m_dp->abort();
1446
1447 emit done(false); // success
1448}
1449
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef INSTALLBOOTLOADER_H
23#define INSTALLBOOTLOADER_H
24
25#ifndef CONSOLE
26#include <QtGui>
27#else
28#include <QtCore>
29#endif
30
31#include "progressloggerinterface.h"
32#include "httpget.h"
33#include "irivertools/irivertools.h"
34
35#include "../ipodpatcher/ipodpatcher.h"
36#include "../sansapatcher/sansapatcher.h"
37
38bool initIpodpatcher();
39bool initSansapatcher();
40
41class BootloaderInstaller : public QObject
42{
43 Q_OBJECT
44
45public:
46 BootloaderInstaller(QObject* parent);
47 ~BootloaderInstaller() {}
48
49 void install(ProgressloggerInterface* dp);
50 void uninstall(ProgressloggerInterface* dp);
51
52 void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;}
53 void setDevice(QString device) {m_device= device;} //!< the current plattform
54 void setBootloaderMethod(QString method) {m_bootloadermethod= method;}
55 void setBootloaderName(QString name){m_bootloadername= name;}
56 void setBootloaderBaseUrl(QString baseUrl){m_bootloaderUrlBase = baseUrl;}
57 void setOrigFirmwarePath(QString path) {m_origfirmware = path;} //!< for iriver original firmware
58 void setBootloaderInfoUrl(QString url) {m_bootloaderinfoUrl =url; } //!< the url for the info file
59 bool downloadInfo(); //!< should be called before install/uninstall, blocks until downloaded.
60 bool uptodate(); //!< returns wether the bootloader is uptodate
61
62signals:
63 void done(bool error); //installation finished.
64
65signals: // internal signals. Dont use this from out side.
66 void prepare();
67 void finish();
68
69private slots:
70 void createInstallLog(); // adds the bootloader entry to the log
71 void removeInstallLog(); // removes the bootloader entry from the log
72
73 void downloadDone(bool);
74 void downloadRequestFinished(int, bool);
75 void infoDownloadDone(bool);
76 void infoRequestFinished(int, bool);
77 void installEnded(bool);
78
79 // gigabeat specific routines
80 void gigabeatPrepare();
81 void gigabeatFinish();
82
83 //iaudio specific routines
84 void iaudioPrepare();
85 void iaudioFinish();
86
87 //h10 specific routines
88 void h10Prepare();
89 void h10Finish();
90
91 //ipod specific routines
92 void ipodPrepare();
93 void ipodFinish();
94
95 //sansa specific routines
96 void sansaPrepare();
97 void sansaFinish();
98
99 //iriver specific routines
100 void iriverPrepare();
101 void iriverFinish();
102
103 //mrobe100 specific routines
104 void mrobe100Prepare();
105 void mrobe100Finish();
106
107private:
108
109 HttpGet *infodownloader;
110 QTemporaryFile bootloaderInfo;
111 volatile bool infoDownloaded;
112 volatile bool infoError;
113
114 QString m_mountpoint, m_device,m_bootloadermethod,m_bootloadername;
115 QString m_bootloaderUrlBase,m_tempfilename,m_origfirmware;
116 QString m_bootloaderinfoUrl;
117 bool m_install;
118
119 int series,table_entry; // for fwpatcher
120
121 HttpGet *getter;
122 QTemporaryFile downloadFile;
123
124 ProgressloggerInterface* m_dp;
125
126};
127#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: irivertools.h
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#ifndef CHECKSUMS_H
24#define CHECKSUMS_H
25
26/* precalculated checksums for H110/H115 */
27static struct sumpairs h100pairs[] = {
28#include "h100sums.h"
29};
30
31/* precalculated checksums for H120/H140 */
32static struct sumpairs h120pairs[] = {
33#include "h120sums.h"
34};
35
36/* precalculated checksums for H320/H340 */
37static struct sumpairs h300pairs[] = {
38#include "h300sums.h"
39};
40
41#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: irivertools.cpp
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <QtCore>
22#include "irivertools.h"
23
24const unsigned char munge[] = {
25 0x7a, 0x36, 0xc4, 0x43, 0x49, 0x6b, 0x35, 0x4e, 0xa3, 0x46, 0x25, 0x84,
26 0x4d, 0x73, 0x74, 0x61
27};
28
29const unsigned char header_modify[] = "* IHPFIRM-DECODED ";
30
31const char * const models[] = { "iHP-100", "iHP-120/iHP-140", "H300 series",
32 NULL };
33
34/* aligns with models array; expected min firmware size */
35const unsigned int firmware_minsize[] = { 0x100000, 0x100000, 0x200000 };
36/* aligns with models array; expected max firmware size */
37const unsigned int firmware_maxsize[] = { 0x200000, 0x200000, 0x400000 };
38
39const unsigned char header[][16] = {
40 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
41 { 0x20, 0x03, 0x08, 0x27, 0x24, 0x00, 0x02, 0x30, 0x19, 0x17, 0x65, 0x73,
42 0x85, 0x32, 0x83, 0x22 },
43 { 0x20, 0x04, 0x03, 0x27, 0x20, 0x50, 0x01, 0x70, 0x80, 0x30, 0x80, 0x06,
44 0x30, 0x19, 0x17, 0x65 }
45};
46
47/* begin mkboot.c excerpt */
48unsigned char image[0x400000 + 0x220 + 0x400000/0x200];
49
50int mkboot(QString infile, QString outfile, QString bootloader, int origin)
51{
52 int i;
53 int len,bllen;
54 int actual_length, total_length, binary_length, num_chksums;
55
56 memset(image, 0xff, sizeof(image));
57
58 /* First, read the iriver original firmware into the image */
59 QFile f(infile);
60 if(!f.open(QIODevice::ReadOnly))
61 {
62 // can't open input file
63 return -1;
64 }
65 i = f.read((char*)image,16);
66 if(i < 16) {
67 // reading header failed
68 return -2;
69 }
70
71 /* This is the length of the binary image without the scrambling
72 overhead (but including the ESTFBINR header) */
73 binary_length = image[4] + (image[5] << 8) +
74 (image[6] << 16) + (image[7] << 24);
75
76 /* Read the rest of the binary data, but not the checksum block */
77 len = binary_length+0x200-16;
78 i = f.read((char*)image+16, len);
79 if(i < len) {
80 // reading firmware failed
81 return -3;
82 }
83
84 f.close();
85 /* Now, read the boot loader into the image */
86 f.setFileName(bootloader);
87 if(!f.open(QIODevice::ReadOnly))
88 {
89 // can't open bootloader file
90 return -4;
91 }
92
93 bllen = f.size();
94
95 i = f.read((char*)image+0x220 + origin, bllen);
96 if(i < bllen) {
97 // reading bootloader file failed
98 return -5;
99 }
100
101 f.close();
102 f.setFileName(outfile);
103 if(!f.open(QIODevice::WriteOnly))
104 {
105 // can't open output file
106 return -6;
107 }
108
109 /* Patch the reset vector to start the boot loader */
110 image[0x220 + 4] = image[origin + 0x220 + 4];
111 image[0x220 + 5] = image[origin + 0x220 + 5];
112 image[0x220 + 6] = image[origin + 0x220 + 6];
113 image[0x220 + 7] = image[origin + 0x220 + 7];
114
115 /* This is the actual length of the binary, excluding all headers */
116 actual_length = origin + bllen;
117
118 /* Patch the ESTFBINR header */
119 image[0x20c] = (actual_length >> 24) & 0xff;
120 image[0x20d] = (actual_length >> 16) & 0xff;
121 image[0x20e] = (actual_length >> 8) & 0xff;
122 image[0x20f] = actual_length & 0xff;
123
124 image[0x21c] = (actual_length >> 24) & 0xff;
125 image[0x21d] = (actual_length >> 16) & 0xff;
126 image[0x21e] = (actual_length >> 8) & 0xff;
127 image[0x21f] = actual_length & 0xff;
128
129 /* This is the length of the binary, including the ESTFBINR header and
130 rounded up to the nearest 0x200 boundary */
131 binary_length = (actual_length + 0x20 + 0x1ff) & 0xfffffe00;
132
133 /* The number of checksums, i.e number of 0x200 byte blocks */
134 num_chksums = binary_length / 0x200;
135
136 /* The total file length, including all headers and checksums */
137 total_length = binary_length + num_chksums + 0x200;
138
139 /* Patch the scrambler header with the new length info */
140 image[0] = total_length & 0xff;
141 image[1] = (total_length >> 8) & 0xff;
142 image[2] = (total_length >> 16) & 0xff;
143 image[3] = (total_length >> 24) & 0xff;
144
145 image[4] = binary_length & 0xff;
146 image[5] = (binary_length >> 8) & 0xff;
147 image[6] = (binary_length >> 16) & 0xff;
148 image[7] = (binary_length >> 24) & 0xff;
149
150 image[8] = num_chksums & 0xff;
151 image[9] = (num_chksums >> 8) & 0xff;
152 image[10] = (num_chksums >> 16) & 0xff;
153 image[11] = (num_chksums >> 24) & 0xff;
154
155 i = f.write((char*)image,total_length);
156 if(i < total_length) {
157 // writing bootloader file failed
158 return -7;
159 }
160
161 f.close();
162
163 return 0;
164}
165
166/* end mkboot.c excerpt */
167
168
169int intable(char *md5, struct sumpairs *table, int len)
170{
171 int i;
172 for (i = 0; i < len; i++) {
173 if (strncmp(md5, table[i].unpatched, 32) == 0) {
174 return i;
175 }
176 }
177 return -1;
178}
179
180
181
182
183static int testheader( const unsigned char * const data )
184{
185 const unsigned char * const d = data+16;
186 const char * const * m = models;
187 int index = 0;
188 while( *m )
189 {
190 if( memcmp( header[ index ], d, 16 ) == 0 )
191 return index;
192 index++;
193 m++;
194 };
195 return -1;
196};
197
198static void modifyheader( unsigned char * data )
199{
200 const unsigned char * h = header_modify;
201 int i;
202 for( i=0; i<512; i++ )
203 {
204 if( *h == '\0' )
205 h = header_modify;
206 *data++ ^= *h++;
207 };
208};
209
210int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify,
211 enum striptype stripmode)
212{
213 QFile infile(infile_name);
214 QFile outfile(outfile_name);
215 int i = -1;
216 unsigned char headerdata[512];
217 unsigned long dwLength1, dwLength2, dwLength3, fp = 0;
218 unsigned char blockdata[16+16];
219 unsigned char out[16];
220 unsigned char newmunge;
221 signed long lenread;
222 int s = 0;
223 unsigned char * pChecksums, * ppChecksums = 0;
224 unsigned char ck;
225
226
227 if(!infile.open(QIODevice::ReadOnly))
228 {
229 // can't open input file
230 return -1;
231 }
232 if(!outfile.open(QIODevice::WriteOnly))
233 {
234 // can't open output file
235 return -2;
236 }
237 lenread = infile.read( (char*)headerdata, 512);
238 if( lenread != 512 )
239 {
240 // header length doesn't match
241 infile.close();
242 outfile.close();
243 return -3;
244 };
245
246 i = testheader( headerdata );
247 if( i == -1 )
248 {
249 // header unknown
250 infile.close();
251 outfile.close();
252 return -4;
253 };
254 fprintf( stderr, "Model %s\n", models[ i ] );
255
256 dwLength1 = headerdata[0] | (headerdata[1]<<8) |
257 (headerdata[2]<<16) | (headerdata[3]<<24);
258 dwLength2 = headerdata[4] | (headerdata[5]<<8) |
259 (headerdata[6]<<16) | (headerdata[7]<<24);
260 dwLength3 = headerdata[8] | (headerdata[9]<<8) |
261 (headerdata[10]<<16) | (headerdata[11]<<24);
262
263 if( dwLength1 < firmware_minsize[ i ] ||
264 dwLength1 > firmware_maxsize[ i ] ||
265 dwLength2 < firmware_minsize[ i ] ||
266 dwLength2 > dwLength1 ||
267 dwLength3 > dwLength1 ||
268 dwLength2>>9 != dwLength3 ||
269 dwLength2+dwLength3+512 != dwLength1 )
270 {
271 // file 'length' data is wrong
272 infile.close();
273 outfile.close();
274 return -5;
275 };
276
277 pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) );
278
279 if( modify )
280 {
281 modifyheader( headerdata );
282 };
283
284 if( stripmode == STRIP_NONE )
285 outfile.write( (char*)headerdata, 512);
286
287 memset( blockdata, 0, 16 );
288
289 ck = 0;
290 while( ( fp < dwLength2 ) &&
291 ( lenread = infile.read( (char*)blockdata+16, 16) == 16) )
292 {
293 fp += 16;
294
295 for( i=0; i<16; ++i )
296 {
297 newmunge = blockdata[16+i] ^ munge[i];
298 out[i] = newmunge ^ blockdata[i];
299 blockdata[i] = newmunge;
300 ck += out[i];
301 }
302
303 if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF )
304 {
305 outfile.write( (char*)out+4, 12);
306 outfile.write( (char*)out, 4);
307 }
308 else
309 {
310 if( ESTF_SIZE - fp < 16 )
311 {
312 memcpy( out+4, blockdata+16, 12 );
313 memcpy( out, blockdata+28, 4 );
314 outfile.write((char*) blockdata+16+ESTF_SIZE-fp, ESTF_SIZE-fp);
315 }
316 }
317
318
319 if( s == 496 )
320 {
321 s = 0;
322 memset( blockdata, 0, 16 );
323 *ppChecksums++ = ck;
324 ck = 0;
325 }
326 else
327 s+=16;
328 };
329
330 if( fp != dwLength2 )
331 {
332 // 'length2' field mismatch
333 infile.close();
334 outfile.close();
335 return -6;
336 };
337
338 fp = 0;
339 ppChecksums = pChecksums;
340 while( ( fp < dwLength3 ) &&
341 ( lenread = infile.read((char*) blockdata, 32 ) ) > 0 )
342 {
343 fp += lenread;
344 if( stripmode == STRIP_NONE )
345 outfile.write((char*) blockdata, lenread );
346 if( memcmp( ppChecksums, blockdata, lenread ) != 0 )
347 {
348 // file checksum wrong
349 infile.close();
350 outfile.close();
351 return -7;
352 };
353 ppChecksums += lenread;
354 };
355
356 if( fp != dwLength3 )
357 {
358 // 'length3' field mismatch
359 infile.close();
360 outfile.close();
361 return -8;
362 };
363
364
365 fprintf( stderr, "File decoded correctly and all checksums matched!\n" );
366 switch( stripmode )
367 {
368 default:
369 case STRIP_NONE:
370 fprintf(stderr, "Output file contains all headers and "
371 "checksums\n");
372 break;
373 case STRIP_HEADER_CHECKSUM:
374 fprintf( stderr, "NB: output file contains only ESTFBINR header"
375 " and decoded firmware code\n" );
376 break;
377 case STRIP_HEADER_CHECKSUM_ESTF:
378 fprintf( stderr, "NB: output file contains only raw decoded "
379 "firmware code\n" );
380 break;
381 };
382
383 infile.close();
384 outfile.close();
385 return 0;
386
387};
388
389int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify)
390{
391 QFile infile(infile_name);
392 QFile outfile(outfile_name);
393 int i = -1;
394 unsigned char headerdata[512];
395 unsigned long dwLength1, dwLength2, dwLength3, fp = 0;
396 unsigned char blockdata[16+16];
397 unsigned char out[16];
398 unsigned char newmunge;
399 signed long lenread;
400 int s = 0;
401 unsigned char * pChecksums, * ppChecksums;
402 unsigned char ck;
403
404 if(!infile.open(QIODevice::ReadOnly))
405 {
406 // can't open input file
407 return -1;
408 }
409 if(!outfile.open(QIODevice::WriteOnly))
410 {
411 // can't open output file
412 infile.close();
413 return -2;
414 }
415
416 lenread = infile.read((char*) headerdata, 512 );
417 if( lenread != 512 )
418 {
419 // header length error
420 infile.close();
421 outfile.close();
422 return -3;
423 };
424
425 if( modify )
426 {
427 modifyheader( headerdata ); /* reversible */
428 };
429
430 i = testheader( headerdata );
431 if( i == -1 )
432 {
433 // header verification error
434 infile.close();
435 outfile.close();
436 return -4;
437 };
438 fprintf( stderr, "Model %s\n", models[ i ] );
439
440 dwLength1 = headerdata[0] | (headerdata[1]<<8) |
441 (headerdata[2]<<16) | (headerdata[3]<<24);
442 dwLength2 = headerdata[4] | (headerdata[5]<<8) |
443 (headerdata[6]<<16) | (headerdata[7]<<24);
444 dwLength3 = headerdata[8] | (headerdata[9]<<8) |
445 (headerdata[10]<<16) | (headerdata[11]<<24);
446
447 if( dwLength1 < firmware_minsize[i] ||
448 dwLength1 > firmware_maxsize[i] ||
449 dwLength2 < firmware_minsize[i] ||
450 dwLength2 > dwLength1 ||
451 dwLength3 > dwLength1 ||
452 dwLength2+dwLength3+512 != dwLength1 )
453 {
454 // file 'length' error
455 infile.close();
456 outfile.close();
457 return -5;
458 };
459
460 pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) );
461
462 outfile.write( (char*)headerdata, 512);
463
464 memset( blockdata, 0, 16 );
465 ck = 0;
466 while( ( fp < dwLength2 ) &&
467 ( lenread = infile.read((char*) blockdata+16, 16) ) == 16 )
468 {
469 fp += 16;
470 for( i=0; i<16; ++i )
471 {
472 newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i];
473 out[i] = newmunge ^ munge[i];
474 ck += blockdata[16+i];
475 blockdata[i] = newmunge;
476 };
477 outfile.write( (char*)out, 16);
478
479 if( s == 496 )
480 {
481 s = 0;
482 memset( blockdata, 0, 16 );
483 *ppChecksums++ = ck;
484 ck = 0;
485 }
486 else
487 s+=16;
488 };
489
490 if( fp != dwLength2 )
491 {
492 // file 'length1' mismatch
493 infile.close();
494 outfile.close();
495 return -6;
496 };
497
498 /* write out remainder w/out applying descrambler */
499 fp = 0;
500 lenread = dwLength3;
501 ppChecksums = pChecksums;
502 while( ( fp < dwLength3) &&
503 ( lenread = outfile.write((char*) ppChecksums, lenread) ) > 0 )
504 {
505 fp += lenread;
506 ppChecksums += lenread;
507 lenread = dwLength3 - fp;
508 };
509
510 if( fp != dwLength3 )
511 {
512 // 'length2' field mismatch
513 infile.close();
514 outfile.close();
515 return -8;
516 };
517
518 fprintf( stderr, "File encoded successfully and checksum table built!\n" );
519
520 infile.close();
521 outfile.close();
522 return 0;
523
524};
525
526
527
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: irivertools.h
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23
24#ifndef IRIVERTOOLS_H_INCLUDED
25#define IRIVERTOOLS_H_INCLUDED
26
27#include <QtCore>
28
29#include "md5sum.h"
30
31#define ESTF_SIZE 32
32
33struct sumpairs {
34 const char *unpatched;
35 const char *patched;
36};
37
38
39enum striptype
40{
41 STRIP_NONE,
42 STRIP_HEADER_CHECKSUM,
43 STRIP_HEADER_CHECKSUM_ESTF
44};
45
46/* protos for iriver.c */
47
48int intable(char *md5, struct sumpairs *table, int len);
49
50int mkboot(QString infile, QString outfile,QString bootloader,int origin);
51int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify,
52 enum striptype stripmode);
53int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify);
54
55#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: md5sum.cpp
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22/*
23 * RFC 1321 compliant MD5 implementation
24 *
25 * Copyright (C) 2001-2003 Christophe Devine
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 */
41
42
43#include "md5sum.h"
44
45
46#define GET_UINT32(n,b,i) \
47{ \
48 (n) = ( (uint32) (b)[(i) ] ) \
49 | ( (uint32) (b)[(i) + 1] << 8 ) \
50 | ( (uint32) (b)[(i) + 2] << 16 ) \
51 | ( (uint32) (b)[(i) + 3] << 24 ); \
52}
53
54#define PUT_UINT32(n,b,i) \
55{ \
56 (b)[(i) ] = (uint8) ( (n) ); \
57 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
58 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
59 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
60}
61
62void md5_starts( md5_context *ctx )
63{
64 ctx->total[0] = 0;
65 ctx->total[1] = 0;
66
67 ctx->state[0] = 0x67452301;
68 ctx->state[1] = 0xEFCDAB89;
69 ctx->state[2] = 0x98BADCFE;
70 ctx->state[3] = 0x10325476;
71}
72
73void md5_process( md5_context *ctx, uint8 data[64] )
74{
75 uint32 X[16], A, B, C, D;
76
77 GET_UINT32( X[0], data, 0 );
78 GET_UINT32( X[1], data, 4 );
79 GET_UINT32( X[2], data, 8 );
80 GET_UINT32( X[3], data, 12 );
81 GET_UINT32( X[4], data, 16 );
82 GET_UINT32( X[5], data, 20 );
83 GET_UINT32( X[6], data, 24 );
84 GET_UINT32( X[7], data, 28 );
85 GET_UINT32( X[8], data, 32 );
86 GET_UINT32( X[9], data, 36 );
87 GET_UINT32( X[10], data, 40 );
88 GET_UINT32( X[11], data, 44 );
89 GET_UINT32( X[12], data, 48 );
90 GET_UINT32( X[13], data, 52 );
91 GET_UINT32( X[14], data, 56 );
92 GET_UINT32( X[15], data, 60 );
93
94#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
95
96#define P(a,b,c,d,k,s,t) \
97{ \
98 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
99}
100
101 A = ctx->state[0];
102 B = ctx->state[1];
103 C = ctx->state[2];
104 D = ctx->state[3];
105
106#define F(x,y,z) (z ^ (x & (y ^ z)))
107
108 P( A, B, C, D, 0, 7, 0xD76AA478 );
109 P( D, A, B, C, 1, 12, 0xE8C7B756 );
110 P( C, D, A, B, 2, 17, 0x242070DB );
111 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
112 P( A, B, C, D, 4, 7, 0xF57C0FAF );
113 P( D, A, B, C, 5, 12, 0x4787C62A );
114 P( C, D, A, B, 6, 17, 0xA8304613 );
115 P( B, C, D, A, 7, 22, 0xFD469501 );
116 P( A, B, C, D, 8, 7, 0x698098D8 );
117 P( D, A, B, C, 9, 12, 0x8B44F7AF );
118 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
119 P( B, C, D, A, 11, 22, 0x895CD7BE );
120 P( A, B, C, D, 12, 7, 0x6B901122 );
121 P( D, A, B, C, 13, 12, 0xFD987193 );
122 P( C, D, A, B, 14, 17, 0xA679438E );
123 P( B, C, D, A, 15, 22, 0x49B40821 );
124
125#undef F
126
127#define F(x,y,z) (y ^ (z & (x ^ y)))
128
129 P( A, B, C, D, 1, 5, 0xF61E2562 );
130 P( D, A, B, C, 6, 9, 0xC040B340 );
131 P( C, D, A, B, 11, 14, 0x265E5A51 );
132 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
133 P( A, B, C, D, 5, 5, 0xD62F105D );
134 P( D, A, B, C, 10, 9, 0x02441453 );
135 P( C, D, A, B, 15, 14, 0xD8A1E681 );
136 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
137 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
138 P( D, A, B, C, 14, 9, 0xC33707D6 );
139 P( C, D, A, B, 3, 14, 0xF4D50D87 );
140 P( B, C, D, A, 8, 20, 0x455A14ED );
141 P( A, B, C, D, 13, 5, 0xA9E3E905 );
142 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
143 P( C, D, A, B, 7, 14, 0x676F02D9 );
144 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
145
146#undef F
147
148#define F(x,y,z) (x ^ y ^ z)
149
150 P( A, B, C, D, 5, 4, 0xFFFA3942 );
151 P( D, A, B, C, 8, 11, 0x8771F681 );
152 P( C, D, A, B, 11, 16, 0x6D9D6122 );
153 P( B, C, D, A, 14, 23, 0xFDE5380C );
154 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
155 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
156 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
157 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
158 P( A, B, C, D, 13, 4, 0x289B7EC6 );
159 P( D, A, B, C, 0, 11, 0xEAA127FA );
160 P( C, D, A, B, 3, 16, 0xD4EF3085 );
161 P( B, C, D, A, 6, 23, 0x04881D05 );
162 P( A, B, C, D, 9, 4, 0xD9D4D039 );
163 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
164 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
165 P( B, C, D, A, 2, 23, 0xC4AC5665 );
166
167#undef F
168
169#define F(x,y,z) (y ^ (x | ~z))
170
171 P( A, B, C, D, 0, 6, 0xF4292244 );
172 P( D, A, B, C, 7, 10, 0x432AFF97 );
173 P( C, D, A, B, 14, 15, 0xAB9423A7 );
174 P( B, C, D, A, 5, 21, 0xFC93A039 );
175 P( A, B, C, D, 12, 6, 0x655B59C3 );
176 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
177 P( C, D, A, B, 10, 15, 0xFFEFF47D );
178 P( B, C, D, A, 1, 21, 0x85845DD1 );
179 P( A, B, C, D, 8, 6, 0x6FA87E4F );
180 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
181 P( C, D, A, B, 6, 15, 0xA3014314 );
182 P( B, C, D, A, 13, 21, 0x4E0811A1 );
183 P( A, B, C, D, 4, 6, 0xF7537E82 );
184 P( D, A, B, C, 11, 10, 0xBD3AF235 );
185 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
186 P( B, C, D, A, 9, 21, 0xEB86D391 );
187
188#undef F
189#undef S
190#undef P
191
192
193 ctx->state[0] += A;
194 ctx->state[1] += B;
195 ctx->state[2] += C;
196 ctx->state[3] += D;
197}
198
199void md5_update( md5_context *ctx, uint8 *input, uint32 length )
200{
201 uint32 left, fill;
202
203 if( ! length ) return;
204
205 left = ctx->total[0] & 0x3F;
206 fill = 64 - left;
207
208 ctx->total[0] += length;
209 ctx->total[0] &= 0xFFFFFFFF;
210
211 if( ctx->total[0] < length )
212 ctx->total[1]++;
213
214 if( left && length >= fill )
215 {
216 memcpy( (void *) (ctx->buffer + left),
217 (void *) input, fill );
218 md5_process( ctx, ctx->buffer );
219 length -= fill;
220 input += fill;
221 left = 0;
222 }
223
224 while( length >= 64 )
225 {
226 md5_process( ctx, input );
227 length -= 64;
228 input += 64;
229 }
230
231 if( length )
232 {
233 memcpy( (void *) (ctx->buffer + left),
234 (void *) input, length );
235 }
236}
237
238static uint8 md5_padding[64] =
239{
240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
244};
245
246void md5_finish( md5_context *ctx, uint8 digest[16] )
247{
248 uint32 last, padn;
249 uint32 high, low;
250 uint8 msglen[8];
251
252 high = ( ctx->total[0] >> 29 )
253 | ( ctx->total[1] << 3 );
254 low = ( ctx->total[0] << 3 );
255
256 PUT_UINT32( low, msglen, 0 );
257 PUT_UINT32( high, msglen, 4 );
258
259 last = ctx->total[0] & 0x3F;
260 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
261
262 md5_update( ctx, md5_padding, padn );
263 md5_update( ctx, msglen, 8 );
264
265 PUT_UINT32( ctx->state[0], digest, 0 );
266 PUT_UINT32( ctx->state[1], digest, 4 );
267 PUT_UINT32( ctx->state[2], digest, 8 );
268 PUT_UINT32( ctx->state[3], digest, 12 );
269}
270
271int FileMD5(QString name, char *md5)
272{
273 int i, read;
274 md5_context ctx;
275 unsigned char md5sum[16];
276 unsigned char block[32768];
277
278 QFile file(name);
279
280 if (!file.open(QIODevice::ReadOnly)) {
281 return 0;
282 }
283 md5_starts(&ctx);
284 while ( !file.atEnd() ) {
285 read = file.read((char*)block, sizeof(block));
286 md5_update(&ctx, block, read);
287 }
288 file.close();
289 md5_finish(&ctx, md5sum);
290 for (i = 0; i < 16; ++i)
291 {
292 sprintf(md5 + 2*i, "%02x", md5sum[i]);
293 }
294 return 1;
295}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: md5sum.h
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23
24#ifndef MD5SUM_H_INCLUDED
25#define MD5SUM_H_INCLUDED
26
27#ifndef uint8
28#define uint8 unsigned char
29#endif
30
31
32#ifndef uint32
33#define uint32 unsigned long int
34#endif
35
36#include <QtCore>
37
38typedef struct
39{
40 uint32 total[2];
41 uint32 state[4];
42 uint8 buffer[64];
43}
44md5_context;
45
46void md5_starts( md5_context *ctx );
47void md5_update( md5_context *ctx, uint8 *input, uint32 length );
48void md5_finish( md5_context *ctx, uint8 digest[16] );
49
50int FileMD5(QString name, char *md5);
51
52#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()
245 return deviceSettingCurGet("bootloadername").toString(); 245 return deviceSettingCurGet("bootloadername").toString();
246} 246}
247 247
248QString RbSettings::curBootloaderFile()
249{
250 return deviceSettingCurGet("bootloaderfile").toString();
251}
252
248QString RbSettings::curVoiceName() 253QString RbSettings::curVoiceName()
249{ 254{
250 return deviceSettingCurGet("voicename").toString(); 255 return deviceSettingCurGet("voicename").toString();
@@ -623,3 +628,4 @@ void RbSettings::setEncoderNarrowband(QString enc,bool nb)
623{ 628{
624 userSettingsGroupSet(enc,"narrowband",nb); 629 userSettingsGroupSet(enc,"narrowband",nb);
625} 630}
631
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
103 QString curEncoder(); 103 QString curEncoder();
104 QString curTTS(); 104 QString curTTS();
105 QString curResolution(); 105 QString curResolution();
106 QString curBootloaderFile();
106 int curTargetId(); 107 int curTargetId();
107 108
108 //! Set Functions 109 //! 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"
167platform=h100 167platform=h100
168released=yes 168released=yes
169needsbootloader=yes 169needsbootloader=yes
170bootloadermethod=fwpatcher 170bootloadermethod=hex
171bootloadername=bootloader-h100.bin 171bootloadername=/iriver/bootloader-h100.bin
172bootloaderfile=/ihp_100.hex
172resolution=160x128x2 173resolution=160x128x2
173manualname=rockbox-h100 174manualname=rockbox-h100
174brand=Iriver 175brand=Iriver
@@ -182,8 +183,9 @@ name="iHP120 / iHP140 / H120 / H140"
182platform=h120 183platform=h120
183released=yes 184released=yes
184needsbootloader=yes 185needsbootloader=yes
185bootloadermethod=fwpatcher 186bootloadermethod=hex
186bootloadername=bootloader-h120.bin 187bootloadername=/iriver/bootloader-h120.bin
188bootloaderfile=/ihp_120.hex
187resolution=160x128x2 189resolution=160x128x2
188manualname=rockbox-h100 190manualname=rockbox-h100
189brand=Iriver 191brand=Iriver
@@ -197,8 +199,9 @@ name="H320 / H340"
197platform=h300 199platform=h300
198released=yes 200released=yes
199needsbootloader=yes 201needsbootloader=yes
200bootloadermethod=fwpatcher 202bootloadermethod=hex
201bootloadername=bootloader-h300.bin 203bootloadername=/iriver/bootloader-h300.bin
204bootloaderfile=/H300.hex
202resolution=220x176x16 205resolution=220x176x16
203manualname=rockbox-h300 206manualname=rockbox-h300
204brand=Iriver 207brand=Iriver
@@ -212,8 +215,9 @@ name="H10 (5 / 6GB) UMS"
212platform=h10_5gb 215platform=h10_5gb
213released=yes 216released=yes
214needsbootloader=yes 217needsbootloader=yes
215bootloadermethod=h10 218bootloadermethod=mi4
216bootloadername=H10.mi4 219bootloadername=/iriver/H10.mi4
220bootloaderfile=/System/H10.mi4
217resolution=128x128x16 221resolution=128x128x16
218manualname= 222manualname=
219brand=Iriver 223brand=Iriver
@@ -227,8 +231,9 @@ name="H10 (5 / 6GB) MTP"
227platform=h10_5gb 231platform=h10_5gb
228released=yes 232released=yes
229needsbootloader=yes 233needsbootloader=yes
230bootloadermethod=h10 234bootloadermethod=mi4
231bootloadername=H10_5GB-MTP/H10.mi4 235bootloadername=/iriver/H10_5GB-MTP/H10.mi4
236bootloaderfile=/System/H10.mi4
232resolution=128x128x16 237resolution=128x128x16
233manualname= 238manualname=
234brand=Iriver 239brand=Iriver
@@ -242,8 +247,9 @@ name="H10 (20GB)"
242platform=h10 247platform=h10
243released=yes 248released=yes
244needsbootloader=yes 249needsbootloader=yes
245bootloadermethod=h10 250bootloadermethod=mi4
246bootloadername=H10_20GC.mi4 251bootloadername=/iriver/H10_20GC.mi4
252bootloaderfile=/System/H10_20GC.mi4
247resolution=160x128x16 253resolution=160x128x16
248manualname= 254manualname=
249brand=Iriver 255brand=Iriver
@@ -258,8 +264,8 @@ name="Ipod (1st / 2nd gen)"
258platform=ipod1g2g 264platform=ipod1g2g
259released=yes 265released=yes
260needsbootloader=yes 266needsbootloader=yes
261bootloadermethod=ipodpatcher 267bootloadermethod=ipod
262bootloadername=ipod1g2g 268bootloadername=/ipod/bootloader-ipod1g2g.ipod
263resolution=160x128x2 269resolution=160x128x2
264manualname= 270manualname=
265brand=Apple 271brand=Apple
@@ -272,8 +278,8 @@ name="Ipod Colour / Photo / U2 (4th gen)"
272platform=ipodcolor 278platform=ipodcolor
273released=yes 279released=yes
274needsbootloader=yes 280needsbootloader=yes
275bootloadermethod=ipodpatcher 281bootloadermethod=ipod
276bootloadername=ipodcolor 282bootloadername=/ipod/bootloader-ipodcolor.ipod
277resolution=220x176x16 283resolution=220x176x16
278manualname= 284manualname=
279brand=Apple 285brand=Apple
@@ -286,8 +292,8 @@ name="Ipod Nano (1st gen)"
286platform=ipodnano 292platform=ipodnano
287released=yes 293released=yes
288needsbootloader=yes 294needsbootloader=yes
289bootloadermethod=ipodpatcher 295bootloadermethod=ipod
290bootloadername=ipodnano 296bootloadername=/ipod/bootloader-ipodnano.ipod
291resolution=176x132x16 297resolution=176x132x16
292manualname= 298manualname=
293brand=Apple 299brand=Apple
@@ -301,8 +307,8 @@ name="Ipod (4th gen, greyscale)"
301platform=ipod4gray 307platform=ipod4gray
302released=yes 308released=yes
303needsbootloader=yes 309needsbootloader=yes
304bootloadermethod=ipodpatcher 310bootloadermethod=ipod
305bootloadername=ipod4g 311bootloadername=/ipod/bootloader-ipod4g.ipod
306resolution=160x128x2 312resolution=160x128x2
307manualname= 313manualname=
308brand=Apple 314brand=Apple
@@ -315,8 +321,8 @@ name="Ipod Video (5th gen) 30GB"
315platform=ipodvideo 321platform=ipodvideo
316released=yes 322released=yes
317needsbootloader=yes 323needsbootloader=yes
318bootloadermethod=ipodpatcher 324bootloadermethod=ipod
319bootloadername=ipodvideo 325bootloadername=/ipod/bootloader-ipodvideo.ipod
320resolution=320x240x16 326resolution=320x240x16
321manualname= 327manualname=
322brand=Apple 328brand=Apple
@@ -329,8 +335,8 @@ name="Ipod Video (5th gen) 60/80GB"
329platform=ipodvideo64mb 335platform=ipodvideo64mb
330released=yes 336released=yes
331needsbootloader=yes 337needsbootloader=yes
332bootloadermethod=ipodpatcher 338bootloadermethod=ipod
333bootloadername=ipodvideo 339bootloadername=/ipod/bootloader-ipodvideo.ipod
334resolution=320x240x16 340resolution=320x240x16
335manualname= 341manualname=
336brand=Apple 342brand=Apple
@@ -344,8 +350,8 @@ name="Ipod (3rd gen)"
344platform=ipod3g 350platform=ipod3g
345released=yes 351released=yes
346needsbootloader=yes 352needsbootloader=yes
347bootloadermethod=ipodpatcher 353bootloadermethod=ipod
348bootloadername=ipod3g 354bootloadername=/ipod/bootloader-ipod3g.ipod
349resolution=160x128x2 355resolution=160x128x2
350manualname= 356manualname=
351brand=Apple 357brand=Apple
@@ -359,8 +365,8 @@ name="Ipod Mini (1st gen)"
359platform=ipodmini1g 365platform=ipodmini1g
360released=yes 366released=yes
361needsbootloader=yes 367needsbootloader=yes
362bootloadermethod=ipodpatcher 368bootloadermethod=ipod
363bootloadername=ipodmini 369bootloadername=/ipod/bootloader-ipodmini.ipod
364resolution=138x110x2 370resolution=138x110x2
365manualname=rockbox-ipodmini2g 371manualname=rockbox-ipodmini2g
366brand=Apple 372brand=Apple
@@ -373,8 +379,8 @@ name="Ipod Mini (2nd gen)"
373platform=ipodmini2g 379platform=ipodmini2g
374released=yes 380released=yes
375needsbootloader=yes 381needsbootloader=yes
376bootloadermethod=ipodpatcher 382bootloadermethod=ipod
377bootloadername=ipodmini2g 383bootloadername=/ipod/bootloader-ipodmini2g.ipod
378resolution=138x110x2 384resolution=138x110x2
379manualname=rockbox-ipodmini2g 385manualname=rockbox-ipodmini2g
380brand=Apple 386brand=Apple
@@ -387,8 +393,9 @@ name="iAudio X5 / X5L"
387platform=iaudiox5 393platform=iaudiox5
388released=yes 394released=yes
389needsbootloader=yes 395needsbootloader=yes
390bootloadermethod=iaudio 396bootloadermethod=file
391bootloadername=x5_fw.bin 397bootloadername=/iaudio/x5_fw.bin
398bootloaderfile=/FIRMWARE/x5_fw.bin
392resolution=160x128x16 399resolution=160x128x16
393manualname= 400manualname=
394brand=Cowon 401brand=Cowon
@@ -402,8 +409,9 @@ name="iAudio X5V"
402platform=iaudiox5 409platform=iaudiox5
403released=yes 410released=yes
404needsbootloader=yes 411needsbootloader=yes
405bootloadermethod=iaudio 412bootloadermethod=file
406bootloadername=x5v_fw.bin 413bootloadername=/iaudio/x5v_fw.bin
414bootloaderfile=/FIRMWARE/x5v_fw.bin
407resolution=160x128x2 415resolution=160x128x2
408manualname= 416manualname=
409brand=Cowon 417brand=Cowon
@@ -416,8 +424,9 @@ name="iAudio M5 / M5L"
416platform=iaudiom5 424platform=iaudiom5
417released=yes 425released=yes
418needsbootloader=yes 426needsbootloader=yes
419bootloadermethod=iaudio 427bootloadermethod=file
420bootloadername=m5_fw.bin 428bootloadername=/iaudio/m5_fw.bin
429bootloaderfile=/FIRMWARE/m5_fw.bin
421resolution=160x128x2 430resolution=160x128x2
422manualname= 431manualname=
423brand=Cowon 432brand=Cowon
@@ -431,8 +440,9 @@ name="iAudio M3 / M3L"
431platform=iaudiom3 440platform=iaudiom3
432released=no 441released=no
433needsbootloader=yes 442needsbootloader=yes
434bootloadermethod=iaudio 443bootloadermethod=file
435bootloadername=cowon_m3.bin 444bootloadername=/iaudio/cowon_m3.bin
445bootloaderfile=/FIRMWARE/cowon_m3.bin
436resolution=128x96x2 446resolution=128x96x2
437manualname= 447manualname=
438brand=Cowon 448brand=Cowon
@@ -446,8 +456,9 @@ name="Gigabeat F / X"
446platform=gigabeatf 456platform=gigabeatf
447released=yes 457released=yes
448needsbootloader=yes 458needsbootloader=yes
449bootloadermethod=gigabeatf 459bootloadermethod=file
450bootloadername=FWIMG01.DAT 460bootloadername=/gigabeat/FWIMG01.DAT
461bootloaderfile=/SYSTEM/FWIMG01.DAT
451resolution=240x320x16 462resolution=240x320x16
452manualname= 463manualname=
453brand=Toshiba 464brand=Toshiba
@@ -461,8 +472,8 @@ name="Sansa E200"
461platform=sansae200 472platform=sansae200
462released=yes 473released=yes
463needsbootloader=yes 474needsbootloader=yes
464bootloadermethod=sansapatcher 475bootloadermethod=sansa
465bootloadername=PP5022.mi4 476bootloadername=/sandisk-sansa/e200/PP5022.mi4
466resolution=176x220x16 477resolution=176x220x16
467manualname= 478manualname=
468brand=Sandisk 479brand=Sandisk
@@ -478,8 +489,8 @@ name="Sansa C200"
478platform=sansac200 489platform=sansac200
479released=yes 490released=yes
480needsbootloader=yes 491needsbootloader=yes
481bootloadermethod=sansapatcher 492bootloadermethod=sansa
482bootloadername=firmware.mi4 493bootloadername=/sandisk-sansa/c200/firmware.mi4
483resolution=132x80x16 494resolution=132x80x16
484manualname= 495manualname=
485brand=Sandisk 496brand=Sandisk
@@ -493,8 +504,9 @@ name="m:robe100"
493platform=mrobe100 504platform=mrobe100
494released=yes 505released=yes
495needsbootloader=yes 506needsbootloader=yes
496bootloadermethod=mrobe100 507bootloadermethod=mi4
497bootloadername=pp5020.mi4 508bootloadername=/olympus/mrobe100/pp5020.mi4
509bootloaderfile=/System/pp5020.mi4
498resolution=160x128x1 510resolution=160x128x1
499manualname= 511manualname=
500brand=Olympus 512brand=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 @@
28#include "installtalkwindow.h" 28#include "installtalkwindow.h"
29#include "createvoicewindow.h" 29#include "createvoicewindow.h"
30#include "httpget.h" 30#include "httpget.h"
31#include "installbootloader.h"
32#include "installthemes.h" 31#include "installthemes.h"
33#include "uninstallwindow.h" 32#include "uninstallwindow.h"
34#include "browseof.h"
35#include "utils.h" 33#include "utils.h"
36#include "rbzip.h" 34#include "rbzip.h"
37#include "sysinfo.h" 35#include "sysinfo.h"
38#include "detect.h" 36#include "detect.h"
39 37
38#include "progressloggerinterface.h"
39
40#include "bootloaderinstallbase.h"
41#include "bootloaderinstallmi4.h"
42#include "bootloaderinstallhex.h"
43#include "bootloaderinstallipod.h"
44#include "bootloaderinstallsansa.h"
45#include "bootloaderinstallfile.h"
46
40#if defined(Q_OS_LINUX) 47#if defined(Q_OS_LINUX)
41#include <stdio.h> 48#include <stdio.h>
42#endif 49#endif
@@ -52,17 +59,19 @@
52RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent) 59RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
53{ 60{
54 absolutePath = qApp->applicationDirPath(); 61 absolutePath = qApp->applicationDirPath();
55 62
56 ui.setupUi(this);
57
58 settings = new RbSettings(); 63 settings = new RbSettings();
59 settings->open(); 64 settings->open();
60 HttpGet::setGlobalUserAgent("rbutil/"VERSION); 65 HttpGet::setGlobalUserAgent("rbutil/"VERSION);
66 // init startup & autodetection
67 ui.setupUi(this);
68 updateSettings();
69 downloadInfo();
61 70
62 m_gotInfo = false; 71 m_gotInfo = false;
63 72 m_auto = false;
73
64 // manual tab 74 // manual tab
65 updateSettings();
66 ui.radioPdf->setChecked(true); 75 ui.radioPdf->setChecked(true);
67 76
68 // info tab 77 // info tab
@@ -112,10 +121,6 @@ RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
112 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable())); 121 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
113#endif 122#endif
114 123
115 initIpodpatcher();
116 initSansapatcher();
117 downloadInfo();
118
119} 124}
120 125
121 126
@@ -158,6 +163,8 @@ void RbUtilQt::downloadDone(bool error)
158{ 163{
159 if(error) { 164 if(error) {
160 qDebug() << "network error:" << daily->error(); 165 qDebug() << "network error:" << daily->error();
166 QMessageBox::critical(this, tr("Network error"),
167 tr("Can't get version information."));
161 return; 168 return;
162 } 169 }
163 qDebug() << "network status:" << daily->error(); 170 qDebug() << "network status:" << daily->error();
@@ -218,8 +225,9 @@ void RbUtilQt::downloadDone(int id, bool error)
218 .arg(daily->errorString()); 225 .arg(daily->errorString());
219 if(error) { 226 if(error) {
220 QMessageBox::about(this, "Network Error", errorString); 227 QMessageBox::about(this, "Network Error", errorString);
228 m_networkerror = daily->errorString();
221 } 229 }
222 qDebug() << "downloadDone:" << id << error; 230 qDebug() << "downloadDone:" << id << "error:" << error;
223} 231}
224 232
225 233
@@ -428,6 +436,7 @@ bool RbUtilQt::smallInstallInner()
428 { 436 {
429 m_error = false; 437 m_error = false;
430 m_installed = false; 438 m_installed = false;
439 m_auto = true;
431 if(!installBootloaderAuto()) 440 if(!installBootloaderAuto())
432 return true; 441 return true;
433 else 442 else
@@ -436,6 +445,7 @@ bool RbUtilQt::smallInstallInner()
436 while(!m_installed) 445 while(!m_installed)
437 QApplication::processEvents(); 446 QApplication::processEvents();
438 } 447 }
448 m_auto = false;
439 if(m_error) return true; 449 if(m_error) return true;
440 logger->undoAbort(); 450 logger->undoAbort();
441 } 451 }
@@ -452,6 +462,7 @@ bool RbUtilQt::smallInstallInner()
452 QApplication::processEvents(); 462 QApplication::processEvents();
453 } 463 }
454 464
465 installBootloaderPost(false);
455 return false; 466 return false;
456} 467}
457 468
@@ -580,82 +591,167 @@ void RbUtilQt::installBootloaderBtn()
580 591
581 // create logger 592 // create logger
582 logger = new ProgressLoggerGui(this); 593 logger = new ProgressLoggerGui(this);
583 logger->show(); 594
584
585 installBootloader(); 595 installBootloader();
586} 596}
587 597
588void RbUtilQt::installBootloader() 598void RbUtilQt::installBootloader()
589{ 599{
590 QString platform = settings->curPlatform(); 600 QString platform = settings->curPlatform();
601 QString backupDestination = "";
602 m_error = false;
591 603
592 // create installer 604 // create installer
593 blinstaller = new BootloaderInstaller(this); 605 BootloaderInstallBase *bl;
594 606 QString type = settings->curBootloaderMethod();
595 blinstaller->setMountPoint(settings->mountpoint()); 607 if(type == "mi4") {
596 608 bl = new BootloaderInstallMi4(this);
597 blinstaller->setDevice(platform); 609 }
598 blinstaller->setBootloaderMethod(settings->curBootloaderMethod()); 610 else if(type == "hex") {
599 blinstaller->setBootloaderName(settings->curBootloaderName()); 611 bl = new BootloaderInstallHex(this);
600 blinstaller->setBootloaderBaseUrl(settings->bootloaderUrl()); 612 }
601 blinstaller->setBootloaderInfoUrl(settings->bootloaderInfoUrl()); 613 else if(type == "sansa") {
602 if(!blinstaller->downloadInfo()) 614 bl = new BootloaderInstallSansa(this);
603 { 615 }
604 logger->addItem(tr("Could not get the bootloader info file!"),LOGERROR); 616 else if(type == "ipod") {
617 bl = new BootloaderInstallIpod(this);
618 }
619 else if(type == "file") {
620 bl = new BootloaderInstallFile(this);
621 }
622 else {
623 logger->addItem(tr("No install method known."), LOGERROR);
605 logger->abort(); 624 logger->abort();
606 m_error = true;
607 return; 625 return;
608 } 626 }
609 627
610 if(blinstaller->uptodate()) 628 // set bootloader filename. Do this now as installed() needs it.
629 QString blfile;
630 blfile = settings->mountpoint() + settings->curBootloaderFile();
631 // special case for H10 pure: this player can have a different
632 // bootloader file filename. This is handled here to keep the install
633 // class clean, though having it here is also not the nicest solution.
634 if(settings->curPlatformName() == "h10_ums"
635 || settings->curPlatformName() == "h10_mtp") {
636 if(resolvePathCase(blfile).isEmpty())
637 blfile = settings->mountpoint()
638 + settings->curBootloaderName().replace("H10",
639 "H10EMP", Qt::CaseInsensitive);
640 }
641 bl->setBlFile(blfile);
642 QUrl url(settings->bootloaderUrl() + settings->curBootloaderName());
643 bl->setBlUrl(url);
644 bl->setLogfile(settings->mountpoint() + "/.rockbox/rbutil.log");
645
646 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
647 if(QMessageBox::question(this, tr("Bootloader detected"),
648 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
649 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
650 logger->close();
651 m_error = true;
652 return;
653 }
654 }
655 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
656 && bl->capabilities() & BootloaderInstallBase::Backup)
611 { 657 {
612 int ret = QMessageBox::question(this, tr("Bootloader Installation"), 658 QString targetFolder = settings->name(settings->curPlatform())
613 tr("The bootloader is already installed and up to date.\n" 659 + " Firmware Backup";
614 "Do want to replace the current bootloader?"), 660 // remove invalid character(s)
615 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); 661 targetFolder.remove(QRegExp("[:/]"));
616 if(ret == QMessageBox::No) 662 if(QMessageBox::question(this, tr("Create Bootloader backup"),
617 { 663 tr("You can create a backup of the original bootloader "
618 logger->addItem(tr("Bootloader installation skipped!"), LOGINFO); 664 "file. Press \"Yes\" to select an output folder on your "
619 logger->abort(); 665 "computer to save the file to. The file will get placed "
620 m_installed = true; 666 "in a new folder \"%1\" created below the selected folder.\n"
621 return; 667 "Press \"No\" to skip this step.").arg(targetFolder),
668 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
669 BrowseDirtree tree(this, tr("Browse backup folder"));
670 tree.setDir(QDir::home());
671 tree.exec();
672
673 backupDestination = tree.getSelected() + "/" + targetFolder;
674 qDebug() << backupDestination;
675 // backup needs to be done after the logger has been set up.
622 } 676 }
623 } 677 }
624 678
625 // if fwpatcher , ask for extra file 679 if(bl->capabilities() & BootloaderInstallBase::NeedsFlashing)
626 QString offirmware;
627 if(settings->curBootloaderMethod() == "fwpatcher")
628 { 680 {
629 BrowseOF ofbrowser(this); 681 int ret;
630 ofbrowser.setFile(settings->ofPath()); 682 ret = QMessageBox::information(this, tr("Prerequisites"),
631 if(ofbrowser.exec() == QDialog::Accepted) 683 tr("Bootloader installation requires you to provide "
632 { 684 "a firmware file of the original firmware (hex file). "
633 offirmware = ofbrowser.getFile(); 685 "You need to download this file yourself due to legal "
634 qDebug() << offirmware; 686 "reasons. Please refer to the "
635 if(!QFileInfo(offirmware).exists()) 687 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and the "
636 { 688 "<a href='http://www.rockbox.org/wiki/IriverBoot"
637 logger->addItem(tr("Original Firmware Path is wrong!"),LOGERROR); 689 "#Download_and_extract_a_recent_ve'>IriverBoot</a> wiki page on "
638 logger->abort(); 690 "how to obtain this file.<br/>"
639 m_error = true; 691 "Press Ok to continue and browse your computer for the firmware "
640 return; 692 "file."),
641 } 693 QMessageBox::Ok | QMessageBox::Abort);
642 else 694 if(ret != QMessageBox::Ok) {
643 { 695 m_error = true;
644 settings->setOfPath(offirmware); 696 return;
645 settings->sync();
646 }
647 } 697 }
648 else 698 // open dialog to browse to hex file
649 { 699 QString hexfile;
650 logger->addItem(tr("Original Firmware selection Canceled!"),LOGERROR); 700 hexfile = QFileDialog::getOpenFileName(this,
651 logger->abort(); 701 tr("Select firmware file"), QDir::homePath(), "*.hex");
702 if(!QFileInfo(hexfile).isReadable()) {
703 logger->addItem(tr("Error opening firmware file"), LOGERROR);
652 m_error = true; 704 m_error = true;
653 return; 705 return;
654 } 706 }
707 ((BootloaderInstallHex*)bl)->setHexfile(hexfile);
708 }
709
710 // the bootloader install class does NOT use any GUI stuff.
711 // All messages are passed via signals.
712 connect(bl, SIGNAL(done(bool)), logger, SLOT(abort()));
713 connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
714 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
715 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
716
717 // show logger and start install.
718 logger->show();
719 if(!backupDestination.isEmpty()) {
720 if(!bl->backup(backupDestination)) {
721 if(QMessageBox::warning(this, tr("Backup error"),
722 tr("Could not create backup file. Continue?"),
723 QMessageBox::No | QMessageBox::Yes)
724 == QMessageBox::No) {
725 logger->abort();
726 return;
727 }
728 }
655 } 729 }
656 blinstaller->setOrigFirmwarePath(offirmware); 730 bl->install();
657 connect(blinstaller,SIGNAL(done(bool)),this,SLOT(installdone(bool))); 731}
658 blinstaller->install(logger); 732
733void RbUtilQt::installBootloaderPost(bool error)
734{
735 qDebug() << __func__ << error;
736 // if an error occured don't perform post install steps.
737 if(error) {
738 m_error = true;
739 return;
740 }
741 else
742 m_error = false;
743
744 m_installed = true;
745 // end here if automated install
746 if(m_auto)
747 return;
748
749 QString msg = BootloaderInstallBase::postinstallHints(settings->curPlatform());
750 if(!msg.isEmpty()) {
751 QMessageBox::information(this, tr("Manual steps required"), msg);
752 logger->close();
753 }
754
659} 755}
660 756
661void RbUtilQt::installFontsBtn() 757void RbUtilQt::installFontsBtn()
@@ -825,23 +921,52 @@ void RbUtilQt::uninstallBootloader(void)
825 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; 921 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
826 // create logger 922 // create logger
827 ProgressLoggerGui* logger = new ProgressLoggerGui(this); 923 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
924 logger->setProgressVisible(false);
828 logger->show(); 925 logger->show();
829 926
830 BootloaderInstaller blinstaller(this); 927 QString platform = settings->curPlatform();
831 blinstaller.setMountPoint(settings->mountpoint()); 928
832 blinstaller.setDevice(settings->curPlatform()); 929 // create installer
833 blinstaller.setBootloaderMethod(settings->curBootloaderMethod()); 930 BootloaderInstallBase *bl;
834 blinstaller.setBootloaderName(settings->curBootloaderName()); 931 QString type = settings->curBootloaderMethod();
835 blinstaller.setBootloaderBaseUrl(settings->bootloaderUrl()); 932 if(type == "mi4") {
836 blinstaller.setBootloaderInfoUrl(settings->bootloaderInfoUrl()); 933 bl = new BootloaderInstallMi4();
837 if(!blinstaller.downloadInfo()) 934 }
838 { 935 else if(type == "hex") {
839 logger->addItem(tr("Could not get the bootloader info file!"),LOGERROR); 936 bl = new BootloaderInstallHex();
937 }
938 else if(type == "sansa") {
939 bl = new BootloaderInstallSansa();
940 }
941 else if(type == "ipod") {
942 bl = new BootloaderInstallIpod();
943 }
944 else if(type == "file") {
945 bl = new BootloaderInstallFile();
946 }
947 else {
948 logger->addItem(tr("No uninstall method known."), LOGERROR);
840 logger->abort(); 949 logger->abort();
841 return; 950 return;
842 } 951 }
843 952
844 blinstaller.uninstall(logger); 953 QString blfile = settings->mountpoint() + settings->curBootloaderFile();
954 if(settings->curPlatformName() == "h10_ums"
955 || settings->curPlatformName() == "h10_mtp") {
956 if(resolvePathCase(blfile).isEmpty())
957 blfile = settings->mountpoint()
958 + settings->curBootloaderName().replace("H10",
959 "H10EMP", Qt::CaseInsensitive);
960 }
961 bl->setBlFile(blfile);
962
963 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
964 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
965
966 int result;
967 result = bl->uninstall();
968
969 logger->abort();
845 970
846} 971}
847 972
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 @@
30#include "httpget.h" 30#include "httpget.h"
31#include "installzip.h" 31#include "installzip.h"
32#include "progressloggergui.h" 32#include "progressloggergui.h"
33#include "installbootloader.h" 33#include "bootloaderinstallbase.h"
34 34
35#include "rbsettings.h" 35#include "rbsettings.h"
36 36
@@ -44,7 +44,7 @@ class RbUtilQt : public QMainWindow
44 private: 44 private:
45 Ui::RbUtilQtFrm ui; 45 Ui::RbUtilQtFrm ui;
46 RbSettings* settings; 46 RbSettings* settings;
47 47
48 void initDeviceNames(void); 48 void initDeviceNames(void);
49 QString deviceName(QString); 49 QString deviceName(QString);
50 QString platform; 50 QString platform;
@@ -56,14 +56,15 @@ class RbUtilQt : public QMainWindow
56 void updateManual(void); 56 void updateManual(void);
57 ProgressLoggerGui *logger; 57 ProgressLoggerGui *logger;
58 ZipInstaller *installer; 58 ZipInstaller *installer;
59 BootloaderInstaller* blinstaller;
60 QUrl proxy(void); 59 QUrl proxy(void);
61 QMap<QString, QString> versmap; 60 QMap<QString, QString> versmap;
62 bool chkConfig(bool); 61 bool chkConfig(bool);
63 62
64 volatile bool m_installed; 63 volatile bool m_installed;
65 volatile bool m_error; 64 volatile bool m_error;
65 QString m_networkerror;
66 bool m_gotInfo; 66 bool m_gotInfo;
67 bool m_auto;
67 68
68 private slots: 69 private slots:
69 void about(void); 70 void about(void);
@@ -85,6 +86,7 @@ class RbUtilQt : public QMainWindow
85 void installBootloaderBtn(void); 86 void installBootloaderBtn(void);
86 bool installBootloaderAuto(void); 87 bool installBootloaderAuto(void);
87 void installBootloader(void); 88 void installBootloader(void);
89 void installBootloaderPost(bool error);
88 90
89 void installFontsBtn(void); 91 void installFontsBtn(void);
90 bool installFontsAuto(void); 92 bool installFontsAuto(void);
@@ -101,6 +103,7 @@ class RbUtilQt : public QMainWindow
101 void downloadDone(int, bool); 103 void downloadDone(int, bool);
102 void downloadBleedingDone(bool); 104 void downloadBleedingDone(bool);
103 void downloadInfo(void); 105 void downloadInfo(void);
106
104 void installVoice(void); 107 void installVoice(void);
105 void installThemes(void); 108 void installThemes(void);
106 void uninstall(void); 109 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
31PRE_TARGETDEPS += rbspeex 31PRE_TARGETDEPS += rbspeex
32 32
33# rule for creating ctags file 33# rule for creating ctags file
34tags.commands = ctags -R --c++-kinds=+p --fields=+iaS --extra=+q $(SOURCES) 34tags.commands = ctags -R --c++-kinds=+p --fields=+iaS --extra=+q $(SOURCES)
35tags.depends = $(SOURCES) 35tags.depends = $(SOURCES)
36QMAKE_EXTRA_TARGETS += tags 36QMAKE_EXTRA_TARGETS += tags
37 37
@@ -51,21 +51,17 @@ SOURCES += rbutilqt.cpp \
51 zip/zip.cpp \ 51 zip/zip.cpp \
52 zip/unzip.cpp \ 52 zip/unzip.cpp \
53 installzip.cpp \ 53 installzip.cpp \
54 installbootloader.cpp \
55 progressloggergui.cpp \ 54 progressloggergui.cpp \
56 installtalkwindow.cpp \ 55 installtalkwindow.cpp \
57 talkfile.cpp \ 56 talkfile.cpp \
58 autodetection.cpp \ 57 autodetection.cpp \
59 ../ipodpatcher/ipodpatcher.c \ 58 ../ipodpatcher/ipodpatcher.c \
60 ../sansapatcher/sansapatcher.c \ 59 ../sansapatcher/sansapatcher.c \
61 irivertools/irivertools.cpp \
62 irivertools/md5sum.cpp \
63 browsedirtree.cpp \ 60 browsedirtree.cpp \
64 installthemes.cpp \ 61 installthemes.cpp \
65 uninstall.cpp \ 62 uninstall.cpp \
66 uninstallwindow.cpp \ 63 uninstallwindow.cpp \
67 utils.cpp \ 64 utils.cpp \
68 browseof.cpp \
69 preview.cpp \ 65 preview.cpp \
70 encoders.cpp \ 66 encoders.cpp \
71 encodersgui.cpp \ 67 encodersgui.cpp \
@@ -78,9 +74,17 @@ SOURCES += rbutilqt.cpp \
78 rbsettings.cpp \ 74 rbsettings.cpp \
79 rbunzip.cpp \ 75 rbunzip.cpp \
80 rbzip.cpp \ 76 rbzip.cpp \
77 detect.cpp \
81 sysinfo.cpp \ 78 sysinfo.cpp \
82 detect.cpp 79 bootloaderinstallbase.cpp \
83 80 bootloaderinstallmi4.cpp \
81 bootloaderinstallhex.cpp \
82 bootloaderinstallipod.cpp \
83 bootloaderinstallsansa.cpp \
84 bootloaderinstallfile.cpp \
85 ../../tools/mkboot.c \
86 ../../tools/iriver.c
87
84HEADERS += rbutilqt.h \ 88HEADERS += rbutilqt.h \
85 install.h \ 89 install.h \
86 httpget.h \ 90 httpget.h \
@@ -92,7 +96,6 @@ HEADERS += rbutilqt.h \
92 zip/zip_p.h \ 96 zip/zip_p.h \
93 version.h \ 97 version.h \
94 installzip.h \ 98 installzip.h \
95 installbootloader.h \
96 installtalkwindow.h \ 99 installtalkwindow.h \
97 talkfile.h \ 100 talkfile.h \
98 autodetection.h \ 101 autodetection.h \
@@ -103,18 +106,14 @@ HEADERS += rbutilqt.h \
103 ../ipodpatcher/parttypes.h \ 106 ../ipodpatcher/parttypes.h \
104 ../sansapatcher/sansapatcher.h \ 107 ../sansapatcher/sansapatcher.h \
105 ../sansapatcher/sansaio.h \ 108 ../sansapatcher/sansaio.h \
106 irivertools/irivertools.h \
107 irivertools/md5sum.h \
108 irivertools/h100sums.h \ 109 irivertools/h100sums.h \
109 irivertools/h120sums.h \ 110 irivertools/h120sums.h \
110 irivertools/h300sums.h \ 111 irivertools/h300sums.h \
111 irivertools/checksums.h \
112 browsedirtree.h \ 112 browsedirtree.h \
113 installthemes.h \ 113 installthemes.h \
114 uninstall.h \ 114 uninstall.h \
115 uninstallwindow.h \ 115 uninstallwindow.h \
116 utils.h \ 116 utils.h \
117 browseof.h \
118 preview.h \ 117 preview.h \
119 encoders.h \ 118 encoders.h \
120 encodersgui.h \ 119 encodersgui.h \
@@ -128,11 +127,19 @@ HEADERS += rbutilqt.h \
128 rbunzip.h \ 127 rbunzip.h \
129 rbzip.h \ 128 rbzip.h \
130 sysinfo.h \ 129 sysinfo.h \
131 detect.h 130 detect.h \
132 131 bootloaderinstallbase.h \
132 bootloaderinstallmi4.h \
133 bootloaderinstallhex.h \
134 bootloaderinstallipod.h \
135 bootloaderinstallsansa.h \
136 bootloaderinstallfile.h \
137 ../../tools/mkboot.h \
138 ../../tools/iriver.h
139
133# Needed by QT on Win 140# Needed by QT on Win
134INCLUDEPATH = . irivertools zip zlib ../ipodpatcher ../sansapatcher ../../tools/rbspeex ../../tools 141INCLUDEPATH = . irivertools zip zlib ../ipodpatcher ../sansapatcher ../../tools/rbspeex ../../tools
135 142
136LIBS += -L../../tools/rbspeex -lrbspeex 143LIBS += -L../../tools/rbspeex -lrbspeex
137 144
138TEMPLATE = app 145TEMPLATE = app
@@ -158,7 +165,6 @@ FORMS += rbutilqtfrm.ui \
158 installtalkfrm.ui \ 165 installtalkfrm.ui \
159 installthemesfrm.ui \ 166 installthemesfrm.ui \
160 uninstallfrm.ui \ 167 uninstallfrm.ui \
161 browseoffrm.ui \
162 previewfrm.ui \ 168 previewfrm.ui \
163 rbspeexcfgfrm.ui \ 169 rbspeexcfgfrm.ui \
164 encexescfgfrm.ui \ 170 encexescfgfrm.ui \