The credits file now also has underscores, which need to be escaped in LaTeX.
[Rockbox.git] / rbutil / bootloaders.cpp
blob039451f247be443fdd60416d8bb105c19046af6b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: bootloaders.cpp
11 * Copyright (C) 2007 Dominik Wenger
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
21 #include "bootloaders.h"
22 #include "irivertools.h"
23 #include "md5sum.h"
25 #include "rbutil.h"
26 #include "installlog.h"
29 int verbose =0;
30 // reserves memory for ipodpatcher
31 bool initIpodpatcher()
33 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
34 else return false;
36 // uses ipodpatcher for add and rem of bootloader
37 bool ipodpatcher(int mode,wxString bootloadername)
39 wxString src,dest,buf;
41 struct ipod_t ipod;
43 int n = ipod_scan(&ipod);
44 if (n == 0)
46 ERR_DIALOG(wxT("[ERR] No ipods found."), wxT("Scanning for Ipods"));
47 return false;
49 if (n > 1)
51 ERR_DIALOG(wxT("[ERR] to many ipods found."), wxT("Scanning for Ipods"));
52 return false;
55 // downloading files
56 if(mode == BOOTLOADER_ADD)
58 src.Printf(wxT("%s/ipod/%s.ipod"),gv->bootloader_url.c_str(),bootloadername.c_str());
59 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
60 gv->stdpaths->GetUserDataDir().c_str(),bootloadername.c_str());
61 if ( DownloadURL(src, dest) )
63 wxRemoveFile(dest);
64 buf.Printf(wxT("Unable to download %s"), src.c_str() );
65 ERR_DIALOG(buf, wxT("Install"));
66 return false;
70 if (ipod_open(&ipod, 0) < 0)
72 ERR_DIALOG(wxT("[ERR] could not open ipod"), wxT("open Ipod"));
73 return false;
76 if (read_partinfo(&ipod,0) < 0)
78 ERR_DIALOG(wxT("[ERR] could not read partitiontable"), wxT("reading partitiontable"));
79 return false;
82 if (ipod.pinfo[0].start==0)
84 ERR_DIALOG(wxT("[ERR] No partition 0 on disk"), wxT("reading partitiontable"));
85 int i;
86 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
88 buf.Printf(wxT("[INFO] Part Start Sector End Sector Size (MB) Type\n"));
89 ERR_DIALOG(buf, wxT("reading partitiontable"));
90 for ( i = 0; i < 4; i++ ) {
91 if (ipod.pinfo[i].start != 0) {
92 buf.Printf(wxT("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n"),
94 ipod.pinfo[i].start,
95 ipod.pinfo[i].start+ipod.pinfo[i].size-1,
96 ipod.pinfo[i].size/sectors_per_MB,
97 get_parttype(ipod.pinfo[i].type),
98 ipod.pinfo[i].type);
99 ERR_DIALOG(buf, wxT("reading partitiontable"));
102 return false;
105 read_directory(&ipod);
107 if (ipod.nimages <= 0)
109 ERR_DIALOG(wxT("[ERR] Failed to read firmware directory"), wxT("reading directory"));
110 return false;
112 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
114 buf.Printf(wxT("[ERR] Unknown version number in firmware (%08x)\n"),
115 ipod.ipod_directory[0].vers );
116 ERR_DIALOG(buf, wxT("reading directory"));
117 return false;
120 if (ipod.macpod)
122 WARN_DIALOG(wxT("Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod"),wxT("MacPod"));
126 if(mode == BOOTLOADER_ADD)
128 if (ipod_reopen_rw(&ipod) < 0) {
129 ERR_DIALOG(wxT("[ERR] Could not open Ipod in RW mode"), wxT("Bootloader add"));
130 return false;
133 if (add_bootloader(&ipod, (char*)dest.c_str(), FILETYPE_DOT_IPOD)==0) {
135 } else {
136 ERR_DIALOG(wxT("[ERR] failed to add Bootloader"), wxT("Bootloader add"));
137 return false;
140 else if(mode == BOOTLOADER_REM)
142 if (ipod_reopen_rw(&ipod) < 0) {
143 ERR_DIALOG(wxT("[ERR] Could not open Ipod in RW mode"), wxT("Bootloader add"));
144 return false;
147 if (ipod.ipod_directory[0].entryOffset==0) {
148 ERR_DIALOG(wxT("[ERR] No bootloader detected.\n"), wxT("Bootloader del"));
149 return false;
150 } else {
151 if (delete_bootloader(&ipod)==0) {
153 } else {
154 ERR_DIALOG(wxT("[ERR] --delete-bootloader failed.\n"), wxT("Bootloader del"));
155 return false;
160 ipod_close(&ipod);
161 return true;
164 // reserves memory for sansapatcher
165 bool initSansaPatcher()
167 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
168 else return false;
172 // sansainstallation
173 bool sansapatcher(int mode,wxString bootloadername)
175 wxString src,dest,buf;
177 struct sansa_t sansa;
179 int n = sansa_scan(&sansa);
180 if (n == 0)
182 ERR_DIALOG(wxT("[ERR] No Sansa found."), wxT("Scanning for Sansa"));
183 return false;
185 if (n > 1)
187 ERR_DIALOG(wxT("[ERR] to many Sansa found."), wxT("Scanning for Sansa"));
188 return false;
191 // downloading files
192 if(mode == BOOTLOADER_ADD)
194 src.Printf(wxT("%s/sandisk-sansa/e200/%s"),gv->bootloader_url.c_str(),bootloadername.c_str());
195 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
196 gv->stdpaths->GetUserDataDir().c_str(),bootloadername.c_str());
197 if ( DownloadURL(src, dest) )
199 wxRemoveFile(dest);
200 buf.Printf(wxT("Unable to download %s"), src.c_str() );
201 ERR_DIALOG(buf, wxT("Download"));
202 return false;
206 if (sansa_open(&sansa, 0) < 0)
208 ERR_DIALOG(wxT("[ERR] could not open sansa"), wxT("open Sansa"));
209 return false;
212 if (sansa_read_partinfo(&sansa,0) < 0)
214 ERR_DIALOG(wxT("[ERR] could not read partitiontable"), wxT("reading partitiontable"));
215 return false;
218 int i = is_e200(&sansa);
219 if (i < 0) {
220 ERR_DIALOG(wxT("[ERR] Disk is not an E200 (%d), aborting.\n"), wxT("Checking Disk"));
221 return false;
224 if (sansa.hasoldbootloader)
226 ERR_DIALOG(wxT("[ERR] ************************************************************************\n"
227 "[ERR] *** OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
228 "[ERR] *** You must reinstall the original Sansa firmware before running\n"
229 "[ERR] *** sansapatcher for the first time.\n"
230 "[ERR] *** See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
231 "[ERR] ************************************************************************\n"),wxT("Checking Disk"));
232 return false;
235 if(mode == BOOTLOADER_ADD)
237 if (sansa_reopen_rw(&sansa) < 0) {
238 ERR_DIALOG(wxT("[ERR] Could not open Sansa in RW mode"), wxT("Bootloader add"));
239 return false;
242 if (sansa_add_bootloader(&sansa, (char*)dest.c_str(), FILETYPE_MI4)==0) {
244 } else {
245 ERR_DIALOG(wxT("[ERR] failed to add Bootloader"), wxT("Bootloader add"));
249 else if(mode == BOOTLOADER_REM)
251 if (sansa_reopen_rw(&sansa) < 0) {
252 ERR_DIALOG(wxT("[ERR] Could not open Sansa in RW mode"), wxT("Bootloader Remove"));
255 if (sansa_delete_bootloader(&sansa)==0) {
257 } else {
258 ERR_DIALOG(wxT("[ERR] failed to remove Bootloader"), wxT("Bootloader remove"));
262 sansa_close(&sansa);
263 return true;
266 // gigabeatinstallation
267 bool gigabeatf(int mode,wxString bootloadername,wxString deviceDir)
269 wxString path1,path2;
270 wxString err;
271 wxString src,dest;
273 path1.Printf(wxT("%s" PATH_SEP "GBSYSTEM" PATH_SEP "FWIMG" PATH_SEP "FWIMG01.DAT"),deviceDir.c_str());
275 if(mode == BOOTLOADER_ADD)
277 //Files downloaden
278 src.Printf(wxT("%s/gigabeat/%s"), gv->bootloader_url.c_str(),bootloadername.c_str());
279 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
280 gv->stdpaths->GetUserDataDir().c_str(),bootloadername.c_str());
281 if( DownloadURL(src, dest) )
283 wxRemoveFile(dest);
284 err.Printf(wxT("Unable to download %s"), src.c_str() );
285 ERR_DIALOG(err, wxT("Install"));
286 return false;
290 if(!wxFileExists(path1))
292 err.Printf(wxT("[ERR] Coud not find %s"),path1.c_str());
293 ERR_DIALOG(err, wxT("Bootloader add"));
294 return false;
296 path2 = path1;
297 path2.Append(wxT(".ORIG"));
298 if(!wxFileExists(path2))
300 if(!wxRenameFile(path1,path2,false))
302 err.Printf(wxT("[ERR] Coud not rename %s to %s"),path1.c_str(),path2.c_str());
303 ERR_DIALOG(err, wxT("Bootloader add"));
304 return false;
309 if(!wxCopyFile(dest,path1))
311 err.Printf(wxT("[ERR] Coud not copy %s to %s"),dest.c_str(),path2.c_str());
312 ERR_DIALOG(err, wxT("Bootloader add"));
313 return false;
316 else if(mode == BOOTLOADER_REM)
318 path2 = path1;
319 path2.Append(wxT(".ORIG"));
320 if(!wxFileExists(path2))
322 err.Printf(wxT("[ERR] Coud not find %s"),path1.c_str());
323 ERR_DIALOG(err, wxT("Bootloader del"));
324 return false;
326 if(!wxRenameFile(path2,path1,true))
328 err.Printf(wxT("[ERR] Coud not rename %s to %s"),path1.c_str(),path2.c_str());
329 ERR_DIALOG(err, wxT("Bootloader del"));
330 return false;
333 return true;
336 // iaudio bootloader install
337 bool iaudiox5(int mode,wxString bootloadername,wxString deviceDir)
339 wxString path1,path2;
340 wxString err;
341 wxString src,dest;
343 path1.Printf(wxT("%s" PATH_SEP "FIRMWARE" PATH_SEP "%s"),deviceDir.c_str(),bootloadername.c_str());
345 if(mode == BOOTLOADER_ADD)
347 //Files downloaden
348 src.Printf(wxT("%s/iaudio/%s"),gv->bootloader_url.c_str(),bootloadername.c_str());
349 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
350 gv->stdpaths->GetUserDataDir().c_str(),bootloadername.c_str());
351 if( DownloadURL(src, dest) )
353 wxRemoveFile(dest);
354 err.Printf(wxT("Unable to download %s"), src.c_str() );
355 ERR_DIALOG(err, wxT("Install"));
356 return false;
359 // copy file
360 if(!wxCopyFile(dest,path1))
362 err.Printf(wxT("[ERR] Coud not copy %s to %s"),dest.c_str(),path2.c_str());
363 ERR_DIALOG(err, wxT("Bootloader add"));
364 return false;
367 return true; // install ready
369 else
370 return false; //no uninstallation possible
373 // H10 install
374 bool h10(int mode,wxString bootloadername,wxString deviceDir)
376 wxString err,src,dest,path1,path2;
378 int pos = bootloadername.Find('/');
379 if(pos == wxNOT_FOUND) pos = 0;
380 wxString firmwarename = bootloadername.SubString(pos,bootloadername.Length());
381 //wxString firmDir = gv->curbootloader.SubString(0,pos);
383 if(mode == BOOTLOADER_ADD)
385 //Files downloaden
386 src.Printf(wxT("%s/iriver/%s"), gv->bootloader_url.c_str(),bootloadername.c_str());
387 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
388 gv->stdpaths->GetUserDataDir().c_str(),firmwarename.c_str());
389 if( DownloadURL(src, dest) )
391 wxRemoveFile(dest);
392 err.Printf(wxT("Unable to download %s"), src.c_str() );
393 ERR_DIALOG(err, wxT("Install"));
394 return false;
397 path1.Printf(wxT("%sSYSTEM" PATH_SEP "%s"),deviceDir.c_str(),firmwarename.c_str());
398 path2.Printf(wxT("%sSYSTEM" PATH_SEP "Original.mi4"),deviceDir.c_str());
400 if(!wxFileExists(path1)) //Firmware dosent exists on player
402 path1.Printf(wxT("%sSYSTEM" PATH_SEP "H10EMP.mi4"),deviceDir.c_str()); //attempt other firmwarename
403 if(!wxFileExists(path1)) //Firmware dosent exists on player
405 err.Printf(wxT("[ERR] File %s does not Exist"),path1.c_str());
406 ERR_DIALOG(err, wxT("Bootloader add"));
407 return false;
410 if(!wxFileExists(path2)) //there is already a original firmware
412 if(!wxRenameFile(path1,path2,false)) //rename Firmware to Original
414 err.Printf(wxT("[ERR] Coud not rename %s to %s"),path1.c_str(),path2.c_str());
415 ERR_DIALOG(err, wxT("Bootloader add"));
416 return false;
420 if(!wxCopyFile(dest,path1)) // copy file
422 err.Printf(wxT("[ERR] Coud not copy %s to %s"),dest.c_str(),path1.c_str());
423 ERR_DIALOG(err,wxT("Bootloader add"));
424 return false;
427 return true; //install ready
430 else if(mode == BOOTLOADER_REM)
432 path1.Printf(wxT("%sSYSTEM" PATH_SEP "%s"),deviceDir.c_str(),firmwarename.c_str());
433 path2.Printf(wxT("%sSYSTEM" PATH_SEP "Original.mi4"),gv->curdestdir.c_str());
434 if(!wxFileExists(path1)) //Firmware dosent exists on player
436 path1.Printf(wxT("%s" PATH_SEP "SYSTEM" PATH_SEP "H10EMP.mi4"),deviceDir.c_str()); //attempt other firmwarename
437 if(!wxFileExists(path1)) //Firmware dosent exists on player
439 err.Printf(wxT("[ERR] File %s does not Exist"),path1.c_str());
440 ERR_DIALOG(err, wxT("Bootloader rem"));
441 return false;
445 if(!wxFileExists(path2)) //Original Firmware dosent exists on player
447 err.Printf(wxT("[ERR] File %s does not Exist"),path2.c_str());
448 ERR_DIALOG(err, wxT("Bootloader rem"));
449 return false;
452 if(!wxRenameFile(path2,path1,true)) //rename Firmware to Original
454 err.Printf(wxT("[ERR] Coud not rename %s to %s"),path2.c_str(),path1.c_str());
455 ERR_DIALOG(err, wxT("Bootloader add"));
456 return false;
460 // shouldn't get here
461 return false;
464 // FWPatcher
465 bool fwpatcher(int mode,wxString bootloadername,wxString deviceDir,wxString firmware)
467 if(mode == BOOTLOADER_ADD)
469 char md5sum_str[32];
470 wxString src,dest,err;
471 int series,table_entry;
473 if (!FileMD5(firmware, md5sum_str)) {
474 ERR_DIALOG(wxT("Could not open firmware"), wxT("Open Firmware"));
475 return false;
477 else {
478 /* Check firmware against md5sums in h120sums and h100sums */
479 series = 0;
480 table_entry = intable(md5sum_str, &h120pairs[0],
481 sizeof(h120pairs)/sizeof(struct sumpairs));
482 if (table_entry >= 0) {
483 series = 120;
485 else {
486 table_entry = intable(md5sum_str, &h100pairs[0],
487 sizeof(h100pairs)/sizeof(struct sumpairs));
488 if (table_entry >= 0) {
489 series = 100;
491 else {
492 table_entry =
493 intable(md5sum_str, &h300pairs[0],
494 sizeof(h300pairs)/sizeof(struct sumpairs));
495 if (table_entry >= 0)
496 series = 300;
499 if (series == 0) {
500 ERR_DIALOG(wxT("Could not detect firmware type"), wxT("Detect Player out of Firmware"));
501 return false;
503 else
505 //Download bootloader
506 src.Printf(wxT("%s/iriver/%s"), gv->bootloader_url.c_str(),bootloadername.c_str());
507 dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "%s"),
508 gv->stdpaths->GetUserDataDir().c_str(),bootloadername.c_str());
509 if( DownloadURL(src, dest) )
511 wxRemoveFile(dest);
512 err.Printf(wxT("Unable to download %s"), src.c_str() );
513 ERR_DIALOG(err, wxT("Install"));
514 return false;
517 if(!PatchFirmware(firmware,dest,series, table_entry)) // Patch firmware
519 ERR_DIALOG(wxT("Patching Firmware failed"), wxT("Patching Firmware"));
520 return false;
524 // Load patched Firmware to player
525 src.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "new.hex"),
526 gv->stdpaths->GetUserDataDir().c_str());
528 if(gv->curplat == wxT("h100"))
529 dest.Printf(wxT("%s" PATH_SEP "ihp_100.hex"),deviceDir.c_str());
530 else if(gv->curplat == wxT("h120"))
531 dest.Printf(wxT("%s" PATH_SEP "ihp_120.hex"),deviceDir.c_str());
532 else if(gv->curplat == wxT("h300"))
533 dest.Printf(wxT("%s" PATH_SEP "H300.hex"),deviceDir.c_str());
535 if(!wxRenameFile(src,dest))
537 ERR_DIALOG(wxT("Copying Firmware to Device failed"), wxT("Copying Firmware"));
538 return false;
540 else
542 return true;
547 else
549 return false; //no uninstall possible