1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
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"
24 BootloaderInstaller::BootloaderInstaller(QObject
* parent
): QObject(parent
)
29 void BootloaderInstaller::install(ProgressloggerInterface
* dp
)
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()));
80 m_dp
->addItem(tr("unsupported install Method"),LOGERROR
);
88 void BootloaderInstaller::uninstall(ProgressloggerInterface
* dp
)
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
);
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
);
139 m_dp
->addItem(tr("unsupported install Method"),LOGERROR
);
147 void BootloaderInstaller::downloadRequestFinished(int id
, bool error
)
149 qDebug() << "BootloaderInstall::downloadRequestFinished" << id
<< error
;
150 qDebug() << "error:" << getter
->errorString();
155 void BootloaderInstaller::downloadDone(bool error
)
157 qDebug() << "Install::downloadDone, error:" << error
;
159 // update progress bar
161 int max
= m_dp
->getProgressMax();
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
);
174 m_dp
->addItem(tr("Download error: %1").arg(getter
->errorString()),LOGERROR
);
179 else m_dp
->addItem(tr("Download finished."),LOGOK
);
186 void BootloaderInstaller::installEnded(bool error
)
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;
208 while(!infoDownloaded
)
209 QCoreApplication::processEvents();
213 void BootloaderInstaller::infoDownloadDone(bool error
)
217 qDebug() << "network error:" << infodownloader
->error();
220 qDebug() << "network status:" << infodownloader
->error();
222 infoDownloaded
= true;
225 void BootloaderInstaller::infoRequestFinished(int id
, bool error
)
231 errorString
= tr("Network error: %1. Please check your network and proxy settings.")
232 .arg(infodownloader
->errorString());
234 if(error
) QMessageBox::about(NULL
, "Network Error", errorString
);
236 qDebug() << "downloadDone:" << id
<< error
;
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();
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();
272 bool BootloaderInstaller::uptodate()
274 QString installedMd5
;
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())
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();
291 if(installedMd5
!= serverMd5
)
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
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
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
);
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
);
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
);
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
);
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
);
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
);
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();
402 if(!firmwareFile
.rename(firmwareOrig
))
404 m_dp
->addItem(tr("Could not rename: %1 to %2")
405 .arg(firmware
,firmwareOrig
),LOGERROR
);
410 else // or remove the normal firmware, if the original is there
412 QFile
firmwareFile(firmware
);
413 firmwareFile
.remove();
417 if(!downloadFile
.copy(firmware
))
419 m_dp
->addItem(tr("Could not copy: %1 to %2")
420 .arg(m_tempfilename
,firmware
),LOGERROR
);
425 downloadFile
.remove();
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
);
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
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()
472 QDir
dir(m_mountpoint
+ "/FIRMWARE/");
475 dir
.mkpath(m_mountpoint
+ "/FIRMWARE/");
477 firmware
= resolvePathCase(m_mountpoint
+ "/FIRMWARE/") + "/" + m_bootloadername
;
480 if(!downloadFile
.copy(firmware
))
482 m_dp
->addItem(tr("Could not copy: %1 to %2")
483 .arg(m_tempfilename
,firmware
),LOGERROR
);
488 downloadFile
.remove();
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
);
500 emit
done(false); // success
505 /**************************************************
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
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);
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
);
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
);
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
);
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
);
587 emit
done(false); //success
592 void BootloaderInstaller::h10Finish()
594 QString firmwarename
= m_bootloadername
.section('/', -1);
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
);
616 QFileInfo
firmwareOrigFI(firmwareOrig
);
618 if(!firmwareOrigFI
.exists())
620 QFile
firmwareFile(firmware
);
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();
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
);
636 else //there is already a original firmware
638 QFile
firmwareFile(firmware
);
639 firmwareFile
.remove();
642 if(!downloadFile
.copy(firmware
))
644 m_dp
->addItem(tr("Could not copy: %1 to %2")
645 .arg(m_tempfilename
,firmware
),LOGERROR
);
650 downloadFile
.remove();
654 m_dp
->addItem(tr("Bootloader install finished successfully."),LOGOK
);
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
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
;
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
);
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
);
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
);
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
);
740 emit
done(false); //success
745 void BootloaderInstaller::mrobe100Finish()
747 QString firmwarename
= m_bootloadername
;
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
);
764 QFileInfo
firmwareOrigFI(firmwareOrig
);
766 if(!firmwareOrigFI
.exists())
768 QFile
firmwareFile(firmware
);
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();
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
);
783 else //there is already a original firmware
785 QFile
firmwareFile(firmware
);
786 firmwareFile
.remove();
789 if(!downloadFile
.copy(firmware
))
791 m_dp
->addItem(tr("Could not copy: %1 to %2")
792 .arg(m_tempfilename
,firmware
),LOGERROR
);
797 downloadFile
.remove();
801 m_dp
->addItem(tr("Bootloader install finished successfully."),LOGOK
);
804 emit
done(false); // success
808 /**************************************************
809 *** ipod secific code
810 ***************************************************/
812 // reserves memory for ipodpatcher
813 bool initIpodpatcher()
815 if (ipod_alloc_buffer(&ipod_sectorbuf
,BUFFER_SIZE
) < 0) return true;
819 void BootloaderInstaller::ipodPrepare()
821 m_dp
->addItem(tr("Searching for ipods"),LOGINFO
);
824 int n
= ipod_scan(&ipod
);
827 m_dp
->addItem(tr("No Ipods found"),LOGERROR
);
833 m_dp
->addItem(tr("Too many Ipods found"),LOGERROR
);
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
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
);
869 if (read_partinfo(&ipod
,0) < 0)
871 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
876 if (ipod
.pinfo
[0].start
==0)
878 m_dp
->addItem(tr("No partition 0 on disk"),LOGERROR
);
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(
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
);
900 read_directory(&ipod
);
902 if (ipod
.nimages
<= 0)
904 m_dp
->addItem(tr("Failed to read firmware directory"),LOGERROR
);
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
);
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"),
926 if (ipod_reopen_rw(&ipod
) < 0)
928 m_dp
->addItem(tr("Could not open Ipod in RW mode"),LOGERROR
);
933 if (ipod
.ipod_directory
[0].entryOffset
==0) {
934 m_dp
->addItem(tr("No bootloader detected."),LOGERROR
);
939 if (delete_bootloader(&ipod
)==0)
941 m_dp
->addItem(tr("Successfully removed Bootloader"),LOGOK
);
949 m_dp
->addItem(tr("--delete-bootloader failed."),LOGERROR
);
957 void BootloaderInstaller::ipodFinish()
962 if (ipod_open(&ipod
, 0) < 0)
964 m_dp
->addItem(tr("could not open ipod"),LOGERROR
);
969 if (read_partinfo(&ipod
,0) < 0)
971 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
976 if (ipod
.pinfo
[0].start
==0)
978 m_dp
->addItem(tr("No partition 0 on disk"),LOGERROR
);
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(
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
);
1002 read_directory(&ipod
);
1004 if (ipod
.nimages
<= 0)
1006 m_dp
->addItem(tr("Failed to read firmware directory"),LOGERROR
);
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
);
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"),
1028 if (ipod_reopen_rw(&ipod
) < 0)
1030 m_dp
->addItem(tr("Could not open Ipod in RW mode"),LOGERROR
);
1035 if (add_bootloader(&ipod
, m_tempfilename
.toLatin1().data(), FILETYPE_DOT_IPOD
)==0)
1037 m_dp
->addItem(tr("Successfully added Bootloader"),LOGOK
);
1045 m_dp
->addItem(tr("failed to add Bootloader"),LOGERROR
);
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;
1063 void BootloaderInstaller::sansaPrepare()
1065 m_dp
->addItem(tr("Searching for sansas"),LOGINFO
);
1066 struct sansa_t sansa
;
1068 int n
= sansa_scan(&sansa
);
1071 m_dp
->addItem(tr("No Sansa found"),LOGERROR
);
1077 m_dp
->addItem(tr("Too many Sansas found"),LOGERROR
);
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
);
1114 if (sansa_read_partinfo(&sansa
,0) < 0)
1116 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
1121 int i
= is_sansa(&sansa
);
1123 m_dp
->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i
),LOGERROR
);
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
);
1141 if (sansa_reopen_rw(&sansa
) < 0)
1143 m_dp
->addItem(tr("Could not open Sansa in RW mode"),LOGERROR
);
1148 if (sansa_delete_bootloader(&sansa
)==0)
1150 m_dp
->addItem(tr("Successfully removed Bootloader"),LOGOK
);
1153 sansa_close(&sansa
);
1158 m_dp
->addItem(tr("--delete-bootloader failed."),LOGERROR
);
1160 sansa_close(&sansa
);
1166 void BootloaderInstaller::sansaFinish()
1168 struct sansa_t sansa
;
1171 if (sansa_open(&sansa
, 0) < 0)
1173 m_dp
->addItem(tr("could not open Sansa"),LOGERROR
);
1178 if (sansa_read_partinfo(&sansa
,0) < 0)
1180 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
1186 int i
= is_sansa(&sansa
);
1189 m_dp
->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i
),LOGERROR
);
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
);
1206 if (sansa_reopen_rw(&sansa
) < 0)
1208 m_dp
->addItem(tr("Could not open Sansa in RW mode"),LOGERROR
);
1213 if (sansa_add_bootloader(&sansa
, m_tempfilename
.toLatin1().data(), FILETYPE_MI4
)==0)
1215 m_dp
->addItem(tr("Successfully added Bootloader"),LOGOK
);
1218 sansa_close(&sansa
);
1223 m_dp
->addItem(tr("failed to add Bootloader"),LOGERROR
);
1224 sansa_close(&sansa
);
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
);
1244 /* Check firmware against md5sums in h120sums and h100sums */
1246 table_entry
= intable(md5sum_str
, &h120pairs
[0],
1247 sizeof(h120pairs
)/sizeof(struct sumpairs
));
1248 if (table_entry
>= 0) {
1253 table_entry
= intable(md5sum_str
, &h100pairs
[0],
1254 sizeof(h100pairs
)/sizeof(struct sumpairs
));
1255 if (table_entry
>= 0)
1261 table_entry
= intable(md5sum_str
, &h300pairs
[0],
1262 sizeof(h300pairs
)/sizeof(struct sumpairs
));
1263 if (table_entry
>= 0)
1269 m_dp
->addItem(tr("Could not detect firmware type"),LOGERROR
);
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()
1298 char md5sum_str
[32];
1299 struct sumpairs
*sums
= 0;
1302 /* get pointer to the correct bootloader.bin */
1305 sums
= &h100pairs
[0];
1309 sums
= &h120pairs
[0];
1313 sums
= &h300pairs
[0];
1318 // temporary files needs to be opened to get the filename
1319 QTemporaryFile firmwareBin
, newBin
, newHex
;
1323 QString firmwareBinName
= firmwareBin
.fileName();
1324 QString newBinName
= newBin
.fileName();
1325 QString newHexName
= newHex
.fileName();
1326 firmwareBin
.close();
1332 if ((result
= iriver_decode(m_origfirmware
, firmwareBinName
, FALSE
, STRIP_NONE
)) < 0)
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();
1354 if((result
= mkboot(firmwareBinName
, newBinName
, m_tempfilename
, origin
)) < 0)
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();
1375 if((result
= iriver_encode(newBinName
, newHexName
, FALSE
)) < 0)
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();
1399 if (!FileMD5(newHexName
, md5sum_str
))
1401 m_dp
->addItem(tr("Error in checksumming"),LOGERROR
);
1402 firmwareBin
.remove();
1408 if (strncmp(sums
[table_entry
].patched
, md5sum_str
, 32) == 0) {
1409 /* delete temp files */
1410 firmwareBin
.remove();
1414 // Load patched Firmware to player
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";
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
);
1434 downloadFile
.remove();
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
);
1447 emit
done(false); // success