rbutil: make a backup of the OF in gigabeat and h10 bootloader installation. (in...
[Rockbox.git] / rbutil / rbutilqt / installbootloader.cpp
blob61655fd1f3154e14d6c259f63e958234277c6c67
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"
23 BootloaderInstaller::BootloaderInstaller(QObject* parent): QObject(parent)
28 void BootloaderInstaller::install(ProgressloggerInterface* dp)
30 m_dp = dp;
31 m_install = true;
32 m_dp->addItem(tr("Starting bootloader installation"),LOGINFO);
33 connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool)));
35 if(m_bootloadermethod == "gigabeatf")
37 // connect internal signal
38 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
39 connect(this,SIGNAL(finish()),this,SLOT(gigabeatFinish()));
41 else if(m_bootloadermethod == "iaudio")
43 // connect internal signal
44 connect(this,SIGNAL(prepare()),this,SLOT(iaudioPrepare()));
45 connect(this,SIGNAL(finish()),this,SLOT(iaudioFinish()));
47 else if(m_bootloadermethod == "h10")
49 // connect internal signal
50 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
51 connect(this,SIGNAL(finish()),this,SLOT(h10Finish()));
53 else if(m_bootloadermethod == "ipodpatcher")
55 // connect internal signal
56 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
57 connect(this,SIGNAL(finish()),this,SLOT(ipodFinish()));
59 else if(m_bootloadermethod == "sansapatcher")
61 // connect internal signal
62 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
63 connect(this,SIGNAL(finish()),this,SLOT(sansaFinish()));
65 else if(m_bootloadermethod == "fwpatcher")
67 // connect internal signal
68 connect(this,SIGNAL(prepare()),this,SLOT(iriverPrepare()));
69 connect(this,SIGNAL(finish()),this,SLOT(iriverFinish()));
71 else
73 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
74 emit done(true);
75 return;
78 emit prepare();
81 void BootloaderInstaller::uninstall(ProgressloggerInterface* dp)
83 m_dp = dp;
84 m_install = false;
85 m_dp->addItem(tr("Starting bootloader uninstallation"),LOGINFO);
86 connect(this, SIGNAL(done(bool)), this, SLOT(installEnded(bool)));
88 if(m_bootloadermethod == "gigabeatf")
90 // connect internal signal
91 connect(this,SIGNAL(prepare()),this,SLOT(gigabeatPrepare()));
93 else if(m_bootloadermethod == "iaudio")
95 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
96 emit done(true);
97 return;
99 else if(m_bootloadermethod == "iaudio")
101 // connect internal signal
102 connect(this,SIGNAL(prepare()),this,SLOT(h10Prepare()));
104 else if(m_bootloadermethod == "ipodpatcher")
106 // connect internal signal
107 connect(this,SIGNAL(prepare()),this,SLOT(ipodPrepare()));
109 else if(m_bootloadermethod == "sansapatcher")
111 // connect internal signal
112 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
114 else if(m_bootloadermethod == "fwpatcher")
116 m_dp->addItem(tr("No uninstallation possible"),LOGWARNING);
117 emit done(true);
118 return;
120 else
122 m_dp->addItem(tr("unsupported install Method"),LOGERROR);
123 emit done(true);
124 return;
127 emit prepare();
130 void BootloaderInstaller::downloadRequestFinished(int id, bool error)
132 qDebug() << "BootloaderInstall::downloadRequestFinished" << id << error;
133 qDebug() << "error:" << getter->errorString();
135 downloadDone(error);
138 void BootloaderInstaller::downloadDone(bool error)
140 qDebug() << "Install::downloadDone, error:" << error;
142 // update progress bar
144 int max = m_dp->getProgressMax();
145 if(max == 0) {
146 max = 100;
147 m_dp->setProgressMax(max);
149 m_dp->setProgressValue(max);
150 if(getter->httpResponse() != 200) {
151 m_dp->addItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR);
152 m_dp->abort();
153 emit done(true);
154 return;
156 if(error) {
157 m_dp->addItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR);
158 m_dp->abort();
159 emit done(true);
160 return;
162 else m_dp->addItem(tr("Download finished."),LOGOK);
164 emit finish();
168 void BootloaderInstaller::updateDataReadProgress(int read, int total)
170 m_dp->setProgressMax(total);
171 m_dp->setProgressValue(read);
172 qDebug() << "progress:" << read << "/" << total;
176 void BootloaderInstaller::installEnded(bool error)
178 (void) error;
179 m_dp->abort();
182 bool BootloaderInstaller::downloadInfo()
184 // try to get the current build information
185 infodownloader = new HttpGet(this);
187 connect(infodownloader, SIGNAL(done(bool)), this, SLOT(infoDownloadDone(bool)));
188 connect(infodownloader, SIGNAL(requestFinished(int, bool)), this, SLOT(infoRequestFinished(int, bool)));
190 infodownloader->setProxy(m_proxy);
192 qDebug() << "downloading bootloader info";
193 infodownloader->setFile(&bootloaderInfo);
194 infodownloader->getFile(QUrl(m_bootloaderinfoUrl));
196 // block until its downloaded
197 qDebug() << "Waiting for Download finished";
198 infoDownloaded=false;
199 infoError = false;
200 while(!infoDownloaded )
201 QCoreApplication::processEvents();
202 return !infoError;
205 void BootloaderInstaller::infoDownloadDone(bool error)
207 if(error)
209 qDebug() << "network error:" << infodownloader->error();
210 return;
212 qDebug() << "network status:" << infodownloader->error();
214 infoDownloaded = true;
217 void BootloaderInstaller::infoRequestFinished(int id, bool error)
220 if(error)
222 QString errorString;
223 errorString = tr("Network error: %1. Please check your network and proxy settings.")
224 .arg(infodownloader->errorString());
225 #ifndef CONSOLE
226 if(error) QMessageBox::about(NULL, "Network Error", errorString);
227 #endif
228 qDebug() << "downloadDone:" << id << error;
230 infoError = true;
231 infoDownloaded = true;
233 qDebug() << "infoRequestFinished:" << id << error;
237 void BootloaderInstaller::createInstallLog()
239 m_dp->addItem(tr("Creating installation log"),LOGINFO);
240 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
242 bootloaderInfo.open();
243 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
244 bootloaderInfo.close();
245 info.beginGroup(m_device);
247 installlog.beginGroup("Bootloader");
248 installlog.setValue("md5sum",info.value("md5sum").toString());
249 installlog.endGroup();
250 installlog.sync();
253 void BootloaderInstaller::removeInstallLog()
255 m_dp->addItem(tr("Editing installation log"),LOGINFO);
256 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
257 installlog.beginGroup("Bootloader");
258 installlog.remove("md5sum");
259 installlog.endGroup();
260 installlog.sync();
264 bool BootloaderInstaller::uptodate()
266 QString installedMd5;
267 QString serverMd5;
269 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
270 installlog.beginGroup("Bootloader");
271 installedMd5 = installlog.value("md5sum").toString();
272 installlog.endGroup();
274 bootloaderInfo.open();
275 QSettings info(bootloaderInfo.fileName(), QSettings::IniFormat, this);
276 bootloaderInfo.close();
277 info.beginGroup(m_device);
278 serverMd5 = info.value("md5sum").toString();
279 info.endGroup();
281 if(installedMd5 != serverMd5)
282 return false;
283 else
284 return true;
287 /**************************************************
288 *** gigabeat secific code
289 ***************************************************/
291 void BootloaderInstaller::gigabeatPrepare()
293 if(m_install) // Installation
295 QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername;
297 m_dp->addItem(tr("Downloading file %1.%2")
298 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
300 // temporary file needs to be opened to get the filename
301 downloadFile.open();
302 m_tempfilename = downloadFile.fileName();
303 downloadFile.close();
304 // get the real file.
305 getter = new HttpGet(this);
306 getter->setProxy(m_proxy);
307 getter->setFile(&downloadFile);
308 getter->getFile(QUrl(url));
309 // connect signals from HttpGet
310 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
311 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
312 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
314 else //UnInstallation
316 QString firmware = m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT";
317 QString firmwareOrig = firmware.append(".ORIG");
319 QFileInfo firmwareOrigFI(firmwareOrig);
321 // check if original firmware exists
322 if(!firmwareOrigFI.exists())
324 m_dp->addItem(tr("Could not find the Original Firmware at: %1")
325 .arg(firmwareOrig),LOGERROR);
326 emit done(true);
327 return;
330 QFile firmwareFile(firmware);
331 QFile firmwareOrigFile(firmwareOrig);
333 //remove modified firmware
334 if(!firmwareFile.remove())
336 m_dp->addItem(tr("Could not remove the Firmware at: %1")
337 .arg(firmware),LOGERROR);
338 emit done(true);
339 return;
342 //copy original firmware
343 if(!firmwareOrigFile.copy(firmware))
345 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
346 .arg(firmwareOrig,firmware),LOGERROR);
347 emit done(true);
348 return;
351 removeInstallLog();
353 emit done(false); //success
358 void BootloaderInstaller::gigabeatFinish()
360 // this step is only need for installation, so no code for uninstall here
362 m_dp->addItem(tr("Finishing bootloader install"),LOGINFO);
364 QString firmware = m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername;
366 QFileInfo firmwareFI(firmware);
368 // check if firmware exists
369 if(!firmwareFI.exists())
371 m_dp->addItem(tr("Could not find the Firmware at: %1")
372 .arg(firmware),LOGERROR);
373 emit done(true);
374 return;
377 QString firmwareOrig = firmware;
378 firmwareOrig.append(".ORIG");
379 QFileInfo firmwareOrigFI(firmwareOrig);
381 // rename and backup the firmware, if there is no original firmware there
382 if(!firmwareOrigFI.exists())
384 QFile firmwareFile(firmware);
385 //backup
386 QDir::home().mkdir("Gigabeat Original Firmware Backup");
387 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Gigabeat Original Firmware Backup/") + m_bootloadername);
389 //rename
390 if(!firmwareFile.rename(firmwareOrig))
392 m_dp->addItem(tr("Could not rename: %1 to %2")
393 .arg(firmware,firmwareOrig),LOGERROR);
394 emit done(true);
395 return;
398 else // or remove the normal firmware, if the original is there
400 QFile firmwareFile(firmware);
401 firmwareFile.remove();
404 //copy the firmware
405 if(!downloadFile.copy(firmware))
407 m_dp->addItem(tr("Could not copy: %1 to %2")
408 .arg(m_tempfilename,firmware),LOGERROR);
409 emit done(true);
410 return;
413 downloadFile.remove();
415 createInstallLog();
417 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
418 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
419 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
420 m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO);
421 m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO);
422 m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO);
423 m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO);
426 m_dp->abort();
428 emit done(false); // success
432 /**************************************************
433 *** iaudio secific code
434 ***************************************************/
435 void BootloaderInstaller::iaudioPrepare()
438 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
440 m_dp->addItem(tr("Downloading file %1.%2")
441 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
443 // temporary file needs to be opened to get the filename
444 downloadFile.open();
445 m_tempfilename = downloadFile.fileName();
446 downloadFile.close();
447 // get the real file.
448 getter = new HttpGet(this);
449 getter->setProxy(m_proxy);
450 getter->setFile(&downloadFile);
451 getter->getFile(QUrl(url));
452 // connect signals from HttpGet
453 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
454 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
455 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
458 void BootloaderInstaller::iaudioFinish()
460 QString firmware = m_mountpoint + "/FIRMWARE/" + m_bootloadername;
462 //copy the firmware
463 if(!downloadFile.copy(firmware))
465 m_dp->addItem(tr("Could not copy: %1 to %2")
466 .arg(m_tempfilename,firmware),LOGERROR);
467 emit done(true);
468 return;
471 downloadFile.remove();
473 createInstallLog();
475 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
476 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
477 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
478 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
479 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
481 m_dp->abort();
483 emit done(false); // success
488 /**************************************************
489 *** h10 secific code
490 ***************************************************/
491 void BootloaderInstaller::h10Prepare()
493 if(m_install) // Installation
495 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
497 m_dp->addItem(tr("Downloading file %1.%2")
498 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
500 // temporary file needs to be opened to get the filename
501 downloadFile.open();
502 m_tempfilename = downloadFile.fileName();
503 downloadFile.close();
504 // get the real file.
505 getter = new HttpGet(this);
506 getter->setProxy(m_proxy);
507 getter->setFile(&downloadFile);
508 getter->getFile(QUrl(url));
509 // connect signals from HttpGet
510 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
511 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
512 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
514 else // Uninstallation
517 QString firmwarename = m_bootloadername.section('/', -1);
519 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
520 QString firmwareOrig = m_mountpoint + "/SYSTEM/OF.mi4";
522 QFileInfo firmwareFI(firmware);
523 if(!firmwareFI.exists()) //Firmware dosent exists on player
525 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
526 firmwareFI.setFile(firmware);
527 if(!firmwareFI.exists()) //Firmware dosent exists on player
529 m_dp->addItem(tr("Firmware does not exist: %1")
530 .arg(firmware),LOGERROR);
531 emit done(true);
532 return;
536 QFileInfo firmwareOrigFI(firmwareOrig);
537 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
539 m_dp->addItem(tr("Original Firmware does not exist: %1")
540 .arg(firmwareOrig),LOGERROR);
541 emit done(true);
542 return;
545 QFile firmwareFile(firmware);
546 QFile firmwareOrigFile(firmwareOrig);
548 //remove modified firmware
549 if(!firmwareFile.remove())
551 m_dp->addItem(tr("Could not remove the Firmware at: %1")
552 .arg(firmware),LOGERROR);
553 emit done(true);
554 return;
557 //copy original firmware
558 if(!firmwareOrigFile.copy(firmware))
560 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
561 .arg(firmwareOrig,firmware),LOGERROR);
562 emit done(true);
563 return;
566 removeInstallLog();
568 emit done(false); //success
573 void BootloaderInstaller::h10Finish()
575 QString firmwarename = m_bootloadername.section('/', -1);
577 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
578 QString firmwareOrig = m_mountpoint + "/SYSTEM/OF.mi4";
580 QFileInfo firmwareFI(firmware);
582 if(!firmwareFI.exists()) //Firmware dosent exists on player
584 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
585 firmwareFI.setFile(firmware);
586 if(!firmwareFI.exists()) //Firmware dosent exists on player
588 m_dp->addItem(tr("Firmware does not exist: %1")
589 .arg(firmware),LOGERROR);
590 emit done(true);
591 return;
595 QFileInfo firmwareOrigFI(firmwareOrig);
597 if(!firmwareOrigFI.exists())
599 QFile firmwareFile(firmware);
601 //backup
602 QDir::home().mkdir("Iriver H10 Original Firmware Backup");
603 firmwareFile.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Iriver H10 Original Firmware Backup/") + m_bootloadername);
605 //rename
606 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
608 m_dp->addItem(tr("Could not rename: %1 to %2")
609 .arg(firmware,firmwareOrig),LOGERROR);
610 emit done(true);
611 return;
614 else //there is already a original firmware
616 QFile firmwareFile(firmware);
617 firmwareFile.remove();
619 //copy the firmware
620 if(!downloadFile.copy(firmware))
622 m_dp->addItem(tr("Could not copy: %1 to %2")
623 .arg(m_tempfilename,firmware),LOGERROR);
624 emit done(true);
625 return;
628 downloadFile.remove();
630 createInstallLog();
632 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
633 m_dp->abort();
635 emit done(false); // success
639 /**************************************************
640 *** ipod secific code
641 ***************************************************/
642 int verbose =0;
643 // reserves memory for ipodpatcher
644 bool initIpodpatcher()
646 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
647 else return false;
650 void BootloaderInstaller::ipodPrepare()
652 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
653 struct ipod_t ipod;
655 int n = ipod_scan(&ipod);
656 if (n == 0)
658 m_dp->addItem(tr("No Ipods found"),LOGERROR);
659 emit done(true);
660 return;
662 if (n > 1)
664 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
665 emit done(true);
668 if(m_install) // Installation
671 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
673 m_dp->addItem(tr("Downloading file %1.%2")
674 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
676 // temporary file needs to be opened to get the filename
677 downloadFile.open();
678 m_tempfilename = downloadFile.fileName();
679 downloadFile.close();
680 // get the real file.
681 getter = new HttpGet(this);
682 getter->setProxy(m_proxy);
683 getter->setFile(&downloadFile);
684 getter->getFile(QUrl(url));
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 else // Uninstallation
692 if (ipod_open(&ipod, 0) < 0)
694 m_dp->addItem(tr("could not open ipod"),LOGERROR);
695 emit done(true);
696 return;
699 if (read_partinfo(&ipod,0) < 0)
701 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
702 emit done(true);
703 return;
706 if (ipod.pinfo[0].start==0)
708 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
710 int i;
711 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
712 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
713 for ( i = 0; i < 4; i++ )
715 if (ipod.pinfo[i].start != 0)
717 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
718 i).arg(
719 ipod.pinfo[i].start).arg(
720 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
721 ipod.pinfo[i].size/sectors_per_MB).arg(
722 get_parttype(ipod.pinfo[i].type)).arg(
723 ipod.pinfo[i].type),LOGINFO);
726 emit done(true);
727 return;
730 read_directory(&ipod);
732 if (ipod.nimages <= 0)
734 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
735 emit done(true);
736 return;
738 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
740 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
741 ipod.ipod_directory[0].vers),LOGERROR);
742 emit done(true);
743 return;
746 if (ipod.macpod)
748 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
749 "this. Convert it to WinPod\n"
750 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
751 LOGWARNING);
752 emit done(true);
753 return;
756 if (ipod_reopen_rw(&ipod) < 0)
758 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
759 emit done(true);
760 return;
763 if (ipod.ipod_directory[0].entryOffset==0) {
764 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
765 emit done(true);
766 return;
769 if (delete_bootloader(&ipod)==0)
771 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
772 removeInstallLog();
773 emit done(false);
774 ipod_close(&ipod);
775 return;
777 else
779 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
780 emit done(true);
781 ipod_close(&ipod);
782 return;
787 void BootloaderInstaller::ipodFinish()
789 struct ipod_t ipod;
790 ipod_scan(&ipod);
792 if (ipod_open(&ipod, 0) < 0)
794 m_dp->addItem(tr("could not open ipod"),LOGERROR);
795 emit done(true);
796 return;
799 if (read_partinfo(&ipod,0) < 0)
801 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
802 emit done(true);
803 return;
806 if (ipod.pinfo[0].start==0)
808 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
810 int i;
811 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
813 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
815 for ( i = 0; i < 4; i++ )
817 if (ipod.pinfo[i].start != 0)
819 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
820 i).arg(
821 ipod.pinfo[i].start).arg(
822 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
823 ipod.pinfo[i].size/sectors_per_MB).arg(
824 get_parttype(ipod.pinfo[i].type)).arg(
825 ipod.pinfo[i].type),LOGWARNING);
828 emit done(true);
829 return;
832 read_directory(&ipod);
834 if (ipod.nimages <= 0)
836 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
837 emit done(true);
838 return;
840 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
842 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
843 ipod.ipod_directory[0].vers),LOGERROR);
844 emit done(true);
845 return;
848 if (ipod.macpod)
850 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
851 "this. Convert it to WinPod\n"
852 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
853 LOGWARNING);
854 emit done(true);
855 return;
858 if (ipod_reopen_rw(&ipod) < 0)
860 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
861 emit done(true);
862 return;
865 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
867 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
868 createInstallLog();
869 emit done(false);
870 ipod_close(&ipod);
871 return;
873 else
875 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
876 ipod_close(&ipod);
877 emit done(true);
878 return;
882 /**************************************************
883 *** sansa secific code
884 ***************************************************/
885 // reserves memory for sansapatcher
886 bool initSansapatcher()
888 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
889 else return false;
893 void BootloaderInstaller::sansaPrepare()
895 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
896 struct sansa_t sansa;
898 int n = sansa_scan(&sansa);
899 if (n == 0)
901 m_dp->addItem(tr("No Sansa found"),LOGERROR);
902 emit done(true);
903 return;
905 if (n > 1)
907 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
908 emit done(true);
911 if(m_install) // Installation
913 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
914 + QString(sansa.targetname) + "/" + m_bootloadername;
916 m_dp->addItem(tr("Downloading file %1.%2")
917 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
919 // temporary file needs to be opened to get the filename
920 downloadFile.open();
921 m_tempfilename = downloadFile.fileName();
922 downloadFile.close();
923 // get the real file.
924 getter = new HttpGet(this);
925 getter->setProxy(m_proxy);
926 getter->setFile(&downloadFile);
927 getter->getFile(QUrl(url));
928 // connect signals from HttpGet
929 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
930 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
931 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
933 else // Uninstallation
936 if (sansa_open(&sansa, 0) < 0)
938 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
939 emit done(true);
940 return;
943 if (sansa_read_partinfo(&sansa,0) < 0)
945 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
946 emit done(true);
947 return;
950 int i = is_sansa(&sansa);
951 if (i < 0) {
952 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
953 emit done(true);
954 return;
957 if (sansa.hasoldbootloader)
959 m_dp->addItem(tr("********************************************\n"
960 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
961 "You must reinstall the original Sansa firmware before running\n"
962 "sansapatcher for the first time.\n"
963 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
964 "*********************************************\n"),LOGERROR);
965 emit done(true);
966 return;
970 if (sansa_reopen_rw(&sansa) < 0)
972 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
973 emit done(true);
974 return;
977 if (sansa_delete_bootloader(&sansa)==0)
979 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
980 removeInstallLog();
981 emit done(false);
982 sansa_close(&sansa);
983 return;
985 else
987 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
988 emit done(true);
989 sansa_close(&sansa);
990 return;
995 void BootloaderInstaller::sansaFinish()
997 struct sansa_t sansa;
998 sansa_scan(&sansa);
1000 if (sansa_open(&sansa, 0) < 0)
1002 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
1003 emit done(true);
1004 return;
1007 if (sansa_read_partinfo(&sansa,0) < 0)
1009 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
1010 emit done(true);
1011 return;
1015 int i = is_sansa(&sansa);
1016 if (i < 0) {
1018 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1019 emit done(true);
1020 return;
1023 if (sansa.hasoldbootloader)
1025 m_dp->addItem(tr("********************************************\n"
1026 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1027 "You must reinstall the original Sansa firmware before running\n"
1028 "sansapatcher for the first time.\n"
1029 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
1030 "*********************************************\n"),LOGERROR);
1031 emit done(true);
1032 return;
1035 if (sansa_reopen_rw(&sansa) < 0)
1037 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1038 emit done(true);
1039 return;
1042 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1044 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1045 createInstallLog();
1046 emit done(false);
1047 sansa_close(&sansa);
1048 return;
1050 else
1052 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1053 sansa_close(&sansa);
1054 emit done(true);
1055 return;
1060 /**************************************************
1061 *** iriver /fwpatcher secific code
1062 ***************************************************/
1064 void BootloaderInstaller::iriverPrepare()
1066 char md5sum_str[32];
1067 if (!FileMD5(m_origfirmware, md5sum_str)) {
1068 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
1069 emit done(true);
1070 return;
1073 /* Check firmware against md5sums in h120sums and h100sums */
1074 series = 0;
1075 table_entry = intable(md5sum_str, &h120pairs[0],
1076 sizeof(h120pairs)/sizeof(struct sumpairs));
1077 if (table_entry >= 0) {
1078 series = 120;
1080 else
1082 table_entry = intable(md5sum_str, &h100pairs[0],
1083 sizeof(h100pairs)/sizeof(struct sumpairs));
1084 if (table_entry >= 0)
1086 series = 100;
1088 else
1090 table_entry = intable(md5sum_str, &h300pairs[0],
1091 sizeof(h300pairs)/sizeof(struct sumpairs));
1092 if (table_entry >= 0)
1093 series = 300;
1096 if (series == 0)
1098 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1099 emit done(true);
1100 return;
1103 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1105 m_dp->addItem(tr("Downloading file %1.%2")
1106 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1108 // temporary file needs to be opened to get the filename
1109 downloadFile.open();
1110 m_tempfilename = downloadFile.fileName();
1111 downloadFile.close();
1112 // get the real file.
1113 getter = new HttpGet(this);
1114 getter->setProxy(m_proxy);
1115 getter->setFile(&downloadFile);
1116 getter->getFile(QUrl(url));
1117 // connect signals from HttpGet
1118 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1119 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
1120 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1123 void BootloaderInstaller::iriverFinish()
1125 // Patch firmware
1126 char md5sum_str[32];
1127 struct sumpairs *sums = 0;
1128 int origin = 0;
1130 /* get pointer to the correct bootloader.bin */
1131 switch(series) {
1132 case 100:
1133 sums = &h100pairs[0];
1134 origin = 0x1f0000;
1135 break;
1136 case 120:
1137 sums = &h120pairs[0];
1138 origin = 0x1f0000;
1139 break;
1140 case 300:
1141 sums = &h300pairs[0];
1142 origin = 0x3f0000;
1143 break;
1146 // temporary files needs to be opened to get the filename
1147 QTemporaryFile firmwareBin, newBin, newHex;
1148 firmwareBin.open();
1149 newBin.open();
1150 newHex.open();
1151 QString firmwareBinName = firmwareBin.fileName();
1152 QString newBinName = newBin.fileName();
1153 QString newHexName = newHex.fileName();
1154 firmwareBin.close();
1155 newBin.close();
1156 newHex.close();
1158 // iriver decode
1159 if (iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE,m_dp) == -1)
1161 m_dp->addItem(tr("Error in descramble"),LOGERROR);
1162 firmwareBin.remove();
1163 newBin.remove();
1164 newHex.remove();
1165 emit done(true);
1166 return;
1168 // mkboot
1169 if (!mkboot(firmwareBinName, newBinName, m_tempfilename, origin,m_dp))
1171 m_dp->addItem(tr("Error in patching"),LOGERROR);
1172 firmwareBin.remove();
1173 newBin.remove();
1174 newHex.remove();
1175 emit done(true);
1176 return;
1178 // iriver_encode
1179 if (iriver_encode(newBinName, newHexName, FALSE,m_dp) == -1)
1181 m_dp->addItem(tr("Error in scramble"),LOGERROR);
1182 firmwareBin.remove();
1183 newBin.remove();
1184 newHex.remove();
1185 emit done(true);
1186 return;
1189 /* now md5sum it */
1190 if (!FileMD5(newHexName, md5sum_str))
1192 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1193 firmwareBin.remove();
1194 newBin.remove();
1195 newHex.remove();
1196 emit done(true);
1197 return;
1199 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1200 /* delete temp files */
1201 firmwareBin.remove();
1202 newBin.remove();
1205 // Load patched Firmware to player
1206 QString dest;
1207 if(series == 100)
1208 dest = m_mountpoint + "/ihp_100.hex";
1209 else if(series == 120)
1210 dest = m_mountpoint + "/ihp_120.hex";
1211 else if(series == 300)
1212 dest = m_mountpoint + "/H300.hex";
1214 // copy file
1215 QFile destfile(dest);
1216 if(destfile.exists()) destfile.remove();
1217 if(!newHex.copy(dest))
1219 m_dp->addItem(tr("Could not copy: %1 to %2")
1220 .arg(newHexName,dest),LOGERROR);
1221 emit done(true);
1222 return;
1225 downloadFile.remove();
1226 newHex.remove();
1228 createInstallLog();
1230 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1231 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1232 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1233 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1234 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1235 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1236 m_dp->abort();
1238 emit done(false); // success