1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2008 by Dominik Riebeling
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 #include "bootloaderinstallbase.h"
22 #include "bootloaderinstallhex.h"
24 #include "../../tools/iriver.h"
25 #include "../../tools/mkboot.h"
32 struct md5s md5sums
[] = {
33 #include "irivertools/h100sums.h"
35 #include "irivertools/h120sums.h"
37 #include "irivertools/h300sums.h"
42 BootloaderInstallHex::BootloaderInstallHex(QObject
*parent
)
43 : BootloaderInstallBase(parent
)
48 bool BootloaderInstallHex::install(void)
55 emit
logItem(tr("checking MD5 hash of input file ..."), LOGINFO
);
57 // read hex file into QByteArray
59 file
.open(QIODevice::ReadOnly
);
60 filedata
= file
.readAll();
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
);
70 // check hash and figure model from md5sum
71 int i
= sizeof(md5sums
) / sizeof(struct md5s
);
73 // 3: h300, 2: h120, 1: h100, 0:invalid
75 if(md5sums
[i
].orig
== 0)
77 if(!qstrcmp(md5sums
[i
].orig
, hash
.toAscii()))
81 emit
logItem(tr("Firmware file not recognized."), LOGERROR
);
85 emit
logItem(tr("MD5 hash ok"), LOGOK
);
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."),
97 emit
logItem(tr("Descrambling file"), LOGINFO
);
100 result
= iriver_decode(m_hex
.toAscii().data(),
101 m_descrambled
.fileName().toAscii().data(), FALSE
, STRIP_NONE
);
102 qDebug() << "iriver_decode" << result
;
105 emit
logItem(tr("Error in descramble: %1").arg(scrambleError(result
)), LOGERROR
);
109 // download firmware from server
110 emit
logItem(tr("Downloading bootloader file"), LOGINFO
);
111 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
113 downloadBlStart(m_blurl
);
118 void BootloaderInstallHex::installStage2(void)
120 emit
logItem(tr("Adding bootloader to firmware file"), LOGINFO
);
123 QTemporaryFile tempbin
;
125 QString tempbinName
= tempbin
.fileName();
127 // get temporary files filenames -- external tools need this.
128 m_descrambled
.open();
129 QString descrambledName
= m_descrambled
.fileName();
130 m_descrambled
.close();
132 QString tempfileName
= m_tempfile
.fileName();
149 // iriver decode already done in stage 1
151 if((result
= mkboot(descrambledName
.toLocal8Bit().constData(),
152 tempfileName
.toLocal8Bit().constData(),
153 tempbinName
.toLocal8Bit().constData(), origin
)) < 0)
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;
165 emit
logItem(tr("Error in patching: %1").arg(error
), LOGERROR
);
170 QTemporaryFile targethex
;
172 QString targethexName
= targethex
.fileName();
173 if((result
= iriver_encode(tempbinName
.toLocal8Bit().constData(),
174 targethexName
.toLocal8Bit().constData(), FALSE
)) < 0)
176 emit
logItem(tr("Error in scramble: %1").arg(scrambleError(result
)), LOGERROR
);
183 // finally check the md5sum of the created file
185 filedata
= targethex
.readAll();
187 QString hash
= QCryptographicHash::hash(filedata
,
188 QCryptographicHash::Md5
).toHex();
189 qDebug() << "created hexfile hash:" << hash
;
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
);
198 // finally copy file to player
199 targethex
.copy(m_blfile
);
201 emit
logItem(tr("Success: modified firmware file created"), LOGINFO
);
209 bool BootloaderInstallHex::uninstall(void)
211 emit
logItem("Uninstallation not possible, only installation info removed", LOGINFO
);
212 logInstall(LogRemove
);
217 BootloaderInstallBase::BootloaderType
BootloaderInstallHex::installed(void)
219 return BootloaderUnknown
;
223 BootloaderInstallBase::Capabilities
BootloaderInstallHex::capabilities(void)
225 return (Install
| NeedsFlashing
);
228 QString
BootloaderInstallHex::scrambleError(int 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;