Use the new progressbar value slot instead of wrapping around it.
[Rockbox.git] / rbutil / rbutilqt / installbootloader.cpp
blobdae82b6fd25a3709c94915a88ac9354c1d920988
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
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 ****************************************************************************/
20 #include "installbootloader.h"
21 #include "irivertools/checksums.h"
22 #include "utils.h"
24 BootloaderInstaller::BootloaderInstaller(QObject* parent): QObject(parent)
29 void BootloaderInstaller::install(ProgressloggerInterface* dp)
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)));
36 if(m_bootloadermethod == "gigabeatf")
38 // connect internal signal
39 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
40 connect(this,SIGNAL(finish()),this,SLOT(gigabeatFinish()));
42 else if(m_bootloadermethod == "iaudio")
44 // connect internal signal
45 connect(this,SIGNAL(prepare()),this,SLOT(iaudioPrepare()));
46 connect(this,SIGNAL(finish()),this,SLOT(iaudioFinish()));
48 else if(m_bootloadermethod == "h10")
50 // connect internal signal
51 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
52 connect(this,SIGNAL(finish()),this,SLOT(h10Finish()));
54 else if(m_bootloadermethod == "ipodpatcher")
56 // connect internal signal
57 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
58 connect(this,SIGNAL(finish()),this,SLOT(ipodFinish()));
60 else if(m_bootloadermethod == "sansapatcher")
62 // connect internal signal
63 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
64 connect(this,SIGNAL(finish()),this,SLOT(sansaFinish()));
66 else if(m_bootloadermethod == "fwpatcher")
68 // connect internal signal
69 connect(this,SIGNAL(prepare()),this,SLOT(iriverPrepare()));
70 connect(this,SIGNAL(finish()),this,SLOT(iriverFinish()));
72 else if(m_bootloadermethod == "mrobe100")
74 // connect internal signal
75 connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare()));
76 connect(this,SIGNAL(finish()),this,SLOT(mrobe100Finish()));
78 else
80 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
81 emit done(true);
82 return;
85 emit prepare();
88 void BootloaderInstaller::uninstall(ProgressloggerInterface* dp)
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)));
95 if(m_bootloadermethod == "gigabeatf")
97 // connect internal signal
98 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
100 else if(m_bootloadermethod == "iaudio")
102 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
103 emit done(true);
104 return;
106 else if(m_bootloadermethod == "iaudio")
108 // connect internal signal
109 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
111 else if(m_bootloadermethod == "ipodpatcher")
113 // connect internal signal
114 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
116 else if(m_bootloadermethod == "sansapatcher")
118 // connect internal signal
119 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
121 else if(m_bootloadermethod == "h10")
123 // connect internal signal
124 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
126 else if(m_bootloadermethod == "mrobe100")
128 // connect internal signal
129 connect(this,SIGNAL(prepare()),this,SLOT(mrobe100Prepare()));
131 else if(m_bootloadermethod == "fwpatcher")
133 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
134 emit done(true);
135 return;
137 else
139 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
140 emit done(true);
141 return;
144 emit prepare();
147 void BootloaderInstaller::downloadRequestFinished(int id, bool error)
149 qDebug() << "BootloaderInstall::downloadRequestFinished" << id << error;
150 qDebug() << "error:" << getter->errorString();
152 downloadDone(error);
155 void BootloaderInstaller::downloadDone(bool error)
157 qDebug() << "Install::downloadDone, error:" << error;
159 // update progress bar
161 int max = m_dp->getProgressMax();
162 if(max == 0) {
163 max = 100;
164 m_dp->setProgressMax(max);
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;
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;
179 else m_dp->addItem(tr("Download finished."),LOGOK);
181 emit finish();
186 void BootloaderInstaller::installEnded(bool error)
188 (void) error;
189 m_dp->abort();
192 bool BootloaderInstaller::downloadInfo()
194 // try to get the current build information
195 infodownloader = new HttpGet(this);
197 connect(infodownloader, SIGNAL(done(bool)), this, SLOT(infoDownloadDone(bool)));
198 connect(infodownloader, SIGNAL(requestFinished(int, bool)), this, SLOT(infoRequestFinished(int, bool)));
200 qDebug() << "downloading bootloader info";
201 infodownloader->setFile(&bootloaderInfo);
202 infodownloader->getFile(QUrl(m_bootloaderinfoUrl));
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;
213 void BootloaderInstaller::infoDownloadDone(bool error)
215 if(error)
217 qDebug() << "network error:" << infodownloader->error();
218 return;
220 qDebug() << "network status:" << infodownloader->error();
222 infoDownloaded = true;
225 void BootloaderInstaller::infoRequestFinished(int id, bool error)
228 if(error)
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;
238 infoError = true;
239 infoDownloaded = true;
241 qDebug() << "infoRequestFinished:" << id << error;
245 void BootloaderInstaller::createInstallLog()
247 m_dp->addItem(tr("Creating installation log"),LOGINFO);
248 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
250 bootloaderInfo.open();
251 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
252 bootloaderInfo.close();
253 info.beginGroup(m_device);
255 installlog.beginGroup("Bootloader");
256 installlog.setValue("md5sum",info.value("md5sum").toString());
257 installlog.endGroup();
258 installlog.sync();
261 void BootloaderInstaller::removeInstallLog()
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();
272 bool BootloaderInstaller::uptodate()
274 QString installedMd5;
275 QString serverMd5;
277 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
278 installlog.beginGroup("Bootloader");
279 installedMd5 = installlog.value("md5sum").toString();
280 installlog.endGroup();
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();
291 if(installedMd5 != serverMd5)
292 return false;
293 else
294 return true;
297 /**************************************************
298 *** gigabeat secific code
299 ***************************************************/
301 void BootloaderInstaller::gigabeatPrepare()
303 if(m_install) // Installation
305 QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername;
307 m_dp->addItem(tr("Downloading file %1.%2")
308 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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()));
322 getter->getFile(QUrl(url));
324 else //UnInstallation
326 QString firmware;
327 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT");
328 QString firmwareOrig = resolvePathCase(firmware.append(".ORIG"));
330 QFileInfo firmwareOrigFI(firmwareOrig);
332 // check if original firmware exists
333 if(!firmwareOrigFI.exists())
335 m_dp->addItem(tr("Could not find the Original Firmware at: %1")
336 .arg(firmwareOrig),LOGERROR);
337 emit done(true);
338 return;
341 QFile firmwareFile(firmware);
342 QFile firmwareOrigFile(firmwareOrig);
344 //remove modified firmware
345 if(!firmwareFile.remove())
347 m_dp->addItem(tr("Could not remove the Firmware at: %1")
348 .arg(firmware),LOGERROR);
349 emit done(true);
350 return;
353 // rename original firmware back
354 if(!firmwareOrigFile.rename(firmware))
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;
362 removeInstallLog();
364 emit done(false); //success
369 void BootloaderInstaller::gigabeatFinish()
371 // this step is only need for installation, so no code for uninstall here
373 m_dp->addItem(tr("Finishing bootloader install"),LOGINFO);
375 QString firmware;
376 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername);
378 QFileInfo firmwareFI(firmware);
380 // check if firmware exists
381 if(!firmwareFI.exists())
383 m_dp->addItem(tr("Could not find the Firmware at: %1")
384 .arg(firmware),LOGERROR);
385 emit done(true);
386 return;
389 QString firmwareOrig = firmware;
390 firmwareOrig.append(".ORIG");
391 QFileInfo firmwareOrigFI(firmwareOrig);
393 // rename and backup the firmware, if there is no original firmware there
394 if(!firmwareOrigFI.exists())
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))
404 m_dp->addItem(tr("Could not rename: %1 to %2")
405 .arg(firmware,firmwareOrig),LOGERROR);
406 emit done(true);
407 return;
410 else // or remove the normal firmware, if the original is there
412 QFile firmwareFile(firmware);
413 firmwareFile.remove();
416 //copy the firmware
417 if(!downloadFile.copy(firmware))
419 m_dp->addItem(tr("Could not copy: %1 to %2")
420 .arg(m_tempfilename,firmware),LOGERROR);
421 emit done(true);
422 return;
425 downloadFile.remove();
427 createInstallLog();
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);
438 m_dp->abort();
440 emit done(false); // success
444 /**************************************************
445 *** iaudio secific code
446 ***************************************************/
447 void BootloaderInstaller::iaudioPrepare()
450 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
452 m_dp->addItem(tr("Downloading file %1.%2")
453 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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()));
469 void BootloaderInstaller::iaudioFinish()
471 QString firmware;
472 firmware = resolvePathCase(m_mountpoint + "/FIRMWARE/") + "/" + m_bootloadername;
474 //copy the firmware
475 if(!downloadFile.copy(firmware))
477 m_dp->addItem(tr("Could not copy: %1 to %2")
478 .arg(m_tempfilename,firmware),LOGERROR);
479 emit done(true);
480 return;
483 downloadFile.remove();
485 createInstallLog();
487 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
488 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
489 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
490 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
491 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
493 m_dp->abort();
495 emit done(false); // success
500 /**************************************************
501 *** h10 secific code
502 ***************************************************/
503 void BootloaderInstaller::h10Prepare()
505 if(m_install) // Installation
507 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
509 m_dp->addItem(tr("Downloading file %1.%2")
510 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
512 // temporary file needs to be opened to get the filename
513 downloadFile.open();
514 m_tempfilename = downloadFile.fileName();
515 downloadFile.close();
516 // get the real file.
517 getter = new HttpGet(this);
518 getter->setFile(&downloadFile);
519 // connect signals from HttpGet
520 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
521 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
522 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
524 getter->getFile(QUrl(url));
526 else // Uninstallation
529 QString firmwarename = m_bootloadername.section('/', -1);
531 QString firmware;
532 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
533 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
535 QFileInfo firmwareFI(firmware);
536 if(!firmwareFI.exists()) //Firmware dosent exists on player
538 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/H10EMP.mi4");
539 //attempt other firmwarename
540 firmwareFI.setFile(firmware);
541 if(!firmwareFI.exists()) //Firmware dosent exists on player
543 m_dp->addItem(tr("Firmware does not exist: %1")
544 .arg(firmware),LOGERROR);
545 emit done(true);
546 return;
550 QFileInfo firmwareOrigFI(firmwareOrig);
551 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
553 m_dp->addItem(tr("Original Firmware does not exist: %1")
554 .arg(firmwareOrig),LOGERROR);
555 emit done(true);
556 return;
559 QFile firmwareFile(firmware);
560 QFile firmwareOrigFile(firmwareOrig);
562 //remove modified firmware
563 if(!firmwareFile.remove())
565 m_dp->addItem(tr("Could not remove the Firmware at: %1")
566 .arg(firmware),LOGERROR);
567 emit done(true);
568 return;
571 // rename original firmware back
572 if(!firmwareOrigFile.rename(firmware))
574 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
575 .arg(firmwareOrig,firmware),LOGERROR);
576 emit done(true);
577 return;
580 removeInstallLog();
582 emit done(false); //success
587 void BootloaderInstaller::h10Finish()
589 QString firmwarename = m_bootloadername.section('/', -1);
591 QString firmware;
592 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
593 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
595 QFileInfo firmwareFI(firmware);
597 if(!firmwareFI.exists()) //Firmware dosent exists on player
599 firmware = resolvePathCase(m_mountpoint + "/SYSTEM") +"/H10EMP.mi4";
600 //attempt other firmwarename
601 firmwareFI.setFile(firmware);
602 if(!firmwareFI.exists()) //Firmware dosent exists on player
604 m_dp->addItem(tr("Firmware does not exist: %1")
605 .arg(firmware),LOGERROR);
606 emit done(true);
607 return;
611 QFileInfo firmwareOrigFI(firmwareOrig);
613 if(!firmwareOrigFI.exists())
615 QFile firmwareFile(firmware);
617 //backup
618 QDir::home().mkdir("Iriver H10 Original Firmware Backup");
619 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Iriver H10 Original Firmware Backup/") + m_bootloadername);
620 firmwareFile.unsetError();
622 //rename
623 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
625 m_dp->addItem(tr("Could not rename: %1 to %2")
626 .arg(firmware,firmwareOrig),LOGERROR);
627 emit done(true);
628 return;
631 else //there is already a original firmware
633 QFile firmwareFile(firmware);
634 firmwareFile.remove();
636 //copy the firmware
637 if(!downloadFile.copy(firmware))
639 m_dp->addItem(tr("Could not copy: %1 to %2")
640 .arg(m_tempfilename,firmware),LOGERROR);
641 emit done(true);
642 return;
645 downloadFile.remove();
647 createInstallLog();
649 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
650 m_dp->abort();
652 emit done(false); // success
658 /**************************************************
659 *** mrobe100 secific code
660 ***************************************************/
661 void BootloaderInstaller::mrobe100Prepare()
663 if(m_install) // Installation
665 QString url = m_bootloaderUrlBase + "/olympus/mrobe100/" + m_bootloadername;
667 m_dp->addItem(tr("Downloading file %1.%2")
668 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
670 // temporary file needs to be opened to get the filename
671 downloadFile.open();
672 m_tempfilename = downloadFile.fileName();
673 downloadFile.close();
674 // get the real file.
675 getter = new HttpGet(this);
676 getter->setFile(&downloadFile);
678 // connect signals from HttpGet
679 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
680 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
681 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
683 getter->getFile(QUrl(url));
685 else // Uninstallation
688 QString firmwarename = m_bootloadername;
690 QString firmware;
691 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
692 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
694 QFileInfo firmwareFI(firmware);
695 if(!firmwareFI.exists()) //Firmware dosent exists on player
697 m_dp->addItem(tr("Firmware does not exist: %1")
698 .arg(firmware),LOGERROR);
699 emit done(true);
700 return;
703 QFileInfo firmwareOrigFI(firmwareOrig);
704 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
706 m_dp->addItem(tr("Original Firmware does not exist: %1")
707 .arg(firmwareOrig),LOGERROR);
708 emit done(true);
709 return;
712 QFile firmwareFile(firmware);
713 QFile firmwareOrigFile(firmwareOrig);
715 //remove modified firmware
716 if(!firmwareFile.remove())
718 m_dp->addItem(tr("Could not remove the Firmware at: %1")
719 .arg(firmware),LOGERROR);
720 emit done(true);
721 return;
724 // move original firmware back
725 if(!firmwareOrigFile.rename(firmware))
727 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
728 .arg(firmwareOrig,firmware),LOGERROR);
729 emit done(true);
730 return;
733 removeInstallLog();
735 emit done(false); //success
740 void BootloaderInstaller::mrobe100Finish()
742 QString firmwarename = m_bootloadername;
744 QString firmware;
745 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
746 // NOTE: the filename for the OF may not exist yet, so resolve path only!
747 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
749 QFileInfo firmwareFI(firmware);
751 if(!firmwareFI.exists()) //Firmware dosent exists on player
753 m_dp->addItem(tr("Firmware does not exist: %1")
754 .arg(firmware),LOGERROR);
755 emit done(true);
756 return;
759 QFileInfo firmwareOrigFI(firmwareOrig);
761 if(!firmwareOrigFI.exists())
763 QFile firmwareFile(firmware);
765 //backup
766 QDir::home().mkdir("Olympus mrobe100 Original Firmware Backup");
767 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Olympus mrobe100 Original Firmware Backup/") + m_bootloadername);
768 firmwareFile.unsetError();
769 //rename
770 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
772 m_dp->addItem(tr("Could not rename: %1 to %2")
773 .arg(firmware,firmwareOrig),LOGERROR);
774 emit done(true);
775 return;
778 else //there is already a original firmware
780 QFile firmwareFile(firmware);
781 firmwareFile.remove();
783 //copy the firmware
784 if(!downloadFile.copy(firmware))
786 m_dp->addItem(tr("Could not copy: %1 to %2")
787 .arg(m_tempfilename,firmware),LOGERROR);
788 emit done(true);
789 return;
792 downloadFile.remove();
794 createInstallLog();
796 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
797 m_dp->abort();
799 emit done(false); // success
803 /**************************************************
804 *** ipod secific code
805 ***************************************************/
806 int verbose =0;
807 // reserves memory for ipodpatcher
808 bool initIpodpatcher()
810 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
811 else return false;
814 void BootloaderInstaller::ipodPrepare()
816 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
817 struct ipod_t ipod;
819 int n = ipod_scan(&ipod);
820 if (n == 0)
822 m_dp->addItem(tr("No Ipods found"),LOGERROR);
823 emit done(true);
824 return;
826 if (n > 1)
828 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
829 emit done(true);
832 if(m_install) // Installation
835 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
837 m_dp->addItem(tr("Downloading file %1.%2")
838 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
840 // temporary file needs to be opened to get the filename
841 downloadFile.open();
842 m_tempfilename = downloadFile.fileName();
843 downloadFile.close();
844 // get the real file.
845 getter = new HttpGet(this);
846 getter->setFile(&downloadFile);
848 // connect signals from HttpGet
849 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
850 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
851 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
853 getter->getFile(QUrl(url));
855 else // Uninstallation
857 if (ipod_open(&ipod, 0) < 0)
859 m_dp->addItem(tr("could not open ipod"),LOGERROR);
860 emit done(true);
861 return;
864 if (read_partinfo(&ipod,0) < 0)
866 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
867 emit done(true);
868 return;
871 if (ipod.pinfo[0].start==0)
873 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
875 int i;
876 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
877 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
878 for ( i = 0; i < 4; i++ )
880 if (ipod.pinfo[i].start != 0)
882 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
883 i).arg(
884 ipod.pinfo[i].start).arg(
885 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
886 ipod.pinfo[i].size/sectors_per_MB).arg(
887 get_parttype(ipod.pinfo[i].type)).arg(
888 ipod.pinfo[i].type),LOGINFO);
891 emit done(true);
892 return;
895 read_directory(&ipod);
897 if (ipod.nimages <= 0)
899 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
900 emit done(true);
901 return;
903 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
905 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
906 ipod.ipod_directory[0].vers),LOGERROR);
907 emit done(true);
908 return;
911 if (ipod.macpod)
913 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
914 "this. Convert it to WinPod\n"
915 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
916 LOGWARNING);
917 emit done(true);
918 return;
921 if (ipod_reopen_rw(&ipod) < 0)
923 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
924 emit done(true);
925 return;
928 if (ipod.ipod_directory[0].entryOffset==0) {
929 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
930 emit done(true);
931 return;
934 if (delete_bootloader(&ipod)==0)
936 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
937 removeInstallLog();
938 emit done(false);
939 ipod_close(&ipod);
940 return;
942 else
944 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
945 emit done(true);
946 ipod_close(&ipod);
947 return;
952 void BootloaderInstaller::ipodFinish()
954 struct ipod_t ipod;
955 ipod_scan(&ipod);
957 if (ipod_open(&ipod, 0) < 0)
959 m_dp->addItem(tr("could not open ipod"),LOGERROR);
960 emit done(true);
961 return;
964 if (read_partinfo(&ipod,0) < 0)
966 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
967 emit done(true);
968 return;
971 if (ipod.pinfo[0].start==0)
973 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
975 int i;
976 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
978 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
980 for ( i = 0; i < 4; i++ )
982 if (ipod.pinfo[i].start != 0)
984 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
985 i).arg(
986 ipod.pinfo[i].start).arg(
987 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
988 ipod.pinfo[i].size/sectors_per_MB).arg(
989 get_parttype(ipod.pinfo[i].type)).arg(
990 ipod.pinfo[i].type),LOGWARNING);
993 emit done(true);
994 return;
997 read_directory(&ipod);
999 if (ipod.nimages <= 0)
1001 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
1002 emit done(true);
1003 return;
1005 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
1007 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
1008 ipod.ipod_directory[0].vers),LOGERROR);
1009 emit done(true);
1010 return;
1013 if (ipod.macpod)
1015 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
1016 "this. Convert it to WinPod\n"
1017 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
1018 LOGWARNING);
1019 emit done(true);
1020 return;
1023 if (ipod_reopen_rw(&ipod) < 0)
1025 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
1026 emit done(true);
1027 return;
1030 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
1032 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1033 createInstallLog();
1034 emit done(false);
1035 ipod_close(&ipod);
1036 return;
1038 else
1040 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1041 ipod_close(&ipod);
1042 emit done(true);
1043 return;
1047 /**************************************************
1048 *** sansa secific code
1049 ***************************************************/
1050 // reserves memory for sansapatcher
1051 bool initSansapatcher()
1053 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
1054 else return false;
1058 void BootloaderInstaller::sansaPrepare()
1060 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
1061 struct sansa_t sansa;
1063 int n = sansa_scan(&sansa);
1064 if (n == 0)
1066 m_dp->addItem(tr("No Sansa found"),LOGERROR);
1067 emit done(true);
1068 return;
1070 if (n > 1)
1072 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
1073 emit done(true);
1076 if(m_install) // Installation
1078 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
1079 + QString(sansa.targetname) + "/" + m_bootloadername;
1081 m_dp->addItem(tr("Downloading file %1.%2")
1082 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1084 // temporary file needs to be opened to get the filename
1085 downloadFile.open();
1086 m_tempfilename = downloadFile.fileName();
1087 downloadFile.close();
1088 // get the real file.
1089 getter = new HttpGet(this);
1090 getter->setFile(&downloadFile);
1092 // connect signals from HttpGet
1093 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1094 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
1095 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1097 getter->getFile(QUrl(url));
1099 else // Uninstallation
1102 if (sansa_open(&sansa, 0) < 0)
1104 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1105 emit done(true);
1106 return;
1109 if (sansa_read_partinfo(&sansa,0) < 0)
1111 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1112 emit done(true);
1113 return;
1116 int i = is_sansa(&sansa);
1117 if (i < 0) {
1118 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1119 emit done(true);
1120 return;
1123 if (sansa.hasoldbootloader)
1125 m_dp->addItem(tr("********************************************\n"
1126 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1127 "You must reinstall the original Sansa firmware before running\n"
1128 "sansapatcher for the first time.\n"
1129 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1130 "*********************************************\n"),LOGERROR);
1131 emit done(true);
1132 return;
1136 if (sansa_reopen_rw(&sansa) < 0)
1138 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1139 emit done(true);
1140 return;
1143 if (sansa_delete_bootloader(&sansa)==0)
1145 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
1146 removeInstallLog();
1147 emit done(false);
1148 sansa_close(&sansa);
1149 return;
1151 else
1153 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
1154 emit done(true);
1155 sansa_close(&sansa);
1156 return;
1161 void BootloaderInstaller::sansaFinish()
1163 struct sansa_t sansa;
1164 sansa_scan(&sansa);
1166 if (sansa_open(&sansa, 0) < 0)
1168 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1169 emit done(true);
1170 return;
1173 if (sansa_read_partinfo(&sansa,0) < 0)
1175 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1176 emit done(true);
1177 return;
1181 int i = is_sansa(&sansa);
1182 if (i < 0) {
1184 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1185 emit done(true);
1186 return;
1189 if (sansa.hasoldbootloader)
1191 m_dp->addItem(tr("********************************************\n"
1192 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1193 "You must reinstall the original Sansa firmware before running\n"
1194 "sansapatcher for the first time.\n"
1195 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1196 "*********************************************\n"),LOGERROR);
1197 emit done(true);
1198 return;
1201 if (sansa_reopen_rw(&sansa) < 0)
1203 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1204 emit done(true);
1205 return;
1208 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1210 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1211 createInstallLog();
1212 emit done(false);
1213 sansa_close(&sansa);
1214 return;
1216 else
1218 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1219 sansa_close(&sansa);
1220 emit done(true);
1221 return;
1226 /**************************************************
1227 *** iriver /fwpatcher secific code
1228 ***************************************************/
1230 void BootloaderInstaller::iriverPrepare()
1232 char md5sum_str[32];
1233 if (!FileMD5(m_origfirmware, md5sum_str)) {
1234 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
1235 emit done(true);
1236 return;
1239 /* Check firmware against md5sums in h120sums and h100sums */
1240 series = 0;
1241 table_entry = intable(md5sum_str, &h120pairs[0],
1242 sizeof(h120pairs)/sizeof(struct sumpairs));
1243 if (table_entry >= 0) {
1244 series = 120;
1246 else
1248 table_entry = intable(md5sum_str, &h100pairs[0],
1249 sizeof(h100pairs)/sizeof(struct sumpairs));
1250 if (table_entry >= 0)
1252 series = 100;
1254 else
1256 table_entry = intable(md5sum_str, &h300pairs[0],
1257 sizeof(h300pairs)/sizeof(struct sumpairs));
1258 if (table_entry >= 0)
1259 series = 300;
1262 if (series == 0)
1264 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1265 emit done(true);
1266 return;
1269 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1271 m_dp->addItem(tr("Downloading file %1.%2")
1272 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1274 // temporary file needs to be opened to get the filename
1275 downloadFile.open();
1276 m_tempfilename = downloadFile.fileName();
1277 downloadFile.close();
1278 // get the real file.
1279 getter = new HttpGet(this);
1280 getter->setFile(&downloadFile);
1282 // connect signals from HttpGet
1283 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1284 connect(getter, SIGNAL(dataReadProgress(int, int)), m_dp, SLOT(setProgress(int, int)));
1285 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1287 getter->getFile(QUrl(url));
1290 void BootloaderInstaller::iriverFinish()
1292 // Patch firmware
1293 char md5sum_str[32];
1294 struct sumpairs *sums = 0;
1295 int origin = 0;
1297 /* get pointer to the correct bootloader.bin */
1298 switch(series) {
1299 case 100:
1300 sums = &h100pairs[0];
1301 origin = 0x1f0000;
1302 break;
1303 case 120:
1304 sums = &h120pairs[0];
1305 origin = 0x1f0000;
1306 break;
1307 case 300:
1308 sums = &h300pairs[0];
1309 origin = 0x3f0000;
1310 break;
1313 // temporary files needs to be opened to get the filename
1314 QTemporaryFile firmwareBin, newBin, newHex;
1315 firmwareBin.open();
1316 newBin.open();
1317 newHex.open();
1318 QString firmwareBinName = firmwareBin.fileName();
1319 QString newBinName = newBin.fileName();
1320 QString newHexName = newHex.fileName();
1321 firmwareBin.close();
1322 newBin.close();
1323 newHex.close();
1325 // iriver decode
1326 int result;
1327 if ((result = iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE)) < 0)
1329 QString error;
1330 switch(result) {
1331 case -1: error = tr("Can't open input file"); break;
1332 case -2: error = tr("Can't open output file"); break;
1333 case -3: error = tr("invalid file: header length wrong"); break;
1334 case -4: error = tr("invalid file: unrecognized header"); break;
1335 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1336 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1337 case -7: error = tr("invalid file: internal checksum error"); break;
1338 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1339 default: error = tr("unknown"); break;
1341 m_dp->addItem(tr("Error in descramble: %1").arg(error), LOGERROR);
1342 firmwareBin.remove();
1343 newBin.remove();
1344 newHex.remove();
1345 emit done(true);
1346 return;
1348 // mkboot
1349 if((result = mkboot(firmwareBinName, newBinName, m_tempfilename, origin)) < 0)
1351 QString error;
1352 switch(result) {
1353 case -1: error = tr("could not open input file"); break;
1354 case -2: error = tr("reading header failed"); break;
1355 case -3: error = tr("reading firmware failed"); break;
1356 case -4: error = tr("can't open bootloader file"); break;
1357 case -5: error = tr("reading bootloader file failed"); break;
1358 case -6: error = tr("can't open output file"); break;
1359 case -7: error = tr("writing output file failed"); break;
1361 m_dp->addItem(tr("Error in patching: %1").arg(error), LOGERROR);
1363 firmwareBin.remove();
1364 newBin.remove();
1365 newHex.remove();
1366 emit done(true);
1367 return;
1369 // iriver_encode
1370 if((result = iriver_encode(newBinName, newHexName, FALSE)) < 0)
1372 QString error;
1373 switch(result) {
1374 case -1: error = tr("Can't open input file"); break;
1375 case -2: error = tr("Can't open output file"); break;
1376 case -3: error = tr("invalid file: header length wrong"); break;
1377 case -4: error = tr("invalid file: unrecognized header"); break;
1378 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1379 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1380 case -7: error = tr("invalid file: internal checksum error"); break;
1381 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1382 default: error = tr("unknown"); break;
1384 m_dp->addItem(tr("Error in scramble: %1").arg(error), LOGERROR);
1386 firmwareBin.remove();
1387 newBin.remove();
1388 newHex.remove();
1389 emit done(true);
1390 return;
1393 /* now md5sum it */
1394 if (!FileMD5(newHexName, md5sum_str))
1396 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1397 firmwareBin.remove();
1398 newBin.remove();
1399 newHex.remove();
1400 emit done(true);
1401 return;
1403 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1404 /* delete temp files */
1405 firmwareBin.remove();
1406 newBin.remove();
1409 // Load patched Firmware to player
1410 QString dest;
1411 if(series == 100)
1412 dest = m_mountpoint + "/ihp_100.hex";
1413 else if(series == 120)
1414 dest = m_mountpoint + "/ihp_120.hex";
1415 else if(series == 300)
1416 dest = m_mountpoint + "/H300.hex";
1418 // copy file
1419 QFile destfile(dest);
1420 if(destfile.exists()) destfile.remove();
1421 if(!newHex.copy(dest))
1423 m_dp->addItem(tr("Could not copy: %1 to %2")
1424 .arg(newHexName,dest),LOGERROR);
1425 emit done(true);
1426 return;
1429 downloadFile.remove();
1430 newHex.remove();
1432 createInstallLog();
1434 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1435 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1436 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1437 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1438 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1439 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1440 m_dp->abort();
1442 emit done(false); // success