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"
23 BootloaderInstaller::BootloaderInstaller(QObject
* parent
): QObject(parent
)
28 void BootloaderInstaller::install(ProgressloggerInterface
* dp
)
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()));
73 m_dp
->addItem(tr("unsupported install Method"),LOGERROR
);
81 void BootloaderInstaller::uninstall(ProgressloggerInterface
* dp
)
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
);
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
);
122 m_dp
->addItem(tr("unsupported install Method"),LOGERROR
);
130 void BootloaderInstaller::downloadRequestFinished(int id
, bool error
)
132 qDebug() << "BootloaderInstall::downloadRequestFinished" << id
<< error
;
133 qDebug() << "error:" << getter
->errorString();
138 void BootloaderInstaller::downloadDone(bool error
)
140 qDebug() << "Install::downloadDone, error:" << error
;
142 // update progress bar
144 int max
= m_dp
->getProgressMax();
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
);
157 m_dp
->addItem(tr("Download error: %1").arg(getter
->errorString()),LOGERROR
);
162 else m_dp
->addItem(tr("Download finished."),LOGOK
);
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
)
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;
200 while(!infoDownloaded
)
201 QCoreApplication::processEvents();
205 void BootloaderInstaller::infoDownloadDone(bool error
)
209 qDebug() << "network error:" << infodownloader
->error();
212 qDebug() << "network status:" << infodownloader
->error();
214 infoDownloaded
= true;
217 void BootloaderInstaller::infoRequestFinished(int id
, bool error
)
223 errorString
= tr("Network error: %1. Please check your network and proxy settings.")
224 .arg(infodownloader
->errorString());
226 if(error
) QMessageBox::about(NULL
, "Network Error", errorString
);
228 qDebug() << "downloadDone:" << id
<< error
;
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();
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();
264 bool BootloaderInstaller::uptodate()
266 QString installedMd5
;
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();
281 if(installedMd5
!= serverMd5
)
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
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
);
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
);
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
);
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
);
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
);
386 QDir::home().mkdir("Gigabeat Original Firmware Backup");
387 firmwareFile
.copy(QDir::toNativeSeparators(QDir::homePath()) + QDir::toNativeSeparators("/Gigabeat Original Firmware Backup/") + m_bootloadername
);
390 if(!firmwareFile
.rename(firmwareOrig
))
392 m_dp
->addItem(tr("Could not rename: %1 to %2")
393 .arg(firmware
,firmwareOrig
),LOGERROR
);
398 else // or remove the normal firmware, if the original is there
400 QFile
firmwareFile(firmware
);
401 firmwareFile
.remove();
405 if(!downloadFile
.copy(firmware
))
407 m_dp
->addItem(tr("Could not copy: %1 to %2")
408 .arg(m_tempfilename
,firmware
),LOGERROR
);
413 downloadFile
.remove();
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
);
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
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
;
463 if(!downloadFile
.copy(firmware
))
465 m_dp
->addItem(tr("Could not copy: %1 to %2")
466 .arg(m_tempfilename
,firmware
),LOGERROR
);
471 downloadFile
.remove();
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
);
483 emit
done(false); // success
488 /**************************************************
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
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
);
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
);
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
);
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
);
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
);
595 QFileInfo
firmwareOrigFI(firmwareOrig
);
597 if(!firmwareOrigFI
.exists())
599 QFile
firmwareFile(firmware
);
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
);
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
);
614 else //there is already a original firmware
616 QFile
firmwareFile(firmware
);
617 firmwareFile
.remove();
620 if(!downloadFile
.copy(firmware
))
622 m_dp
->addItem(tr("Could not copy: %1 to %2")
623 .arg(m_tempfilename
,firmware
),LOGERROR
);
628 downloadFile
.remove();
632 m_dp
->addItem(tr("Bootloader install finished successfully."),LOGOK
);
635 emit
done(false); // success
639 /**************************************************
640 *** ipod secific code
641 ***************************************************/
643 // reserves memory for ipodpatcher
644 bool initIpodpatcher()
646 if (ipod_alloc_buffer(§orbuf
,BUFFER_SIZE
) < 0) return true;
650 void BootloaderInstaller::ipodPrepare()
652 m_dp
->addItem(tr("Searching for ipods"),LOGINFO
);
655 int n
= ipod_scan(&ipod
);
658 m_dp
->addItem(tr("No Ipods found"),LOGERROR
);
664 m_dp
->addItem(tr("Too many Ipods found"),LOGERROR
);
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
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
);
699 if (read_partinfo(&ipod
,0) < 0)
701 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
706 if (ipod
.pinfo
[0].start
==0)
708 m_dp
->addItem(tr("No partition 0 on disk"),LOGERROR
);
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(
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
);
730 read_directory(&ipod
);
732 if (ipod
.nimages
<= 0)
734 m_dp
->addItem(tr("Failed to read firmware directory"),LOGERROR
);
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
);
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"),
756 if (ipod_reopen_rw(&ipod
) < 0)
758 m_dp
->addItem(tr("Could not open Ipod in RW mode"),LOGERROR
);
763 if (ipod
.ipod_directory
[0].entryOffset
==0) {
764 m_dp
->addItem(tr("No bootloader detected."),LOGERROR
);
769 if (delete_bootloader(&ipod
)==0)
771 m_dp
->addItem(tr("Successfully removed Bootloader"),LOGOK
);
779 m_dp
->addItem(tr("--delete-bootloader failed."),LOGERROR
);
787 void BootloaderInstaller::ipodFinish()
792 if (ipod_open(&ipod
, 0) < 0)
794 m_dp
->addItem(tr("could not open ipod"),LOGERROR
);
799 if (read_partinfo(&ipod
,0) < 0)
801 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
806 if (ipod
.pinfo
[0].start
==0)
808 m_dp
->addItem(tr("No partition 0 on disk"),LOGERROR
);
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(
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
);
832 read_directory(&ipod
);
834 if (ipod
.nimages
<= 0)
836 m_dp
->addItem(tr("Failed to read firmware directory"),LOGERROR
);
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
);
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"),
858 if (ipod_reopen_rw(&ipod
) < 0)
860 m_dp
->addItem(tr("Could not open Ipod in RW mode"),LOGERROR
);
865 if (add_bootloader(&ipod
, m_tempfilename
.toLatin1().data(), FILETYPE_DOT_IPOD
)==0)
867 m_dp
->addItem(tr("Successfully added Bootloader"),LOGOK
);
875 m_dp
->addItem(tr("failed to add Bootloader"),LOGERROR
);
882 /**************************************************
883 *** sansa secific code
884 ***************************************************/
885 // reserves memory for sansapatcher
886 bool initSansapatcher()
888 if (sansa_alloc_buffer(§orbuf
,BUFFER_SIZE
) < 0) return true;
893 void BootloaderInstaller::sansaPrepare()
895 m_dp
->addItem(tr("Searching for sansas"),LOGINFO
);
896 struct sansa_t sansa
;
898 int n
= sansa_scan(&sansa
);
901 m_dp
->addItem(tr("No Sansa found"),LOGERROR
);
907 m_dp
->addItem(tr("Too many Sansas found"),LOGERROR
);
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
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
);
943 if (sansa_read_partinfo(&sansa
,0) < 0)
945 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
950 int i
= is_sansa(&sansa
);
952 m_dp
->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i
),LOGERROR
);
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
);
970 if (sansa_reopen_rw(&sansa
) < 0)
972 m_dp
->addItem(tr("Could not open Sansa in RW mode"),LOGERROR
);
977 if (sansa_delete_bootloader(&sansa
)==0)
979 m_dp
->addItem(tr("Successfully removed Bootloader"),LOGOK
);
987 m_dp
->addItem(tr("--delete-bootloader failed."),LOGERROR
);
995 void BootloaderInstaller::sansaFinish()
997 struct sansa_t sansa
;
1000 if (sansa_open(&sansa
, 0) < 0)
1002 m_dp
->addItem(tr("could not open Sansa"),LOGERROR
);
1007 if (sansa_read_partinfo(&sansa
,0) < 0)
1009 m_dp
->addItem(tr("could not read partitiontable"),LOGERROR
);
1015 int i
= is_sansa(&sansa
);
1018 m_dp
->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i
),LOGERROR
);
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
);
1035 if (sansa_reopen_rw(&sansa
) < 0)
1037 m_dp
->addItem(tr("Could not open Sansa in RW mode"),LOGERROR
);
1042 if (sansa_add_bootloader(&sansa
, m_tempfilename
.toLatin1().data(), FILETYPE_MI4
)==0)
1044 m_dp
->addItem(tr("Successfully added Bootloader"),LOGOK
);
1047 sansa_close(&sansa
);
1052 m_dp
->addItem(tr("failed to add Bootloader"),LOGERROR
);
1053 sansa_close(&sansa
);
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
);
1073 /* Check firmware against md5sums in h120sums and h100sums */
1075 table_entry
= intable(md5sum_str
, &h120pairs
[0],
1076 sizeof(h120pairs
)/sizeof(struct sumpairs
));
1077 if (table_entry
>= 0) {
1082 table_entry
= intable(md5sum_str
, &h100pairs
[0],
1083 sizeof(h100pairs
)/sizeof(struct sumpairs
));
1084 if (table_entry
>= 0)
1090 table_entry
= intable(md5sum_str
, &h300pairs
[0],
1091 sizeof(h300pairs
)/sizeof(struct sumpairs
));
1092 if (table_entry
>= 0)
1098 m_dp
->addItem(tr("Could not detect firmware type"),LOGERROR
);
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()
1126 char md5sum_str
[32];
1127 struct sumpairs
*sums
= 0;
1130 /* get pointer to the correct bootloader.bin */
1133 sums
= &h100pairs
[0];
1137 sums
= &h120pairs
[0];
1141 sums
= &h300pairs
[0];
1146 // temporary files needs to be opened to get the filename
1147 QTemporaryFile firmwareBin
, newBin
, newHex
;
1151 QString firmwareBinName
= firmwareBin
.fileName();
1152 QString newBinName
= newBin
.fileName();
1153 QString newHexName
= newHex
.fileName();
1154 firmwareBin
.close();
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();
1169 if (!mkboot(firmwareBinName
, newBinName
, m_tempfilename
, origin
,m_dp
))
1171 m_dp
->addItem(tr("Error in patching"),LOGERROR
);
1172 firmwareBin
.remove();
1179 if (iriver_encode(newBinName
, newHexName
, FALSE
,m_dp
) == -1)
1181 m_dp
->addItem(tr("Error in scramble"),LOGERROR
);
1182 firmwareBin
.remove();
1190 if (!FileMD5(newHexName
, md5sum_str
))
1192 m_dp
->addItem(tr("Error in checksumming"),LOGERROR
);
1193 firmwareBin
.remove();
1199 if (strncmp(sums
[table_entry
].patched
, md5sum_str
, 32) == 0) {
1200 /* delete temp files */
1201 firmwareBin
.remove();
1205 // Load patched Firmware to player
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";
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
);
1225 downloadFile
.remove();
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
);
1238 emit
done(false); // success