set missing keywords property.
[Rockbox.git] / rbutil / rbutilqt / installbootloader.cpp
blobc124c711505b38c3213f3e4a7935e6a8cbe33f66
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();
183 /**************************************************
184 *** gigabeat secific code
185 ***************************************************/
187 void BootloaderInstaller::gigabeatPrepare()
189 if(m_install) // Installation
191 QString url = m_bootloaderUrlBase + "/gigabeat/" + m_bootloadername;
193 m_dp->addItem(tr("Downloading file %1.%2")
194 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
196 // temporary file needs to be opened to get the filename
197 downloadFile.open();
198 m_tempfilename = downloadFile.fileName();
199 downloadFile.close();
200 // get the real file.
201 getter = new HttpGet(this);
202 getter->setProxy(m_proxy);
203 getter->setFile(&downloadFile);
204 getter->getFile(QUrl(url));
205 // connect signals from HttpGet
206 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
207 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
208 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
210 else //UnInstallation
212 QString firmware = m_mountpoint + "/GBSYSTEM/FWIMG/FWIMG01.DAT";
213 QString firmwareOrig = firmware.append(".ORIG");
215 QFileInfo firmwareOrigFI(firmwareOrig);
217 // check if original firmware exists
218 if(!firmwareOrigFI.exists())
220 m_dp->addItem(tr("Could not find the Original Firmware at: %1")
221 .arg(firmwareOrig),LOGERROR);
222 emit done(true);
223 return;
226 QFile firmwareFile(firmware);
227 QFile firmwareOrigFile(firmwareOrig);
229 //remove modified firmware
230 if(!firmwareFile.remove())
232 m_dp->addItem(tr("Could not remove the Firmware at: %1")
233 .arg(firmware),LOGERROR);
234 emit done(true);
235 return;
238 //copy original firmware
239 if(!firmwareOrigFile.copy(firmware))
241 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
242 .arg(firmwareOrig,firmware),LOGERROR);
243 emit done(true);
244 return;
247 emit done(false); //success
252 void BootloaderInstaller::gigabeatFinish()
254 // this step is only need for installation, so no code for uninstall here
256 m_dp->addItem(tr("Finishing bootloader install"),LOGINFO);
258 QString firmware = m_mountpoint + "/GBSYSTEM/FWIMG/" + m_bootloadername;
260 QFileInfo firmwareFI(firmware);
262 // check if firmware exists
263 if(!firmwareFI.exists())
265 m_dp->addItem(tr("Could not find the Firmware at: %1")
266 .arg(firmware),LOGERROR);
267 emit done(true);
268 return;
271 QString firmwareOrig = firmware;
272 firmwareOrig.append(".ORIG");
273 QFileInfo firmwareOrigFI(firmwareOrig);
275 // rename the firmware, if there is no original firmware there
276 if(!firmwareOrigFI.exists())
278 QFile firmwareFile(firmware);
279 if(!firmwareFile.rename(firmwareOrig))
281 m_dp->addItem(tr("Could not rename: %1 to %2")
282 .arg(firmware,firmwareOrig),LOGERROR);
283 emit done(true);
284 return;
287 else // or remove the normal firmware, if the original is there
289 QFile firmwareFile(firmware);
290 firmwareFile.remove();
293 //copy the firmware
294 if(!downloadFile.copy(firmware))
296 m_dp->addItem(tr("Could not copy: %1 to %2")
297 .arg(m_tempfilename,firmware),LOGERROR);
298 emit done(true);
299 return;
302 downloadFile.remove();
304 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
305 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
306 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
307 m_dp->addItem(tr("2. Unplug USB and any Power adapters."),LOGINFO);
308 m_dp->addItem(tr("3. Hold POWER to turn the Device off."),LOGINFO);
309 m_dp->addItem(tr("4. Toggle the Battery switch on the Device."),LOGINFO);
310 m_dp->addItem(tr("5. Hold POWER to boot the Rockbox bootloader."),LOGINFO);
313 m_dp->abort();
315 emit done(false); // success
319 /**************************************************
320 *** iaudio secific code
321 ***************************************************/
322 void BootloaderInstaller::iaudioPrepare()
325 QString url = m_bootloaderUrlBase + "/iaudio/" + m_bootloadername;
327 m_dp->addItem(tr("Downloading file %1.%2")
328 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
330 // temporary file needs to be opened to get the filename
331 downloadFile.open();
332 m_tempfilename = downloadFile.fileName();
333 downloadFile.close();
334 // get the real file.
335 getter = new HttpGet(this);
336 getter->setProxy(m_proxy);
337 getter->setFile(&downloadFile);
338 getter->getFile(QUrl(url));
339 // connect signals from HttpGet
340 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
341 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
342 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
345 void BootloaderInstaller::iaudioFinish()
347 QString firmware = m_mountpoint + "/FIRMWARE/" + m_bootloadername;
349 //copy the firmware
350 if(!downloadFile.copy(firmware))
352 m_dp->addItem(tr("Could not copy: %1 to %2")
353 .arg(m_tempfilename,firmware),LOGERROR);
354 emit done(true);
355 return;
358 downloadFile.remove();
360 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
361 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
362 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
363 m_dp->addItem(tr("2. Turn you Device OFF."),LOGINFO);
364 m_dp->addItem(tr("3. Insert Charger."),LOGINFO);
366 m_dp->abort();
368 emit done(false); // success
373 /**************************************************
374 *** h10 secific code
375 ***************************************************/
376 void BootloaderInstaller::h10Prepare()
378 if(m_install) // Installation
380 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
382 m_dp->addItem(tr("Downloading file %1.%2")
383 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
385 // temporary file needs to be opened to get the filename
386 downloadFile.open();
387 m_tempfilename = downloadFile.fileName();
388 downloadFile.close();
389 // get the real file.
390 getter = new HttpGet(this);
391 getter->setProxy(m_proxy);
392 getter->setFile(&downloadFile);
393 getter->getFile(QUrl(url));
394 // connect signals from HttpGet
395 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
396 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
397 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
399 else // Uninstallation
402 QString firmwarename = m_bootloadername.section('/', -1);
404 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
405 QString firmwareOrig = m_mountpoint + "/SYSTEM/Original.mi4";
407 QFileInfo firmwareFI(firmware);
408 if(!firmwareFI.exists()) //Firmware dosent exists on player
410 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
411 firmwareFI.setFile(firmware);
412 if(!firmwareFI.exists()) //Firmware dosent exists on player
414 m_dp->addItem(tr("Firmware doesn not exist: %1")
415 .arg(firmware),LOGERROR);
416 emit done(true);
417 return;
421 QFileInfo firmwareOrigFI(firmwareOrig);
422 if(!firmwareOrigFI.exists()) //Original Firmware dosent exists on player
424 m_dp->addItem(tr("Original Firmware doesn not exist: %1")
425 .arg(firmwareOrig),LOGERROR);
426 emit done(true);
427 return;
430 QFile firmwareFile(firmware);
431 QFile firmwareOrigFile(firmwareOrig);
433 //remove modified firmware
434 if(!firmwareFile.remove())
436 m_dp->addItem(tr("Could not remove the Firmware at: %1")
437 .arg(firmware),LOGERROR);
438 emit done(true);
439 return;
442 //copy original firmware
443 if(!firmwareOrigFile.copy(firmware))
445 m_dp->addItem(tr("Could not copy the Firmware from: %1 to %2")
446 .arg(firmwareOrig,firmware),LOGERROR);
447 emit done(true);
448 return;
451 emit done(false); //success
456 void BootloaderInstaller::h10Finish()
458 QString firmwarename = m_bootloadername.section('/', -1);
460 QString firmware = m_mountpoint + "/SYSTEM/" + firmwarename;
461 QString firmwareOrig = m_mountpoint + "/SYSTEM/Original.mi4";
463 QFileInfo firmwareFI(firmware);
465 if(!firmwareFI.exists()) //Firmware dosent exists on player
467 firmware = m_mountpoint + "/SYSTEM/H10EMP.mi4"; //attempt other firmwarename
468 firmwareFI.setFile(firmware);
469 if(!firmwareFI.exists()) //Firmware dosent exists on player
471 m_dp->addItem(tr("Firmware does not exist: %1")
472 .arg(firmware),LOGERROR);
473 emit done(true);
474 return;
478 QFileInfo firmwareOrigFI(firmwareOrig);
480 if(!firmwareOrigFI.exists()) //there is already a original firmware
482 QFile firmwareFile(firmware);
483 if(!firmwareFile.rename(firmwareOrig)) //rename Firmware to Original
485 m_dp->addItem(tr("Could not rename: %1 to %2")
486 .arg(firmware,firmwareOrig),LOGERROR);
487 emit done(true);
488 return;
491 else
493 QFile firmwareFile(firmware);
494 firmwareFile.remove();
496 //copy the firmware
497 if(!downloadFile.copy(firmware))
499 m_dp->addItem(tr("Could not copy: %1 to %2")
500 .arg(m_tempfilename,firmware),LOGERROR);
501 emit done(true);
502 return;
505 downloadFile.remove();
507 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
508 m_dp->abort();
510 emit done(false); // success
514 /**************************************************
515 *** ipod secific code
516 ***************************************************/
517 int verbose =0;
518 // reserves memory for ipodpatcher
519 bool initIpodpatcher()
521 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
522 else return false;
525 void BootloaderInstaller::ipodPrepare()
527 m_dp->addItem(tr("Searching for ipods"),LOGINFO);
528 struct ipod_t ipod;
530 int n = ipod_scan(&ipod);
531 if (n == 0)
533 m_dp->addItem(tr("No Ipods found"),LOGERROR);
534 emit done(true);
535 return;
537 if (n > 1)
539 m_dp->addItem(tr("Too many Ipods found"),LOGERROR);
540 emit done(true);
543 if(m_install) // Installation
546 QString url = m_bootloaderUrlBase + "/ipod/bootloader-" + m_bootloadername + ".ipod";
548 m_dp->addItem(tr("Downloading file %1.%2")
549 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
551 // temporary file needs to be opened to get the filename
552 downloadFile.open();
553 m_tempfilename = downloadFile.fileName();
554 downloadFile.close();
555 // get the real file.
556 getter = new HttpGet(this);
557 getter->setProxy(m_proxy);
558 getter->setFile(&downloadFile);
559 getter->getFile(QUrl(url));
560 // connect signals from HttpGet
561 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
562 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
563 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
565 else // Uninstallation
567 if (ipod_open(&ipod, 0) < 0)
569 m_dp->addItem(tr("could not open ipod"),LOGERROR);
570 emit done(true);
571 return;
574 if (read_partinfo(&ipod,0) < 0)
576 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
577 emit done(true);
578 return;
581 if (ipod.pinfo[0].start==0)
583 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
585 int i;
586 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
587 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
588 for ( i = 0; i < 4; i++ )
590 if (ipod.pinfo[i].start != 0)
592 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
593 i).arg(
594 ipod.pinfo[i].start).arg(
595 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
596 ipod.pinfo[i].size/sectors_per_MB).arg(
597 get_parttype(ipod.pinfo[i].type)).arg(
598 ipod.pinfo[i].type),LOGINFO);
601 emit done(true);
602 return;
605 read_directory(&ipod);
607 if (ipod.nimages <= 0)
609 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
610 emit done(true);
611 return;
613 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
615 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
616 ipod.ipod_directory[0].vers),LOGERROR);
617 emit done(true);
618 return;
621 if (ipod.macpod)
623 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod"),LOGWARNING);
626 if (ipod_reopen_rw(&ipod) < 0)
628 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
629 emit done(true);
630 return;
633 if (ipod.ipod_directory[0].entryOffset==0) {
634 m_dp->addItem(tr("No bootloader detected."),LOGERROR);
635 emit done(true);
636 return;
639 if (delete_bootloader(&ipod)==0)
641 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
642 emit done(false);
643 ipod_close(&ipod);
644 return;
646 else
648 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
649 emit done(true);
650 ipod_close(&ipod);
651 return;
656 void BootloaderInstaller::ipodFinish()
658 struct ipod_t ipod;
659 ipod_scan(&ipod);
661 if (ipod_open(&ipod, 0) < 0)
663 m_dp->addItem(tr("could not open ipod"),LOGERROR);
664 emit done(true);
665 return;
668 if (read_partinfo(&ipod,0) < 0)
670 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
671 emit done(true);
672 return;
675 if (ipod.pinfo[0].start==0)
677 m_dp->addItem(tr("No partition 0 on disk"),LOGERROR);
679 int i;
680 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
682 m_dp->addItem(tr("[INFO] Part Start Sector End Sector Size (MB) Type\n"),LOGINFO);
684 for ( i = 0; i < 4; i++ )
686 if (ipod.pinfo[i].start != 0)
688 m_dp->addItem(tr("[INFO] %1 %2 %3 %4 %5 (%6)").arg(
689 i).arg(
690 ipod.pinfo[i].start).arg(
691 ipod.pinfo[i].start+ipod.pinfo[i].size-1).arg(
692 ipod.pinfo[i].size/sectors_per_MB).arg(
693 get_parttype(ipod.pinfo[i].type)).arg(
694 ipod.pinfo[i].type),LOGWARNING);
697 emit done(true);
698 return;
701 read_directory(&ipod);
703 if (ipod.nimages <= 0)
705 m_dp->addItem(tr("Failed to read firmware directory"),LOGERROR);
706 emit done(true);
707 return;
709 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
711 m_dp->addItem(tr("Unknown version number in firmware (%1)").arg(
712 ipod.ipod_directory[0].vers),LOGERROR);
713 emit done(true);
714 return;
717 if (ipod.macpod)
719 m_dp->addItem(tr("Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod"),LOGWARNING);
722 if (ipod_reopen_rw(&ipod) < 0)
724 m_dp->addItem(tr("Could not open Ipod in RW mode"),LOGERROR);
725 emit done(true);
726 return;
729 if (add_bootloader(&ipod, m_tempfilename.toLatin1().data(), FILETYPE_DOT_IPOD)==0)
731 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
732 emit done(false);
733 ipod_close(&ipod);
734 return;
736 else
738 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
739 ipod_close(&ipod);
740 emit done(true);
741 return;
745 /**************************************************
746 *** sansa secific code
747 ***************************************************/
748 // reserves memory for sansapatcher
749 bool initSansapatcher()
751 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
752 else return false;
756 void BootloaderInstaller::sansaPrepare()
758 m_dp->addItem(tr("Searching for sansas"),LOGINFO);
759 struct sansa_t sansa;
761 int n = sansa_scan(&sansa);
762 if (n == 0)
764 m_dp->addItem(tr("No Sansa found"),LOGERROR);
765 emit done(true);
766 return;
768 if (n > 1)
770 m_dp->addItem(tr("Too many Sansas found"),LOGERROR);
771 emit done(true);
774 if(m_install) // Installation
776 QString url = m_bootloaderUrlBase + "/sandisk-sansa/e200/" + m_bootloadername;
778 m_dp->addItem(tr("Downloading file %1.%2")
779 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
781 // temporary file needs to be opened to get the filename
782 downloadFile.open();
783 m_tempfilename = downloadFile.fileName();
784 downloadFile.close();
785 // get the real file.
786 getter = new HttpGet(this);
787 getter->setProxy(m_proxy);
788 getter->setFile(&downloadFile);
789 getter->getFile(QUrl(url));
790 // connect signals from HttpGet
791 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
792 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
793 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
795 else // Uninstallation
798 if (sansa_open(&sansa, 0) < 0)
800 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
801 emit done(true);
802 return;
805 if (sansa_read_partinfo(&sansa,0) < 0)
807 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
808 emit done(true);
809 return;
812 int i = is_e200(&sansa);
813 if (i < 0) {
814 m_dp->addItem(tr("Disk is not an E200 (%1), aborting.").arg(i),LOGERROR);
815 emit done(true);
816 return;
819 if (sansa.hasoldbootloader)
821 m_dp->addItem(tr("********************************************\n"
822 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
823 "You must reinstall the original Sansa firmware before running\n"
824 "sansapatcher for the first time.\n"
825 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
826 "*********************************************\n"),LOGERROR);
827 emit done(true);
828 return;
832 if (sansa_reopen_rw(&sansa) < 0)
834 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
835 emit done(true);
836 return;
839 if (sansa_delete_bootloader(&sansa)==0)
841 m_dp->addItem(tr("Successfully removed Bootloader"),LOGOK);
842 emit done(false);
843 sansa_close(&sansa);
844 return;
846 else
848 m_dp->addItem(tr("--delete-bootloader failed."),LOGERROR);
849 emit done(true);
850 sansa_close(&sansa);
851 return;
856 void BootloaderInstaller::sansaFinish()
858 struct sansa_t sansa;
859 sansa_scan(&sansa);
861 if (sansa_open(&sansa, 0) < 0)
863 m_dp->addItem(tr("could not open Sansa"),LOGERROR);
864 emit done(true);
865 return;
868 if (sansa_read_partinfo(&sansa,0) < 0)
870 m_dp->addItem(tr("could not read partitiontable"),LOGERROR);
871 emit done(true);
872 return;
876 int i = is_e200(&sansa);
877 if (i < 0) {
879 m_dp->addItem(tr("Disk is not an E200 (%1), aborting.").arg(i),LOGERROR);
880 emit done(true);
881 return;
884 if (sansa.hasoldbootloader)
886 m_dp->addItem(tr("********************************************\n"
887 "OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
888 "You must reinstall the original Sansa firmware before running\n"
889 "sansapatcher for the first time.\n"
890 "See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
891 "*********************************************\n"),LOGERROR);
892 emit done(true);
893 return;
896 if (sansa_reopen_rw(&sansa) < 0)
898 m_dp->addItem(tr("Could not open Sansa in RW mode"),LOGERROR);
899 emit done(true);
900 return;
903 if (sansa_add_bootloader(&sansa, m_tempfilename.toLatin1().data(), FILETYPE_MI4)==0)
905 m_dp->addItem(tr("Successfully added Bootloader"),LOGOK);
906 emit done(false);
907 sansa_close(&sansa);
908 return;
910 else
912 m_dp->addItem(tr("failed to add Bootloader"),LOGERROR);
913 sansa_close(&sansa);
914 emit done(true);
915 return;
920 /**************************************************
921 *** iriver /fwpatcher secific code
922 ***************************************************/
924 void BootloaderInstaller::iriverPrepare()
926 char md5sum_str[32];
927 if (!FileMD5(m_origfirmware, md5sum_str)) {
928 m_dp->addItem(tr("Could not MD5Sum original firmware"),LOGERROR);
929 emit done(true);
930 return;
933 /* Check firmware against md5sums in h120sums and h100sums */
934 series = 0;
935 table_entry = intable(md5sum_str, &h120pairs[0],
936 sizeof(h120pairs)/sizeof(struct sumpairs));
937 if (table_entry >= 0) {
938 series = 120;
940 else
942 table_entry = intable(md5sum_str, &h100pairs[0],
943 sizeof(h100pairs)/sizeof(struct sumpairs));
944 if (table_entry >= 0)
946 series = 100;
948 else
950 table_entry = intable(md5sum_str, &h300pairs[0],
951 sizeof(h300pairs)/sizeof(struct sumpairs));
952 if (table_entry >= 0)
953 series = 300;
956 if (series == 0)
958 m_dp->addItem(tr("Could not detect firmware type"),LOGERROR);
959 emit done(true);
960 return;
963 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
965 m_dp->addItem(tr("Downloading file %1.%2")
966 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()),LOGINFO);
968 // temporary file needs to be opened to get the filename
969 downloadFile.open();
970 m_tempfilename = downloadFile.fileName();
971 downloadFile.close();
972 // get the real file.
973 getter = new HttpGet(this);
974 getter->setProxy(m_proxy);
975 getter->setFile(&downloadFile);
976 getter->getFile(QUrl(url));
977 // connect signals from HttpGet
978 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
979 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
980 connect(m_dp, SIGNAL(aborted()), getter, SLOT(abort()));
983 void BootloaderInstaller::iriverFinish()
985 // Patch firmware
986 char md5sum_str[32];
987 struct sumpairs *sums = 0;
988 int origin = 0;
990 /* get pointer to the correct bootloader.bin */
991 switch(series) {
992 case 100:
993 sums = &h100pairs[0];
994 origin = 0x1f0000;
995 break;
996 case 120:
997 sums = &h120pairs[0];
998 origin = 0x1f0000;
999 break;
1000 case 300:
1001 sums = &h300pairs[0];
1002 origin = 0x3f0000;
1003 break;
1006 // temporary files needs to be opened to get the filename
1007 QTemporaryFile firmwareBin, newBin, newHex;
1008 firmwareBin.open();
1009 newBin.open();
1010 newHex.open();
1011 QString firmwareBinName = firmwareBin.fileName();
1012 QString newBinName = newBin.fileName();
1013 QString newHexName = newHex.fileName();
1014 firmwareBin.close();
1015 newBin.close();
1016 newHex.close();
1018 // iriver decode
1019 if (iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE,m_dp) == -1)
1021 m_dp->addItem(tr("Error in descramble"),LOGERROR);
1022 firmwareBin.remove();
1023 newBin.remove();
1024 newHex.remove();
1025 emit done(true);
1026 return;
1028 // mkboot
1029 if (!mkboot(firmwareBinName, newBinName, m_tempfilename, origin,m_dp))
1031 m_dp->addItem(tr("Error in patching"),LOGERROR);
1032 firmwareBin.remove();
1033 newBin.remove();
1034 newHex.remove();
1035 emit done(true);
1036 return;
1038 // iriver_encode
1039 if (iriver_encode(newBinName, newHexName, FALSE,m_dp) == -1)
1041 m_dp->addItem(tr("Error in scramble"),LOGERROR);
1042 firmwareBin.remove();
1043 newBin.remove();
1044 newHex.remove();
1045 emit done(true);
1046 return;
1049 /* now md5sum it */
1050 if (!FileMD5(newHexName, md5sum_str))
1052 m_dp->addItem(tr("Error in checksumming"),LOGERROR);
1053 firmwareBin.remove();
1054 newBin.remove();
1055 newHex.remove();
1056 emit done(true);
1057 return;
1059 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1060 /* delete temp files */
1061 firmwareBin.remove();
1062 newBin.remove();
1065 // Load patched Firmware to player
1066 QString dest;
1067 if(series == 100)
1068 dest = m_mountpoint + "/ihp_100.hex";
1069 else if(series == 120)
1070 dest = m_mountpoint + "/ihp_120.hex";
1071 else if(series == 300)
1072 dest = m_mountpoint + "/H300.hex";
1073 // copy file
1074 if(!newHex.copy(dest))
1076 m_dp->addItem(tr("Could not copy: %1 to %2")
1077 .arg(newHexName,dest),LOGERROR);
1078 emit done(true);
1079 return;
1082 downloadFile.remove();
1083 newHex.remove();
1085 m_dp->addItem(tr("Bootloader install finished successfully."),LOGOK);
1086 m_dp->addItem(tr("To finish the Bootloader installation, follow the steps below."),LOGINFO);
1087 m_dp->addItem(tr("1. Eject/Unmount your Device."),LOGINFO);
1088 m_dp->addItem(tr("2. Boot into the original Firmware."),LOGINFO);
1089 m_dp->addItem(tr("3. Use the Firmware flash option in the Original Firmware."),LOGINFO);
1090 m_dp->addItem(tr("4. Reboot."),LOGINFO);
1091 m_dp->abort();
1093 emit done(false); // success