When applying the system proxy values really use the values.
[Rockbox.git] / rbutil / rbutilqt / installbootloader.cpp
blob7c6867ecbd8ebbe77ab78908890ca9972c7e508b
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 the firmware, if there is no original firmware there
382 if(!firmwareOrigFI.exists())
384 QFile firmwareFile(firmware);
385 if(!firmwareFile.rename(firmwareOrig))
387 m_dp->addItem(tr("Could not rename: %1 to %2")
388 .arg(firmware,firmwareOrig),LOGERROR);
389 emit done(true);
390 return;
393 else // or remove the normal firmware, if the original is there
395 QFile firmwareFile(firmware);
396 firmwareFile.remove();
399 //copy the firmware
400 if(!downloadFile.copy(firmware))
402 m_dp->addItem(tr("Could not copy: %1 to %2")
403 .arg(m_tempfilename,firmware),LOGERROR);
404 emit done(true);
405 return;
408 downloadFile.remove();
410 createInstallLog();
412 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
413 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
414 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
415 m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO);
416 m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO);
417 m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO);
418 m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO);
421 m_dp->abort();
423 emit done(false); // success
427 /**************************************************
428 *** iaudio secific code
429 ***************************************************/
430 void BootloaderInstaller::iaudioPrepare()
433 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
435 m_dp->addItem(tr("Downloading file %1.%2")
436 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
438 // temporary file needs to be opened to get the filename
439 downloadFile.open();
440 m_tempfilename = downloadFile.fileName();
441 downloadFile.close();
442 // get the real file.
443 getter = new HttpGet(this);
444 getter->setProxy(m_proxy);
445 getter->setFile(&downloadFile);
446 getter->getFile(QUrl(url));
447 // connect signals from HttpGet
448 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
449 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
450 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
453 void BootloaderInstaller::iaudioFinish()
455 QString firmware = m_mountpoint + "/FIRMWARE/" + m_bootloadername;
457 //copy the firmware
458 if(!downloadFile.copy(firmware))
460 m_dp->addItem(tr("Could not copy: %1 to %2")
461 .arg(m_tempfilename,firmware),LOGERROR);
462 emit done(true);
463 return;
466 downloadFile.remove();
468 createInstallLog();
470 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
471 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
472 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
473 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
474 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
476 m_dp->abort();
478 emit done(false); // success
483 /**************************************************
484 *** h10 secific code
485 ***************************************************/
486 void BootloaderInstaller::h10Prepare()
488 if(m_install) // Installation
490 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
492 m_dp->addItem(tr("Downloading file %1.%2")
493 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
495 // temporary file needs to be opened to get the filename
496 downloadFile.open();
497 m_tempfilename = downloadFile.fileName();
498 downloadFile.close();
499 // get the real file.
500 getter = new HttpGet(this);
501 getter->setProxy(m_proxy);
502 getter->setFile(&downloadFile);
503 getter->getFile(QUrl(url));
504 // connect signals from HttpGet
505 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
506 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
507 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
509 else // Uninstallation
512 QString firmwarename = m_bootloadername.section('/', -1);
514 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
515 QString firmwareOrig = m_mountpoint + "/SYSTEM/OF.mi4";
517 QFileInfo firmwareFI(firmware);
518 if(!firmwareFI.exists()) //Firmware dosent exists on player
520 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
521 firmwareFI.setFile(firmware);
522 if(!firmwareFI.exists()) //Firmware dosent exists on player
524 m_dp->addItem(tr("Firmware does not exist: %1")
525 .arg(firmware),LOGERROR);
526 emit done(true);
527 return;
531 QFileInfo firmwareOrigFI(firmwareOrig);
532 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
534 m_dp->addItem(tr("Original Firmware does not exist: %1")
535 .arg(firmwareOrig),LOGERROR);
536 emit done(true);
537 return;
540 QFile firmwareFile(firmware);
541 QFile firmwareOrigFile(firmwareOrig);
543 //remove modified firmware
544 if(!firmwareFile.remove())
546 m_dp->addItem(tr("Could not remove the Firmware at: %1")
547 .arg(firmware),LOGERROR);
548 emit done(true);
549 return;
552 //copy original firmware
553 if(!firmwareOrigFile.copy(firmware))
555 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
556 .arg(firmwareOrig,firmware),LOGERROR);
557 emit done(true);
558 return;
561 removeInstallLog();
563 emit done(false); //success
568 void BootloaderInstaller::h10Finish()
570 QString firmwarename = m_bootloadername.section('/', -1);
572 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
573 QString firmwareOrig = m_mountpoint + "/SYSTEM/OF.mi4";
575 QFileInfo firmwareFI(firmware);
577 if(!firmwareFI.exists()) //Firmware dosent exists on player
579 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
580 firmwareFI.setFile(firmware);
581 if(!firmwareFI.exists()) //Firmware dosent exists on player
583 m_dp->addItem(tr("Firmware does not exist: %1")
584 .arg(firmware),LOGERROR);
585 emit done(true);
586 return;
590 QFileInfo firmwareOrigFI(firmwareOrig);
592 if(!firmwareOrigFI.exists()) //there is already a original firmware
594 QFile firmwareFile(firmware);
595 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
597 m_dp->addItem(tr("Could not rename: %1 to %2")
598 .arg(firmware,firmwareOrig),LOGERROR);
599 emit done(true);
600 return;
603 else
605 QFile firmwareFile(firmware);
606 firmwareFile.remove();
608 //copy the firmware
609 if(!downloadFile.copy(firmware))
611 m_dp->addItem(tr("Could not copy: %1 to %2")
612 .arg(m_tempfilename,firmware),LOGERROR);
613 emit done(true);
614 return;
617 downloadFile.remove();
619 createInstallLog();
621 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
622 m_dp->abort();
624 emit done(false); // success
628 /**************************************************
629 *** ipod secific code
630 ***************************************************/
631 int verbose =0;
632 // reserves memory for ipodpatcher
633 bool initIpodpatcher()
635 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
636 else return false;
639 void BootloaderInstaller::ipodPrepare()
641 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
642 struct ipod_t ipod;
644 int n = ipod_scan(&ipod);
645 if (n == 0)
647 m_dp->addItem(tr("No Ipods found"),LOGERROR);
648 emit done(true);
649 return;
651 if (n > 1)
653 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
654 emit done(true);
657 if(m_install) // Installation
660 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
662 m_dp->addItem(tr("Downloading file %1.%2")
663 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
665 // temporary file needs to be opened to get the filename
666 downloadFile.open();
667 m_tempfilename = downloadFile.fileName();
668 downloadFile.close();
669 // get the real file.
670 getter = new HttpGet(this);
671 getter->setProxy(m_proxy);
672 getter->setFile(&downloadFile);
673 getter->getFile(QUrl(url));
674 // connect signals from HttpGet
675 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
676 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
677 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
679 else // Uninstallation
681 if (ipod_open(&ipod, 0) < 0)
683 m_dp->addItem(tr("could not open ipod"),LOGERROR);
684 emit done(true);
685 return;
688 if (read_partinfo(&ipod,0) < 0)
690 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
691 emit done(true);
692 return;
695 if (ipod.pinfo[0].start==0)
697 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
699 int i;
700 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
701 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
702 for ( i = 0; i < 4; i++ )
704 if (ipod.pinfo[i].start != 0)
706 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
707 i).arg(
708 ipod.pinfo[i].start).arg(
709 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
710 ipod.pinfo[i].size/sectors_per_MB).arg(
711 get_parttype(ipod.pinfo[i].type)).arg(
712 ipod.pinfo[i].type),LOGINFO);
715 emit done(true);
716 return;
719 read_directory(&ipod);
721 if (ipod.nimages <= 0)
723 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
724 emit done(true);
725 return;
727 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
729 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
730 ipod.ipod_directory[0].vers),LOGERROR);
731 emit done(true);
732 return;
735 if (ipod.macpod)
737 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
738 "this. Convert it to WinPod\n"
739 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
740 LOGWARNING);
741 emit done(true);
742 return;
745 if (ipod_reopen_rw(&ipod) < 0)
747 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
748 emit done(true);
749 return;
752 if (ipod.ipod_directory[0].entryOffset==0) {
753 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
754 emit done(true);
755 return;
758 if (delete_bootloader(&ipod)==0)
760 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
761 removeInstallLog();
762 emit done(false);
763 ipod_close(&ipod);
764 return;
766 else
768 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
769 emit done(true);
770 ipod_close(&ipod);
771 return;
776 void BootloaderInstaller::ipodFinish()
778 struct ipod_t ipod;
779 ipod_scan(&ipod);
781 if (ipod_open(&ipod, 0) < 0)
783 m_dp->addItem(tr("could not open ipod"),LOGERROR);
784 emit done(true);
785 return;
788 if (read_partinfo(&ipod,0) < 0)
790 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
791 emit done(true);
792 return;
795 if (ipod.pinfo[0].start==0)
797 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
799 int i;
800 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
802 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
804 for ( i = 0; i < 4; i++ )
806 if (ipod.pinfo[i].start != 0)
808 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
809 i).arg(
810 ipod.pinfo[i].start).arg(
811 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
812 ipod.pinfo[i].size/sectors_per_MB).arg(
813 get_parttype(ipod.pinfo[i].type)).arg(
814 ipod.pinfo[i].type),LOGWARNING);
817 emit done(true);
818 return;
821 read_directory(&ipod);
823 if (ipod.nimages <= 0)
825 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
826 emit done(true);
827 return;
829 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
831 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
832 ipod.ipod_directory[0].vers),LOGERROR);
833 emit done(true);
834 return;
837 if (ipod.macpod)
839 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on "
840 "this. Convert it to WinPod\n"
841 "See http://www.rockbox.org/wiki/IpodConversionToFAT32"),
842 LOGWARNING);
843 emit done(true);
844 return;
847 if (ipod_reopen_rw(&ipod) < 0)
849 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
850 emit done(true);
851 return;
854 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
856 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
857 createInstallLog();
858 emit done(false);
859 ipod_close(&ipod);
860 return;
862 else
864 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
865 ipod_close(&ipod);
866 emit done(true);
867 return;
871 /**************************************************
872 *** sansa secific code
873 ***************************************************/
874 // reserves memory for sansapatcher
875 bool initSansapatcher()
877 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
878 else return false;
882 void BootloaderInstaller::sansaPrepare()
884 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
885 struct sansa_t sansa;
887 int n = sansa_scan(&sansa);
888 if (n == 0)
890 m_dp->addItem(tr("No Sansa found"),LOGERROR);
891 emit done(true);
892 return;
894 if (n > 1)
896 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
897 emit done(true);
900 if(m_install) // Installation
902 QString url = m_bootloaderUrlBase + "/sandisk-sansa/"
903 + QString(sansa.targetname) + "/" + m_bootloadername;
905 m_dp->addItem(tr("Downloading file %1.%2")
906 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
908 // temporary file needs to be opened to get the filename
909 downloadFile.open();
910 m_tempfilename = downloadFile.fileName();
911 downloadFile.close();
912 // get the real file.
913 getter = new HttpGet(this);
914 getter->setProxy(m_proxy);
915 getter->setFile(&downloadFile);
916 getter->getFile(QUrl(url));
917 // connect signals from HttpGet
918 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
919 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
920 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
922 else // Uninstallation
925 if (sansa_open(&sansa, 0) < 0)
927 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
928 emit done(true);
929 return;
932 if (sansa_read_partinfo(&sansa,0) < 0)
934 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
935 emit done(true);
936 return;
939 int i = is_sansa(&sansa);
940 if (i < 0) {
941 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
942 emit done(true);
943 return;
946 if (sansa.hasoldbootloader)
948 m_dp->addItem(tr("********************************************\n"
949 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
950 "You must reinstall the original Sansa firmware before running\n"
951 "sansapatcher for the first time.\n"
952 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
953 "*********************************************\n"),LOGERROR);
954 emit done(true);
955 return;
959 if (sansa_reopen_rw(&sansa) < 0)
961 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
962 emit done(true);
963 return;
966 if (sansa_delete_bootloader(&sansa)==0)
968 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
969 removeInstallLog();
970 emit done(false);
971 sansa_close(&sansa);
972 return;
974 else
976 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
977 emit done(true);
978 sansa_close(&sansa);
979 return;
984 void BootloaderInstaller::sansaFinish()
986 struct sansa_t sansa;
987 sansa_scan(&sansa);
989 if (sansa_open(&sansa, 0) < 0)
991 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
992 emit done(true);
993 return;
996 if (sansa_read_partinfo(&sansa,0) < 0)
998 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
999 emit done(true);
1000 return;
1004 int i = is_sansa(&sansa);
1005 if (i < 0) {
1007 m_dp->addItem(tr("Disk is not a Sansa (%1), aborting.").arg(i),LOGERROR);
1008 emit done(true);
1009 return;
1012 if (sansa.hasoldbootloader)
1014 m_dp->addItem(tr("********************************************\n"
1015 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
1016 "You must reinstall the original Sansa firmware before running\n"
1017 "sansapatcher for the first time.\n"
1018 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
1019 "*********************************************\n"),LOGERROR);
1020 emit done(true);
1021 return;
1024 if (sansa_reopen_rw(&sansa) < 0)
1026 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
1027 emit done(true);
1028 return;
1031 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
1033 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
1034 createInstallLog();
1035 emit done(false);
1036 sansa_close(&sansa);
1037 return;
1039 else
1041 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
1042 sansa_close(&sansa);
1043 emit done(true);
1044 return;
1049 /**************************************************
1050 *** iriver /fwpatcher secific code
1051 ***************************************************/
1053 void BootloaderInstaller::iriverPrepare()
1055 char md5sum_str[32];
1056 if (!FileMD5(m_origfirmware, md5sum_str)) {
1057 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
1058 emit done(true);
1059 return;
1062 /* Check firmware against md5sums in h120sums and h100sums */
1063 series = 0;
1064 table_entry = intable(md5sum_str, &h120pairs[0],
1065 sizeof(h120pairs)/sizeof(struct sumpairs));
1066 if (table_entry >= 0) {
1067 series = 120;
1069 else
1071 table_entry = intable(md5sum_str, &h100pairs[0],
1072 sizeof(h100pairs)/sizeof(struct sumpairs));
1073 if (table_entry >= 0)
1075 series = 100;
1077 else
1079 table_entry = intable(md5sum_str, &h300pairs[0],
1080 sizeof(h300pairs)/sizeof(struct sumpairs));
1081 if (table_entry >= 0)
1082 series = 300;
1085 if (series == 0)
1087 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
1088 emit done(true);
1089 return;
1092 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
1094 m_dp->addItem(tr("Downloading file %1.%2")
1095 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
1097 // temporary file needs to be opened to get the filename
1098 downloadFile.open();
1099 m_tempfilename = downloadFile.fileName();
1100 downloadFile.close();
1101 // get the real file.
1102 getter = new HttpGet(this);
1103 getter->setProxy(m_proxy);
1104 getter->setFile(&downloadFile);
1105 getter->getFile(QUrl(url));
1106 // connect signals from HttpGet
1107 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
1108 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
1109 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
1112 void BootloaderInstaller::iriverFinish()
1114 // Patch firmware
1115 char md5sum_str[32];
1116 struct sumpairs *sums = 0;
1117 int origin = 0;
1119 /* get pointer to the correct bootloader.bin */
1120 switch(series) {
1121 case 100:
1122 sums = &h100pairs[0];
1123 origin = 0x1f0000;
1124 break;
1125 case 120:
1126 sums = &h120pairs[0];
1127 origin = 0x1f0000;
1128 break;
1129 case 300:
1130 sums = &h300pairs[0];
1131 origin = 0x3f0000;
1132 break;
1135 // temporary files needs to be opened to get the filename
1136 QTemporaryFile firmwareBin, newBin, newHex;
1137 firmwareBin.open();
1138 newBin.open();
1139 newHex.open();
1140 QString firmwareBinName = firmwareBin.fileName();
1141 QString newBinName = newBin.fileName();
1142 QString newHexName = newHex.fileName();
1143 firmwareBin.close();
1144 newBin.close();
1145 newHex.close();
1147 // iriver decode
1148 if (iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE,m_dp) == -1)
1150 m_dp->addItem(tr("Error in descramble"),LOGERROR);
1151 firmwareBin.remove();
1152 newBin.remove();
1153 newHex.remove();
1154 emit done(true);
1155 return;
1157 // mkboot
1158 if (!mkboot(firmwareBinName, newBinName, m_tempfilename, origin,m_dp))
1160 m_dp->addItem(tr("Error in patching"),LOGERROR);
1161 firmwareBin.remove();
1162 newBin.remove();
1163 newHex.remove();
1164 emit done(true);
1165 return;
1167 // iriver_encode
1168 if (iriver_encode(newBinName, newHexName, FALSE,m_dp) == -1)
1170 m_dp->addItem(tr("Error in scramble"),LOGERROR);
1171 firmwareBin.remove();
1172 newBin.remove();
1173 newHex.remove();
1174 emit done(true);
1175 return;
1178 /* now md5sum it */
1179 if (!FileMD5(newHexName, md5sum_str))
1181 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1182 firmwareBin.remove();
1183 newBin.remove();
1184 newHex.remove();
1185 emit done(true);
1186 return;
1188 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1189 /* delete temp files */
1190 firmwareBin.remove();
1191 newBin.remove();
1194 // Load patched Firmware to player
1195 QString dest;
1196 if(series == 100)
1197 dest = m_mountpoint + "/ihp_100.hex";
1198 else if(series == 120)
1199 dest = m_mountpoint + "/ihp_120.hex";
1200 else if(series == 300)
1201 dest = m_mountpoint + "/H300.hex";
1203 // copy file
1204 QFile destfile(dest);
1205 if(destfile.exists()) destfile.remove();
1206 if(!newHex.copy(dest))
1208 m_dp->addItem(tr("Could not copy: %1 to %2")
1209 .arg(newHexName,dest),LOGERROR);
1210 emit done(true);
1211 return;
1214 downloadFile.remove();
1215 newHex.remove();
1217 createInstallLog();
1219 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1220 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1221 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1222 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1223 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1224 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1225 m_dp->abort();
1227 emit done(false); // success