Replaced TAB characters by spaces in sansapatcher
[kugel-rb.git] / rbutil / rbutilqt / installbootloader.cpp
blob4e44284fcca8a2b601694aed022e6efd08a6ade4
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 QDir dir(m_mountpoint + "/FIRMWARE/");
473 if(!dir.exists())
475 dir.mkpath(m_mountpoint + "/FIRMWARE/");
477 firmware = resolvePathCase(m_mountpoint + "/FIRMWARE/") + "/" + m_bootloadername;
479 //copy the firmware
480 if(!downloadFile.copy(firmware))
482 m_dp->addItem(tr("Could not copy: %1 to %2")
483 .arg(m_tempfilename,firmware),LOGERROR);
484 emit done(true);
485 return;
488 downloadFile.remove();
490 createInstallLog();
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);
498 m_dp->abort();
500 emit done(false); // success
505 /**************************************************
506 *** h10 secific code
507 ***************************************************/
508 void BootloaderInstaller::h10Prepare()
510 if(m_install) // Installation
512 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
514 m_dp->addItem(tr("Downloading file %1.%2")
515 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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()));
529 getter->getFile(QUrl(url));
531 else // Uninstallation
534 QString firmwarename = m_bootloadername.section('/', -1);
536 QString firmware;
537 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
538 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
540 QFileInfo firmwareFI(firmware);
541 if(!firmwareFI.exists()) //Firmware dosent exists on player
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
548 m_dp->addItem(tr("Firmware does not exist: %1")
549 .arg(firmware),LOGERROR);
550 emit done(true);
551 return;
555 QFileInfo firmwareOrigFI(firmwareOrig);
556 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
558 m_dp->addItem(tr("Original Firmware does not exist: %1")
559 .arg(firmwareOrig),LOGERROR);
560 emit done(true);
561 return;
564 QFile firmwareFile(firmware);
565 QFile firmwareOrigFile(firmwareOrig);
567 //remove modified firmware
568 if(!firmwareFile.remove())
570 m_dp->addItem(tr("Could not remove the Firmware at: %1")
571 .arg(firmware),LOGERROR);
572 emit done(true);
573 return;
576 // rename original firmware back
577 if(!firmwareOrigFile.rename(firmware))
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;
585 removeInstallLog();
587 emit done(false); //success
592 void BootloaderInstaller::h10Finish()
594 QString firmwarename = m_bootloadername.section('/', -1);
596 QString firmware;
597 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
598 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM") + "/OF.mi4";
600 QFileInfo firmwareFI(firmware);
602 if(!firmwareFI.exists()) //Firmware dosent exists on player
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
609 m_dp->addItem(tr("Firmware does not exist: %1")
610 .arg(firmware),LOGERROR);
611 emit done(true);
612 return;
616 QFileInfo firmwareOrigFI(firmwareOrig);
618 if(!firmwareOrigFI.exists())
620 QFile firmwareFile(firmware);
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();
627 //rename
628 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
630 m_dp->addItem(tr("Could not rename: %1 to %2")
631 .arg(firmware,firmwareOrig),LOGERROR);
632 emit done(true);
633 return;
636 else //there is already a original firmware
638 QFile firmwareFile(firmware);
639 firmwareFile.remove();
641 //copy the firmware
642 if(!downloadFile.copy(firmware))
644 m_dp->addItem(tr("Could not copy: %1 to %2")
645 .arg(m_tempfilename,firmware),LOGERROR);
646 emit done(true);
647 return;
650 downloadFile.remove();
652 createInstallLog();
654 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
655 m_dp->abort();
657 emit done(false); // success
663 /**************************************************
664 *** mrobe100 secific code
665 ***************************************************/
666 void BootloaderInstaller::mrobe100Prepare()
668 if(m_install) // Installation
670 QString url = m_bootloaderUrlBase + "/olympus/mrobe100/" + m_bootloadername;
672 m_dp->addItem(tr("Downloading file %1.%2")
673 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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);
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()));
688 getter->getFile(QUrl(url));
690 else // Uninstallation
693 QString firmwarename = m_bootloadername;
695 QString firmware;
696 firmware = resolvePathCase(m_mountpoint + "/SYSTEM/" + firmwarename);
697 QString firmwareOrig = resolvePathCase(m_mountpoint + "/SYSTEM/OF.mi4");
699 QFileInfo firmwareFI(firmware);
700 if(!firmwareFI.exists()) //Firmware dosent exists on player
702 m_dp->addItem(tr("Firmware does not exist: %1")
703 .arg(firmware),LOGERROR);
704 emit done(true);
705 return;
708 QFileInfo firmwareOrigFI(firmwareOrig);
709 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
711 m_dp->addItem(tr("Original Firmware does not exist: %1")
712 .arg(firmwareOrig),LOGERROR);
713 emit done(true);
714 return;
717 QFile firmwareFile(firmware);
718 QFile firmwareOrigFile(firmwareOrig);
720 //remove modified firmware
721 if(!firmwareFile.remove())
723 m_dp->addItem(tr("Could not remove the Firmware at: %1")
724 .arg(firmware),LOGERROR);
725 emit done(true);
726 return;
729 // move original firmware back
730 if(!firmwareOrigFile.rename(firmware))
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;
738 removeInstallLog();
740 emit done(false); //success
745 void BootloaderInstaller::mrobe100Finish()
747 QString firmwarename = m_bootloadername;
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";
754 QFileInfo firmwareFI(firmware);
756 if(!firmwareFI.exists()) //Firmware dosent exists on player
758 m_dp->addItem(tr("Firmware does not exist: %1")
759 .arg(firmware),LOGERROR);
760 emit done(true);
761 return;
764 QFileInfo firmwareOrigFI(firmwareOrig);
766 if(!firmwareOrigFI.exists())
768 QFile firmwareFile(firmware);
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
777 m_dp->addItem(tr("Could not rename: %1 to %2")
778 .arg(firmware,firmwareOrig),LOGERROR);
779 emit done(true);
780 return;
783 else //there is already a original firmware
785 QFile firmwareFile(firmware);
786 firmwareFile.remove();
788 //copy the firmware
789 if(!downloadFile.copy(firmware))
791 m_dp->addItem(tr("Could not copy: %1 to %2")
792 .arg(m_tempfilename,firmware),LOGERROR);
793 emit done(true);
794 return;
797 downloadFile.remove();
799 createInstallLog();
801 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
802 m_dp->abort();
804 emit done(false); // success
808 /**************************************************
809 *** ipod secific code
810 ***************************************************/
811 int verbose =0;
812 // reserves memory for ipodpatcher
813 bool initIpodpatcher()
815 if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) return true;
816 else return false;
819 void BootloaderInstaller::ipodPrepare()
821 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
822 struct ipod_t ipod;
824 int n = ipod_scan(&ipod);
825 if (n == 0)
827 m_dp->addItem(tr("No Ipods found"),LOGERROR);
828 emit done(true);
829 return;
831 if (n > 1)
833 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
834 emit done(true);
837 if(m_install) // Installation
840 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
842 m_dp->addItem(tr("Downloading file %1.%2")
843 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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);
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()));
858 getter->getFile(QUrl(url));
860 else // Uninstallation
862 if (ipod_open(&ipod, 0) < 0)
864 m_dp->addItem(tr("could not open ipod"),LOGERROR);
865 emit done(true);
866 return;
869 if (read_partinfo(&ipod,0) < 0)
871 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
872 emit done(true);
873 return;
876 if (ipod.pinfo[0].start==0)
878 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
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++ )
885 if (ipod.pinfo[i].start != 0)
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);
896 emit done(true);
897 return;
900 read_directory(&ipod);
902 if (ipod.nimages <= 0)
904 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
905 emit done(true);
906 return;
908 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
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;
916 if (ipod.macpod)
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;
926 if (ipod_reopen_rw(&ipod) < 0)
928 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
929 emit done(true);
930 return;
933 if (ipod.ipod_directory[0].entryOffset==0) {
934 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
935 emit done(true);
936 return;
939 if (delete_bootloader(&ipod)==0)
941 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
942 removeInstallLog();
943 emit done(false);
944 ipod_close(&ipod);
945 return;
947 else
949 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
950 emit done(true);
951 ipod_close(&ipod);
952 return;
957 void BootloaderInstaller::ipodFinish()
959 struct ipod_t ipod;
960 ipod_scan(&ipod);
962 if (ipod_open(&ipod, 0) < 0)
964 m_dp->addItem(tr("could not open ipod"),LOGERROR);
965 emit done(true);
966 return;
969 if (read_partinfo(&ipod,0) < 0)
971 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
972 emit done(true);
973 return;
976 if (ipod.pinfo[0].start==0)
978 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
980 int i;
981 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
983 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
985 for ( i = 0; i < 4; i++ )
987 if (ipod.pinfo[i].start != 0)
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);
998 emit done(true);
999 return;
1002 read_directory(&ipod);
1004 if (ipod.nimages <= 0)
1006 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
1007 emit done(true);
1008 return;
1010 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
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;
1018 if (ipod.macpod)
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;
1028 if (ipod_reopen_rw(&ipod) < 0)
1030 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
1031 emit done(true);
1032 return;
1035 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
1037 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1038 createInstallLog();
1039 emit done(false);
1040 ipod_close(&ipod);
1041 return;
1043 else
1045 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1046 ipod_close(&ipod);
1047 emit done(true);
1048 return;
1052 /**************************************************
1053 *** sansa secific code
1054 ***************************************************/
1055 // reserves memory for sansapatcher
1056 bool initSansapatcher()
1058 if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) return true;
1059 else return false;
1063 void BootloaderInstaller::sansaPrepare()
1065 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
1066 struct sansa_t sansa;
1068 int n = sansa_scan(&sansa);
1069 if (n == 0)
1071 m_dp->addItem(tr("No Sansa found"),LOGERROR);
1072 emit done(true);
1073 return;
1075 if (n > 1)
1077 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
1078 emit done(true);
1081 if(m_install) // Installation
1083 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
1084 + QString(sansa.targetname) + "/" + m_bootloadername;
1086 m_dp->addItem(tr("Downloading file %1.%2")
1087 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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);
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()));
1102 getter->getFile(QUrl(url));
1104 else // Uninstallation
1107 if (sansa_open(&sansa, 0) < 0)
1109 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1110 emit done(true);
1111 return;
1114 if (sansa_read_partinfo(&sansa,0) < 0)
1116 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1117 emit done(true);
1118 return;
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;
1128 if (sansa.hasoldbootloader)
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;
1141 if (sansa_reopen_rw(&sansa) < 0)
1143 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1144 emit done(true);
1145 return;
1148 if (sansa_delete_bootloader(&sansa)==0)
1150 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
1151 removeInstallLog();
1152 emit done(false);
1153 sansa_close(&sansa);
1154 return;
1156 else
1158 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
1159 emit done(true);
1160 sansa_close(&sansa);
1161 return;
1166 void BootloaderInstaller::sansaFinish()
1168 struct sansa_t sansa;
1169 sansa_scan(&sansa);
1171 if (sansa_open(&sansa, 0) < 0)
1173 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1174 emit done(true);
1175 return;
1178 if (sansa_read_partinfo(&sansa,0) < 0)
1180 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1181 emit done(true);
1182 return;
1186 int i = is_sansa(&sansa);
1187 if (i < 0) {
1189 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1190 emit done(true);
1191 return;
1194 if (sansa.hasoldbootloader)
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;
1206 if (sansa_reopen_rw(&sansa) < 0)
1208 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1209 emit done(true);
1210 return;
1213 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1215 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1216 createInstallLog();
1217 emit done(false);
1218 sansa_close(&sansa);
1219 return;
1221 else
1223 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1224 sansa_close(&sansa);
1225 emit done(true);
1226 return;
1231 /**************************************************
1232 *** iriver /fwpatcher secific code
1233 ***************************************************/
1235 void BootloaderInstaller::iriverPrepare()
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;
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;
1251 else
1253 table_entry = intable(md5sum_str, &h100pairs[0],
1254 sizeof(h100pairs)/sizeof(struct sumpairs));
1255 if (table_entry >= 0)
1257 series = 100;
1259 else
1261 table_entry = intable(md5sum_str, &h300pairs[0],
1262 sizeof(h300pairs)/sizeof(struct sumpairs));
1263 if (table_entry >= 0)
1264 series = 300;
1267 if (series == 0)
1269 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1270 emit done(true);
1271 return;
1274 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1276 m_dp->addItem(tr("Downloading file %1.%2")
1277 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
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);
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()));
1292 getter->getFile(QUrl(url));
1295 void BootloaderInstaller::iriverFinish()
1297 // Patch firmware
1298 char md5sum_str[32];
1299 struct sumpairs *sums = 0;
1300 int origin = 0;
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;
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();
1330 // iriver decode
1331 int result;
1332 if ((result = iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE)) < 0)
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;
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;
1353 // mkboot
1354 if((result = mkboot(firmwareBinName, newBinName, m_tempfilename, origin)) < 0)
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;
1366 m_dp->addItem(tr("Error in patching: %1").arg(error), LOGERROR);
1368 firmwareBin.remove();
1369 newBin.remove();
1370 newHex.remove();
1371 emit done(true);
1372 return;
1374 // iriver_encode
1375 if((result = iriver_encode(newBinName, newHexName, FALSE)) < 0)
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;
1389 m_dp->addItem(tr("Error in scramble: %1").arg(error), LOGERROR);
1391 firmwareBin.remove();
1392 newBin.remove();
1393 newHex.remove();
1394 emit done(true);
1395 return;
1398 /* now md5sum it */
1399 if (!FileMD5(newHexName, md5sum_str))
1401 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1402 firmwareBin.remove();
1403 newBin.remove();
1404 newHex.remove();
1405 emit done(true);
1406 return;
1408 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1409 /* delete temp files */
1410 firmwareBin.remove();
1411 newBin.remove();
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";
1423 // copy file
1424 QFile destfile(dest);
1425 if(destfile.exists()) destfile.remove();
1426 if(!newHex.copy(dest))
1428 m_dp->addItem(tr("Could not copy: %1 to %2")
1429 .arg(newHexName,dest),LOGERROR);
1430 emit done(true);
1431 return;
1434 downloadFile.remove();
1435 newHex.remove();
1437 createInstallLog();
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();
1447 emit done(false); // success