Move error message generation out of irivertools.cpp to make it independent from...
[Rockbox.git] / rbutil / rbutilqt / installbootloader.cpp
blob10f6a9f678601666fd003174fecc6864f03b96f1
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();
185 void BootloaderInstaller::updateDataReadProgress(int read, int total)
187 m_dp->setProgressMax(total);
188 m_dp->setProgressValue(read);
189 qDebug() << "progress:" << read << "/" << total;
193 void BootloaderInstaller::installEnded(bool error)
195 (void) error;
196 m_dp->abort();
199 bool BootloaderInstaller::downloadInfo()
201 // try to get the current build information
202 infodownloader = new HttpGet(this);
204 connect(infodownloader, SIGNAL(done(bool)), this, SLOT(infoDownloadDone(bool)));
205 connect(infodownloader, SIGNAL(requestFinished(int, bool)), this, SLOT(infoRequestFinished(int, bool)));
207 qDebug() << "downloading bootloader info";
208 infodownloader->setFile(&bootloaderInfo);
209 infodownloader->getFile(QUrl(m_bootloaderinfoUrl));
211 // block until its downloaded
212 qDebug() << "Waiting for Download finished";
213 infoDownloaded=false;
214 infoError = false;
215 while(!infoDownloaded )
216 QCoreApplication::processEvents();
217 return !infoError;
220 void BootloaderInstaller::infoDownloadDone(bool error)
222 if(error)
224 qDebug() << "network error:" << infodownloader->error();
225 return;
227 qDebug() << "network status:" << infodownloader->error();
229 infoDownloaded = true;
232 void BootloaderInstaller::infoRequestFinished(int id, bool error)
235 if(error)
237 QString errorString;
238 errorString = tr("Network error: %1. Please check your network and proxy settings.")
239 .arg(infodownloader->errorString());
240 #ifndef CONSOLE
241 if(error) QMessageBox::about(NULL, "Network Error", errorString);
242 #endif
243 qDebug() << "downloadDone:" << id << error;
245 infoError = true;
246 infoDownloaded = true;
248 qDebug() << "infoRequestFinished:" << id << error;
252 void BootloaderInstaller::createInstallLog()
254 m_dp->addItem(tr("Creating installation log"),LOGINFO);
255 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
257 bootloaderInfo.open();
258 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
259 bootloaderInfo.close();
260 info.beginGroup(m_device);
262 installlog.beginGroup("Bootloader");
263 installlog.setValue("md5sum",info.value("md5sum").toString());
264 installlog.endGroup();
265 installlog.sync();
268 void BootloaderInstaller::removeInstallLog()
270 m_dp->addItem(tr("Editing installation log"),LOGINFO);
271 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
272 installlog.beginGroup("Bootloader");
273 installlog.remove("md5sum");
274 installlog.endGroup();
275 installlog.sync();
279 bool BootloaderInstaller::uptodate()
281 QString installedMd5;
282 QString serverMd5;
284 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
285 installlog.beginGroup("Bootloader");
286 installedMd5 = installlog.value("md5sum").toString();
287 installlog.endGroup();
289 if(installedMd5.isEmpty())
290 return false;
291 bootloaderInfo.open();
292 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
293 bootloaderInfo.close();
294 info.beginGroup(m_device);
295 serverMd5 = info.value("md5sum").toString();
296 info.endGroup();
298 if(installedMd5 != serverMd5)
299 return false;
300 else
301 return true;
304 /**************************************************
305 *** gigabeat secific code
306 ***************************************************/
308 void BootloaderInstaller::gigabeatPrepare()
310 if(m_install) // Installation
312 QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername;
314 m_dp->addItem(tr("Downloading file %1.%2")
315 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
317 // temporary file needs to be opened to get the filename
318 downloadFile.open();
319 m_tempfilename = downloadFile.fileName();
320 downloadFile.close();
321 // get the real file.
322 getter = new HttpGet(this);
323 getter->setFile(&downloadFile);
324 // connect signals from HttpGet
325 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
326 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
327 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
329 getter->getFile(QUrl(url));
331 else //UnInstallation
333 QString firmware;
334 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT");
335 QString firmwareOrig = resolvePathCase(firmware.append(".ORIG"));
337 QFileInfo firmwareOrigFI(firmwareOrig);
339 // check if original firmware exists
340 if(!firmwareOrigFI.exists())
342 m_dp->addItem(tr("Could not find the Original Firmware at: %1")
343 .arg(firmwareOrig),LOGERROR);
344 emit done(true);
345 return;
348 QFile firmwareFile(firmware);
349 QFile firmwareOrigFile(firmwareOrig);
351 //remove modified firmware
352 if(!firmwareFile.remove())
354 m_dp->addItem(tr("Could not remove the Firmware at: %1")
355 .arg(firmware),LOGERROR);
356 emit done(true);
357 return;
360 // rename original firmware back
361 if(!firmwareOrigFile.rename(firmware))
363 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
364 .arg(firmwareOrig,firmware),LOGERROR);
365 emit done(true);
366 return;
369 removeInstallLog();
371 emit done(false); //success
376 void BootloaderInstaller::gigabeatFinish()
378 // this step is only need for installation, so no code for uninstall here
380 m_dp->addItem(tr("Finishing bootloader install"),LOGINFO);
382 QString firmware;
383 firmware = resolvePathCase(m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername);
385 QFileInfo firmwareFI(firmware);
387 // check if firmware exists
388 if(!firmwareFI.exists())
390 m_dp->addItem(tr("Could not find the Firmware at: %1")
391 .arg(firmware),LOGERROR);
392 emit done(true);
393 return;
396 QString firmwareOrig = firmware;
397 firmwareOrig.append(".ORIG");
398 QFileInfo firmwareOrigFI(firmwareOrig);
400 // rename and backup the firmware, if there is no original firmware there
401 if(!firmwareOrigFI.exists())
403 QFile firmwareFile(firmware);
404 //backup
405 QDir::home().mkdir("Gigabeat Original Firmware Backup");
406 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Gigabeat Original Firmware Backup/") + m_bootloadername);
407 firmwareFile.unsetError();
408 //rename
409 if(!firmwareFile.rename(firmwareOrig))
411 m_dp->addItem(tr("Could not rename: %1 to %2")
412 .arg(firmware,firmwareOrig),LOGERROR);
413 emit done(true);
414 return;
417 else // or remove the normal firmware, if the original is there
419 QFile firmwareFile(firmware);
420 firmwareFile.remove();
423 //copy the firmware
424 if(!downloadFile.copy(firmware))
426 m_dp->addItem(tr("Could not copy: %1 to %2")
427 .arg(m_tempfilename,firmware),LOGERROR);
428 emit done(true);
429 return;
432 downloadFile.remove();
434 createInstallLog();
436 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
437 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
438 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
439 m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO);
440 m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO);
441 m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO);
442 m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO);
445 m_dp->abort();
447 emit done(false); // success
451 /**************************************************
452 *** iaudio secific code
453 ***************************************************/
454 void BootloaderInstaller::iaudioPrepare()
457 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
459 m_dp->addItem(tr("Downloading file %1.%2")
460 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
462 // temporary file needs to be opened to get the filename
463 downloadFile.open();
464 m_tempfilename = downloadFile.fileName();
465 downloadFile.close();
466 // get the real file.
467 getter = new HttpGet(this);
468 getter->setFile(&downloadFile);
469 getter->getFile(QUrl(url));
470 // connect signals from HttpGet
471 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
472 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
473 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
476 void BootloaderInstaller::iaudioFinish()
478 QString firmware;
479 firmware = resolvePathCase(m_mountpoint + "/FIRMWARE/") + "/" + m_bootloadername;
481 //copy the firmware
482 if(!downloadFile.copy(firmware))
484 m_dp->addItem(tr("Could not copy: %1 to %2")
485 .arg(m_tempfilename,firmware),LOGERROR);
486 emit done(true);
487 return;
490 downloadFile.remove();
492 createInstallLog();
494 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
495 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
496 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
497 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
498 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
500 m_dp->abort();
502 emit done(false); // success
507 /**************************************************
508 *** h10 secific code
509 ***************************************************/
510 void BootloaderInstaller::h10Prepare()
512 if(m_install) // Installation
514 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
516 m_dp->addItem(tr("Downloading file %1.%2")
517 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
519 // temporary file needs to be opened to get the filename
520 downloadFile.open();
521 m_tempfilename = downloadFile.fileName();
522 downloadFile.close();
523 // get the real file.
524 getter = new HttpGet(this);
525 getter->setFile(&downloadFile);
526 // connect signals from HttpGet
527 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
528 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
529 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
531 getter->getFile(QUrl(url));
533 else // Uninstallation
536 QString firmwarename = m_bootloadername.section('/', -1);
538 QString firmware;
539 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
540 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
542 QFileInfo firmwareFI(firmware);
543 if(!firmwareFI.exists()) //Firmware dosent exists on player
545 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/H10EMP.mi4");
546 //attempt other firmwarename
547 firmwareFI.setFile(firmware);
548 if(!firmwareFI.exists()) //Firmware dosent exists on player
550 m_dp->addItem(tr("Firmware does not exist: %1")
551 .arg(firmware),LOGERROR);
552 emit done(true);
553 return;
557 QFileInfo firmwareOrigFI(firmwareOrig);
558 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
560 m_dp->addItem(tr("Original Firmware does not exist: %1")
561 .arg(firmwareOrig),LOGERROR);
562 emit done(true);
563 return;
566 QFile firmwareFile(firmware);
567 QFile firmwareOrigFile(firmwareOrig);
569 //remove modified firmware
570 if(!firmwareFile.remove())
572 m_dp->addItem(tr("Could not remove the Firmware at: %1")
573 .arg(firmware),LOGERROR);
574 emit done(true);
575 return;
578 // rename original firmware back
579 if(!firmwareOrigFile.rename(firmware))
581 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
582 .arg(firmwareOrig,firmware),LOGERROR);
583 emit done(true);
584 return;
587 removeInstallLog();
589 emit done(false); //success
594 void BootloaderInstaller::h10Finish()
596 QString firmwarename = m_bootloadername.section('/', -1);
598 QString firmware;
599 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
600 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
602 QFileInfo firmwareFI(firmware);
604 if(!firmwareFI.exists()) //Firmware dosent exists on player
606 firmware = resolvePathCase(m_mountpoint + "/SYSTEM") +"/H10EMP.mi4";
607 //attempt other firmwarename
608 firmwareFI.setFile(firmware);
609 if(!firmwareFI.exists()) //Firmware dosent exists on player
611 m_dp->addItem(tr("Firmware does not exist: %1")
612 .arg(firmware),LOGERROR);
613 emit done(true);
614 return;
618 QFileInfo firmwareOrigFI(firmwareOrig);
620 if(!firmwareOrigFI.exists())
622 QFile firmwareFile(firmware);
624 //backup
625 QDir::home().mkdir("Iriver H10 Original Firmware Backup");
626 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Iriver H10 Original Firmware Backup/") + m_bootloadername);
627 firmwareFile.unsetError();
629 //rename
630 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
632 m_dp->addItem(tr("Could not rename: %1 to %2")
633 .arg(firmware,firmwareOrig),LOGERROR);
634 emit done(true);
635 return;
638 else //there is already a original firmware
640 QFile firmwareFile(firmware);
641 firmwareFile.remove();
643 //copy the firmware
644 if(!downloadFile.copy(firmware))
646 m_dp->addItem(tr("Could not copy: %1 to %2")
647 .arg(m_tempfilename,firmware),LOGERROR);
648 emit done(true);
649 return;
652 downloadFile.remove();
654 createInstallLog();
656 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
657 m_dp->abort();
659 emit done(false); // success
665 /**************************************************
666 *** mrobe100 secific code
667 ***************************************************/
668 void BootloaderInstaller::mrobe100Prepare()
670 if(m_install) // Installation
672 QString url = m_bootloaderUrlBase + "/olympus/mrobe100/" + m_bootloadername;
674 m_dp->addItem(tr("Downloading file %1.%2")
675 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
677 // temporary file needs to be opened to get the filename
678 downloadFile.open();
679 m_tempfilename = downloadFile.fileName();
680 downloadFile.close();
681 // get the real file.
682 getter = new HttpGet(this);
683 getter->setFile(&downloadFile);
685 // connect signals from HttpGet
686 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
687 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
688 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
690 getter->getFile(QUrl(url));
692 else // Uninstallation
695 QString firmwarename = m_bootloadername;
697 QString firmware;
698 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
699 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
701 QFileInfo firmwareFI(firmware);
702 if(!firmwareFI.exists()) //Firmware dosent exists on player
704 m_dp->addItem(tr("Firmware does not exist: %1")
705 .arg(firmware),LOGERROR);
706 emit done(true);
707 return;
710 QFileInfo firmwareOrigFI(firmwareOrig);
711 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
713 m_dp->addItem(tr("Original Firmware does not exist: %1")
714 .arg(firmwareOrig),LOGERROR);
715 emit done(true);
716 return;
719 QFile firmwareFile(firmware);
720 QFile firmwareOrigFile(firmwareOrig);
722 //remove modified firmware
723 if(!firmwareFile.remove())
725 m_dp->addItem(tr("Could not remove the Firmware at: %1")
726 .arg(firmware),LOGERROR);
727 emit done(true);
728 return;
731 // move original firmware back
732 if(!firmwareOrigFile.rename(firmware))
734 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
735 .arg(firmwareOrig,firmware),LOGERROR);
736 emit done(true);
737 return;
740 removeInstallLog();
742 emit done(false); //success
747 void BootloaderInstaller::mrobe100Finish()
749 QString firmwarename = m_bootloadername;
751 QString firmware;
752 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
753 // NOTE: the filename for the OF may not exist yet, so resolve path only!
754 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
756 QFileInfo firmwareFI(firmware);
758 if(!firmwareFI.exists()) //Firmware dosent exists on player
760 m_dp->addItem(tr("Firmware does not exist: %1")
761 .arg(firmware),LOGERROR);
762 emit done(true);
763 return;
766 QFileInfo firmwareOrigFI(firmwareOrig);
768 if(!firmwareOrigFI.exists())
770 QFile firmwareFile(firmware);
772 //backup
773 QDir::home().mkdir("Olympus mrobe100 Original Firmware Backup");
774 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Olympus mrobe100 Original Firmware Backup/") + m_bootloadername);
775 firmwareFile.unsetError();
776 //rename
777 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
779 m_dp->addItem(tr("Could not rename: %1 to %2")
780 .arg(firmware,firmwareOrig),LOGERROR);
781 emit done(true);
782 return;
785 else //there is already a original firmware
787 QFile firmwareFile(firmware);
788 firmwareFile.remove();
790 //copy the firmware
791 if(!downloadFile.copy(firmware))
793 m_dp->addItem(tr("Could not copy: %1 to %2")
794 .arg(m_tempfilename,firmware),LOGERROR);
795 emit done(true);
796 return;
799 downloadFile.remove();
801 createInstallLog();
803 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
804 m_dp->abort();
806 emit done(false); // success
810 /**************************************************
811 *** ipod secific code
812 ***************************************************/
813 int verbose =0;
814 // reserves memory for ipodpatcher
815 bool initIpodpatcher()
817 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
818 else return false;
821 void BootloaderInstaller::ipodPrepare()
823 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
824 struct ipod_t ipod;
826 int n = ipod_scan(&ipod);
827 if (n == 0)
829 m_dp->addItem(tr("No Ipods found"),LOGERROR);
830 emit done(true);
831 return;
833 if (n > 1)
835 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
836 emit done(true);
839 if(m_install) // Installation
842 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
844 m_dp->addItem(tr("Downloading file %1.%2")
845 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
847 // temporary file needs to be opened to get the filename
848 downloadFile.open();
849 m_tempfilename = downloadFile.fileName();
850 downloadFile.close();
851 // get the real file.
852 getter = new HttpGet(this);
853 getter->setFile(&downloadFile);
855 // connect signals from HttpGet
856 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
857 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
858 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
860 getter->getFile(QUrl(url));
862 else // Uninstallation
864 if (ipod_open(&ipod, 0) < 0)
866 m_dp->addItem(tr("could not open ipod"),LOGERROR);
867 emit done(true);
868 return;
871 if (read_partinfo(&ipod,0) < 0)
873 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
874 emit done(true);
875 return;
878 if (ipod.pinfo[0].start==0)
880 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
882 int i;
883 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
884 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
885 for ( i = 0; i < 4; i++ )
887 if (ipod.pinfo[i].start != 0)
889 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
890 i).arg(
891 ipod.pinfo[i].start).arg(
892 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
893 ipod.pinfo[i].size/sectors_per_MB).arg(
894 get_parttype(ipod.pinfo[i].type)).arg(
895 ipod.pinfo[i].type),LOGINFO);
898 emit done(true);
899 return;
902 read_directory(&ipod);
904 if (ipod.nimages <= 0)
906 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
907 emit done(true);
908 return;
910 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
912 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
913 ipod.ipod_directory[0].vers),LOGERROR);
914 emit done(true);
915 return;
918 if (ipod.macpod)
920 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
921 "this. Convert it to WinPod\n"
922 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
923 LOGWARNING);
924 emit done(true);
925 return;
928 if (ipod_reopen_rw(&ipod) < 0)
930 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
931 emit done(true);
932 return;
935 if (ipod.ipod_directory[0].entryOffset==0) {
936 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
937 emit done(true);
938 return;
941 if (delete_bootloader(&ipod)==0)
943 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
944 removeInstallLog();
945 emit done(false);
946 ipod_close(&ipod);
947 return;
949 else
951 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
952 emit done(true);
953 ipod_close(&ipod);
954 return;
959 void BootloaderInstaller::ipodFinish()
961 struct ipod_t ipod;
962 ipod_scan(&ipod);
964 if (ipod_open(&ipod, 0) < 0)
966 m_dp->addItem(tr("could not open ipod"),LOGERROR);
967 emit done(true);
968 return;
971 if (read_partinfo(&ipod,0) < 0)
973 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
974 emit done(true);
975 return;
978 if (ipod.pinfo[0].start==0)
980 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
982 int i;
983 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
985 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
987 for ( i = 0; i < 4; i++ )
989 if (ipod.pinfo[i].start != 0)
991 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
992 i).arg(
993 ipod.pinfo[i].start).arg(
994 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
995 ipod.pinfo[i].size/sectors_per_MB).arg(
996 get_parttype(ipod.pinfo[i].type)).arg(
997 ipod.pinfo[i].type),LOGWARNING);
1000 emit done(true);
1001 return;
1004 read_directory(&ipod);
1006 if (ipod.nimages <= 0)
1008 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
1009 emit done(true);
1010 return;
1012 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
1014 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
1015 ipod.ipod_directory[0].vers),LOGERROR);
1016 emit done(true);
1017 return;
1020 if (ipod.macpod)
1022 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
1023 "this. Convert it to WinPod\n"
1024 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
1025 LOGWARNING);
1026 emit done(true);
1027 return;
1030 if (ipod_reopen_rw(&ipod) < 0)
1032 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
1033 emit done(true);
1034 return;
1037 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
1039 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1040 createInstallLog();
1041 emit done(false);
1042 ipod_close(&ipod);
1043 return;
1045 else
1047 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1048 ipod_close(&ipod);
1049 emit done(true);
1050 return;
1054 /**************************************************
1055 *** sansa secific code
1056 ***************************************************/
1057 // reserves memory for sansapatcher
1058 bool initSansapatcher()
1060 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
1061 else return false;
1065 void BootloaderInstaller::sansaPrepare()
1067 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
1068 struct sansa_t sansa;
1070 int n = sansa_scan(&sansa);
1071 if (n == 0)
1073 m_dp->addItem(tr("No Sansa found"),LOGERROR);
1074 emit done(true);
1075 return;
1077 if (n > 1)
1079 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
1080 emit done(true);
1083 if(m_install) // Installation
1085 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
1086 + QString(sansa.targetname) + "/" + m_bootloadername;
1088 m_dp->addItem(tr("Downloading file %1.%2")
1089 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1091 // temporary file needs to be opened to get the filename
1092 downloadFile.open();
1093 m_tempfilename = downloadFile.fileName();
1094 downloadFile.close();
1095 // get the real file.
1096 getter = new HttpGet(this);
1097 getter->setFile(&downloadFile);
1099 // connect signals from HttpGet
1100 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1101 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
1102 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1104 getter->getFile(QUrl(url));
1106 else // Uninstallation
1109 if (sansa_open(&sansa, 0) < 0)
1111 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1112 emit done(true);
1113 return;
1116 if (sansa_read_partinfo(&sansa,0) < 0)
1118 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1119 emit done(true);
1120 return;
1123 int i = is_sansa(&sansa);
1124 if (i < 0) {
1125 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1126 emit done(true);
1127 return;
1130 if (sansa.hasoldbootloader)
1132 m_dp->addItem(tr("********************************************\n"
1133 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1134 "You must reinstall the original Sansa firmware before running\n"
1135 "sansapatcher for the first time.\n"
1136 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1137 "*********************************************\n"),LOGERROR);
1138 emit done(true);
1139 return;
1143 if (sansa_reopen_rw(&sansa) < 0)
1145 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1146 emit done(true);
1147 return;
1150 if (sansa_delete_bootloader(&sansa)==0)
1152 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
1153 removeInstallLog();
1154 emit done(false);
1155 sansa_close(&sansa);
1156 return;
1158 else
1160 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
1161 emit done(true);
1162 sansa_close(&sansa);
1163 return;
1168 void BootloaderInstaller::sansaFinish()
1170 struct sansa_t sansa;
1171 sansa_scan(&sansa);
1173 if (sansa_open(&sansa, 0) < 0)
1175 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1176 emit done(true);
1177 return;
1180 if (sansa_read_partinfo(&sansa,0) < 0)
1182 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1183 emit done(true);
1184 return;
1188 int i = is_sansa(&sansa);
1189 if (i < 0) {
1191 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1192 emit done(true);
1193 return;
1196 if (sansa.hasoldbootloader)
1198 m_dp->addItem(tr("********************************************\n"
1199 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1200 "You must reinstall the original Sansa firmware before running\n"
1201 "sansapatcher for the first time.\n"
1202 "See http://www.rockbox.org/wiki/SansaE200Install\n"
1203 "*********************************************\n"),LOGERROR);
1204 emit done(true);
1205 return;
1208 if (sansa_reopen_rw(&sansa) < 0)
1210 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1211 emit done(true);
1212 return;
1215 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1217 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1218 createInstallLog();
1219 emit done(false);
1220 sansa_close(&sansa);
1221 return;
1223 else
1225 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1226 sansa_close(&sansa);
1227 emit done(true);
1228 return;
1233 /**************************************************
1234 *** iriver /fwpatcher secific code
1235 ***************************************************/
1237 void BootloaderInstaller::iriverPrepare()
1239 char md5sum_str[32];
1240 if (!FileMD5(m_origfirmware, md5sum_str)) {
1241 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
1242 emit done(true);
1243 return;
1246 /* Check firmware against md5sums in h120sums and h100sums */
1247 series = 0;
1248 table_entry = intable(md5sum_str, &h120pairs[0],
1249 sizeof(h120pairs)/sizeof(struct sumpairs));
1250 if (table_entry >= 0) {
1251 series = 120;
1253 else
1255 table_entry = intable(md5sum_str, &h100pairs[0],
1256 sizeof(h100pairs)/sizeof(struct sumpairs));
1257 if (table_entry >= 0)
1259 series = 100;
1261 else
1263 table_entry = intable(md5sum_str, &h300pairs[0],
1264 sizeof(h300pairs)/sizeof(struct sumpairs));
1265 if (table_entry >= 0)
1266 series = 300;
1269 if (series == 0)
1271 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1272 emit done(true);
1273 return;
1276 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1278 m_dp->addItem(tr("Downloading file %1.%2")
1279 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1281 // temporary file needs to be opened to get the filename
1282 downloadFile.open();
1283 m_tempfilename = downloadFile.fileName();
1284 downloadFile.close();
1285 // get the real file.
1286 getter = new HttpGet(this);
1287 getter->setFile(&downloadFile);
1289 // connect signals from HttpGet
1290 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1291 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
1292 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1294 getter->getFile(QUrl(url));
1297 void BootloaderInstaller::iriverFinish()
1299 // Patch firmware
1300 char md5sum_str[32];
1301 struct sumpairs *sums = 0;
1302 int origin = 0;
1304 /* get pointer to the correct bootloader.bin */
1305 switch(series) {
1306 case 100:
1307 sums = &h100pairs[0];
1308 origin = 0x1f0000;
1309 break;
1310 case 120:
1311 sums = &h120pairs[0];
1312 origin = 0x1f0000;
1313 break;
1314 case 300:
1315 sums = &h300pairs[0];
1316 origin = 0x3f0000;
1317 break;
1320 // temporary files needs to be opened to get the filename
1321 QTemporaryFile firmwareBin, newBin, newHex;
1322 firmwareBin.open();
1323 newBin.open();
1324 newHex.open();
1325 QString firmwareBinName = firmwareBin.fileName();
1326 QString newBinName = newBin.fileName();
1327 QString newHexName = newHex.fileName();
1328 firmwareBin.close();
1329 newBin.close();
1330 newHex.close();
1332 // iriver decode
1333 int result;
1334 if ((result = iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE)) < 0)
1336 QString error;
1337 switch(result) {
1338 case -1: error = tr("Can't open input file"); break;
1339 case -2: error = tr("Can't open output file"); break;
1340 case -3: error = tr("invalid file: header length wrong"); break;
1341 case -4: error = tr("invalid file: unrecognized header"); break;
1342 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1343 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1344 case -7: error = tr("invalid file: internal checksum error"); break;
1345 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1346 default: error = tr("unknown"); break;
1348 m_dp->addItem(tr("Error in descramble: %1").arg(error), LOGERROR);
1349 firmwareBin.remove();
1350 newBin.remove();
1351 newHex.remove();
1352 emit done(true);
1353 return;
1355 // mkboot
1356 if((result = mkboot(firmwareBinName, newBinName, m_tempfilename, origin)) < 0)
1358 QString error;
1359 switch(result) {
1360 case -1: error = tr("could not open input file"); break;
1361 case -2: error = tr("reading header failed"); break;
1362 case -3: error = tr("reading firmware failed"); break;
1363 case -4: error = tr("can't open bootloader file"); break;
1364 case -5: error = tr("reading bootloader file failed"); break;
1365 case -6: error = tr("can't open output file"); break;
1366 case -7: error = tr("writing output file failed"); break;
1368 m_dp->addItem(tr("Error in patching: %1").arg(error), LOGERROR);
1370 firmwareBin.remove();
1371 newBin.remove();
1372 newHex.remove();
1373 emit done(true);
1374 return;
1376 // iriver_encode
1377 if((result = iriver_encode(newBinName, newHexName, FALSE)) < 0)
1379 QString error;
1380 switch(result) {
1381 case -1: error = tr("Can't open input file"); break;
1382 case -2: error = tr("Can't open output file"); break;
1383 case -3: error = tr("invalid file: header length wrong"); break;
1384 case -4: error = tr("invalid file: unrecognized header"); break;
1385 case -5: error = tr("invalid file: \"length\" field wrong"); break;
1386 case -6: error = tr("invalid file: \"length2\" field wrong"); break;
1387 case -7: error = tr("invalid file: internal checksum error"); break;
1388 case -8: error = tr("invalid file: \"length3\" field wrong"); break;
1389 default: error = tr("unknown"); break;
1391 m_dp->addItem(tr("Error in scramble: %1").arg(error), LOGERROR);
1393 firmwareBin.remove();
1394 newBin.remove();
1395 newHex.remove();
1396 emit done(true);
1397 return;
1400 /* now md5sum it */
1401 if (!FileMD5(newHexName, md5sum_str))
1403 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1404 firmwareBin.remove();
1405 newBin.remove();
1406 newHex.remove();
1407 emit done(true);
1408 return;
1410 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1411 /* delete temp files */
1412 firmwareBin.remove();
1413 newBin.remove();
1416 // Load patched Firmware to player
1417 QString dest;
1418 if(series == 100)
1419 dest = m_mountpoint + "/ihp_100.hex";
1420 else if(series == 120)
1421 dest = m_mountpoint + "/ihp_120.hex";
1422 else if(series == 300)
1423 dest = m_mountpoint + "/H300.hex";
1425 // copy file
1426 QFile destfile(dest);
1427 if(destfile.exists()) destfile.remove();
1428 if(!newHex.copy(dest))
1430 m_dp->addItem(tr("Could not copy: %1 to %2")
1431 .arg(newHexName,dest),LOGERROR);
1432 emit done(true);
1433 return;
1436 downloadFile.remove();
1437 newHex.remove();
1439 createInstallLog();
1441 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1442 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1443 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1444 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1445 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1446 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1447 m_dp->abort();
1449 emit done(false); // success