- fix an endless autodetection loop when no user configuration is present
[Rockbox.git] / rbutil / bootloaders.cpp
blob4ac4828307c8b797943421392fdeb04020b7d73a
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"
25 int verbose =0;
26 // reserves memory for ipodpatcher
27 bool initIpodpatcher()
29 if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
30 else return false;
32 // uses ipodpatcher for add and rem of bootloader
33 bool ipodpatcher(int mode,wxString bootloadername)
35 wxString src,dest,buf;
37 struct ipod_t ipod;
39 int n = ipod_scan(&ipod);
40 if (n == 0)
42 ERR_DIALOG(wxT("[ERR] No ipods found."), wxT("Scanning for Ipods"));
43 return false;
45 if (n > 1)
47 ERR_DIALOG(wxT("[ERR] to many ipods found."), wxT("Scanning for Ipods"));
48 return false;
51 // downloading files
52 if(mode == BOOTLOADER_ADD)
54 src = gv->bootloader_url + wxT("/ipod/")
55 + bootloadername + wxT(".ipod");
56 dest = gv->stdpaths->GetUserDataDir()
57 + wxT("" PATH_SEP "download" PATH_SEP) + bootloadername;
58 if ( DownloadURL(src, dest) )
60 wxRemoveFile(dest);
61 ERR_DIALOG(wxT("Unable to download ") + src, wxT("Install"));
62 return false;
66 if (ipod_open(&ipod, 0) < 0)
68 ERR_DIALOG(wxT("[ERR] could not open ipod"), wxT("open Ipod"));
69 return false;
72 if (read_partinfo(&ipod,0) < 0)
74 ERR_DIALOG(wxT("[ERR] could not read partitiontable"), wxT("reading partitiontable"));
75 return false;
78 if (ipod.pinfo[0].start==0)
80 ERR_DIALOG(wxT("[ERR] No partition 0 on disk"), wxT("reading partitiontable"));
81 int i;
82 double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size;
84 buf.Printf(wxT("[INFO] Part Start Sector End Sector Size (MB) Type\n"));
85 ERR_DIALOG(buf, wxT("reading partitiontable"));
86 for ( i = 0; i < 4; i++ ) {
87 if (ipod.pinfo[i].start != 0) {
88 buf.Printf(wxT("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n"),
90 ipod.pinfo[i].start,
91 ipod.pinfo[i].start+ipod.pinfo[i].size-1,
92 ipod.pinfo[i].size/sectors_per_MB,
93 get_parttype(ipod.pinfo[i].type),
94 ipod.pinfo[i].type);
95 ERR_DIALOG(buf, wxT("reading partitiontable"));
98 return false;
101 read_directory(&ipod);
103 if (ipod.nimages <= 0)
105 ERR_DIALOG(wxT("[ERR] Failed to read firmware directory"), wxT("reading directory"));
106 return false;
108 if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0)
110 buf.Printf(wxT("[ERR] Unknown version number in firmware (%08x)\n"),
111 ipod.ipod_directory[0].vers );
112 ERR_DIALOG(buf, wxT("reading directory"));
113 return false;
116 if (ipod.macpod)
118 WARN_DIALOG(wxT("Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod"),wxT("MacPod"));
122 if(mode == BOOTLOADER_ADD)
124 if (ipod_reopen_rw(&ipod) < 0) {
125 ERR_DIALOG(wxT("[ERR] Could not open Ipod in RW mode"), wxT("Bootloader add"));
126 return false;
129 if (add_bootloader(&ipod, (char*)dest.c_str(), FILETYPE_DOT_IPOD)==0) {
131 } else {
132 ERR_DIALOG(wxT("[ERR] failed to add Bootloader"), wxT("Bootloader add"));
133 return false;
136 else if(mode == BOOTLOADER_REM)
138 if (ipod_reopen_rw(&ipod) < 0) {
139 ERR_DIALOG(wxT("[ERR] Could not open Ipod in RW mode"), wxT("Bootloader add"));
140 return false;
143 if (ipod.ipod_directory[0].entryOffset==0) {
144 ERR_DIALOG(wxT("[ERR] No bootloader detected.\n"), wxT("Bootloader del"));
145 return false;
146 } else {
147 if (delete_bootloader(&ipod)==0) {
149 } else {
150 ERR_DIALOG(wxT("[ERR] --delete-bootloader failed.\n"), wxT("Bootloader del"));
151 return false;
156 ipod_close(&ipod);
157 return true;
160 // reserves memory for sansapatcher
161 bool initSansaPatcher()
163 if (sansa_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) return true;
164 else return false;
168 // sansainstallation
169 bool sansapatcher(int mode,wxString bootloadername)
171 wxString src,dest,buf;
173 struct sansa_t sansa;
175 int n = sansa_scan(&sansa);
176 if (n == 0)
178 ERR_DIALOG(wxT("[ERR] No Sansa found."), wxT("Scanning for Sansa"));
179 return false;
181 if (n > 1)
183 ERR_DIALOG(wxT("[ERR] to many Sansa found."), wxT("Scanning for Sansa"));
184 return false;
187 // downloading files
188 if(mode == BOOTLOADER_ADD)
190 src = gv->bootloader_url + wxT("/sandisk-sansa/e200/")
191 + bootloadername;
192 dest = gv->stdpaths->GetUserDataDir()
193 + wxT("" PATH_SEP "download" PATH_SEP) + bootloadername;
194 if ( DownloadURL(src, dest) )
196 wxRemoveFile(dest);
197 ERR_DIALOG(wxT("Unable to download ") + src, wxT("Download"));
198 return false;
202 if (sansa_open(&sansa, 0) < 0)
204 ERR_DIALOG(wxT("[ERR] could not open sansa"), wxT("open Sansa"));
205 return false;
208 if (sansa_read_partinfo(&sansa,0) < 0)
210 ERR_DIALOG(wxT("[ERR] could not read partitiontable"), wxT("reading partitiontable"));
211 return false;
214 int i = is_e200(&sansa);
215 if (i < 0) {
216 ERR_DIALOG(wxT("[ERR] Disk is not an E200 (%d), aborting.\n"), wxT("Checking Disk"));
217 return false;
220 if (sansa.hasoldbootloader)
222 ERR_DIALOG(wxT("[ERR] ************************************************************************\n"
223 "[ERR] *** OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
224 "[ERR] *** You must reinstall the original Sansa firmware before running\n"
225 "[ERR] *** sansapatcher for the first time.\n"
226 "[ERR] *** See http://www.rockbox.org/twiki/bin/view/Main/SansaE200Install\n"
227 "[ERR] ************************************************************************\n"),wxT("Checking Disk"));
228 return false;
231 if(mode == BOOTLOADER_ADD)
233 if (sansa_reopen_rw(&sansa) < 0) {
234 ERR_DIALOG(wxT("[ERR] Could not open Sansa in RW mode"), wxT("Bootloader add"));
235 return false;
238 if (sansa_add_bootloader(&sansa, (char*)dest.c_str(), FILETYPE_MI4)==0) {
240 } else {
241 ERR_DIALOG(wxT("[ERR] failed to add Bootloader"), wxT("Bootloader add"));
245 else if(mode == BOOTLOADER_REM)
247 if (sansa_reopen_rw(&sansa) < 0) {
248 ERR_DIALOG(wxT("[ERR] Could not open Sansa in RW mode"), wxT("Bootloader Remove"));
251 if (sansa_delete_bootloader(&sansa)==0) {
253 } else {
254 ERR_DIALOG(wxT("[ERR] failed to remove Bootloader"), wxT("Bootloader remove"));
258 sansa_close(&sansa);
259 return true;
262 // gigabeatinstallation
263 bool gigabeatf(int mode,wxString bootloadername,wxString deviceDir)
265 wxString path1,path2;
266 wxString err;
267 wxString src,dest;
269 path1 = deviceDir
270 + wxT("" PATH_SEP "GBSYSTEM" PATH_SEP "FWIMG" PATH_SEP "FWIMG01.DAT");
272 if(mode == BOOTLOADER_ADD)
274 //Files downloaden
275 src = gv->bootloader_url + wxT("/gigabeat/") + bootloadername;
276 dest = gv->stdpaths->GetUserDataDir()
277 + wxT("" PATH_SEP "download" PATH_SEP) + bootloadername;
278 if( DownloadURL(src, dest) )
280 wxRemoveFile(dest);
281 ERR_DIALOG(wxT("Unable to download ") + src, wxT("Install"));
282 return false;
286 if(!wxFileExists(path1))
288 ERR_DIALOG(wxT("[ERR] Coud not find ")+path1, wxT("Bootloader add"));
289 return false;
291 path2 = path1;
292 path2.Append(wxT(".ORIG"));
293 if(!wxFileExists(path2))
295 if(!wxRenameFile(path1,path2,false))
297 ERR_DIALOG(wxT("[ERR] Coud not rename ") + path1 + wxT(" to ")
298 + path2, wxT("Bootloader add"));
299 return false;
304 if(!wxCopyFile(dest,path1))
306 ERR_DIALOG(wxT("[ERR] Coud not copy ") + dest + wxT(" to ")
307 + path2, wxT("Bootloader add"));
308 return false;
311 else if(mode == BOOTLOADER_REM)
313 path2 = path1;
314 path2.Append(wxT(".ORIG"));
315 if(!wxFileExists(path2))
317 ERR_DIALOG(wxT("[ERR] Coud not find ") + path1,
318 wxT("Bootloader del"));
319 return false;
321 if(!wxRenameFile(path2,path1,true))
323 ERR_DIALOG(wxT("[ERR] Coud not rename ") + path1 + wxT(" to ")
324 + path2, wxT("Bootloader del"));
325 return false;
328 return true;
331 // iaudio bootloader install
332 bool iaudiox5(int mode,wxString bootloadername,wxString deviceDir)
334 wxString path1,path2;
335 wxString err;
336 wxString src,dest;
338 path1 = deviceDir + wxT("" PATH_SEP "FIRMWARE" PATH_SEP)
339 + bootloadername;
341 if(mode == BOOTLOADER_ADD)
343 //Files downloaden
344 src = gv->bootloader_url + wxT("/iaudio/") + bootloadername;
345 dest = gv->stdpaths->GetUserDataDir()
346 + wxT("" PATH_SEP "download" PATH_SEP) + bootloadername;
347 if( DownloadURL(src, dest) )
349 wxRemoveFile(dest);
350 ERR_DIALOG(wxT("Unable to download ") + src, wxT("Install"));
351 return false;
354 // copy file
355 if(!wxCopyFile(dest,path1))
357 ERR_DIALOG(wxT("[ERR] Coud not copy ")+dest+wxT(" to ")+path2,
358 wxT("Bootloader add"));
359 return false;
362 return true; // install ready
364 else
365 return false; //no uninstallation possible
368 // H10 install
369 bool h10(int mode,wxString bootloadername,wxString deviceDir)
371 wxString err,src,dest,path1,path2;
373 int pos = bootloadername.Find('/');
374 if(pos == wxNOT_FOUND) pos = 0;
375 wxString firmwarename = bootloadername.SubString(pos,bootloadername.Length());
376 //wxString firmDir = gv->curbootloader.SubString(0,pos);
378 if(mode == BOOTLOADER_ADD)
380 //Files downloaden
381 src = gv->bootloader_url + wxT("/iriver/") + bootloadername;
382 dest = gv->stdpaths->GetUserDataDir()
383 + wxT("" PATH_SEP "download" PATH_SEP) + firmwarename;
384 if( DownloadURL(src, dest) )
386 wxRemoveFile(dest);
387 ERR_DIALOG(wxT("Unable to download ") + src, wxT("Install"));
388 return false;
391 path1 = deviceDir + wxT("SYSTEM" PATH_SEP) + firmwarename;
392 path2 = deviceDir + wxT("SYSTEM" PATH_SEP "Original.mi4");
394 if(!wxFileExists(path1)) //Firmware dosent exists on player
396 path1 = deviceDir + wxT("SYSTEM" PATH_SEP "H10EMP.mi4"); //attempt other firmwarename
397 if(!wxFileExists(path1)) //Firmware dosent exists on player
399 ERR_DIALOG(wxT("[ERR] File ") + path1 + wxT(" does not Exist"),
400 wxT("Bootloader add"));
401 return false;
404 if(!wxFileExists(path2)) //there is already a original firmware
406 if(!wxRenameFile(path1,path2,false)) //rename Firmware to Original
408 ERR_DIALOG(wxT("[ERR] Coud not rename ") + path1 + wxT(" to ")
409 + path2, wxT("Bootloader add"));
410 return false;
414 if(!wxCopyFile(dest,path1)) // copy file
416 ERR_DIALOG(wxT("[ERR] Coud not copy ") + dest + wxT(" to ") + path1,
417 wxT("Bootloader add"));
418 return false;
421 return true; //install ready
424 else if(mode == BOOTLOADER_REM)
426 path1 = deviceDir + wxT("SYSTEM" PATH_SEP) + firmwarename;
427 path2 = gv->curdestdir + wxT("SYSTEM" PATH_SEP "Original.mi4");
428 if(!wxFileExists(path1)) //Firmware dosent exists on player
430 path1 = deviceDir + wxT("" PATH_SEP "SYSTEM" PATH_SEP "H10EMP.mi4"); //attempt other firmwarename
431 if(!wxFileExists(path1)) //Firmware dosent exists on player
433 ERR_DIALOG(wxT("[ERR] File ") + path1 + wxT(" does not Exist"),
434 wxT("Bootloader rem"));
435 return false;
439 if(!wxFileExists(path2)) //Original Firmware dosent exists on player
441 ERR_DIALOG(wxT("[ERR] File ") + path2 + wxT(" does not Exist"),
442 wxT("Bootloader rem"));
443 return false;
446 if(!wxRenameFile(path2,path1,true)) //rename Firmware to Original
448 ERR_DIALOG(wxT("[ERR] Coud not rename ") + path2 + wxT(" to ")
449 + path1, wxT("Bootloader add"));
450 return false;
454 // shouldn't get here
455 return false;
458 // FWPatcher
459 bool fwpatcher(int mode,wxString bootloadername,wxString deviceDir,wxString firmware)
461 if(mode == BOOTLOADER_ADD)
463 char md5sum_str[32];
464 wxString src,dest,err;
465 int series,table_entry;
467 if (!FileMD5(firmware, md5sum_str)) {
468 ERR_DIALOG(wxT("Could not open firmware"), wxT("Open Firmware"));
469 return false;
471 else {
472 /* Check firmware against md5sums in h120sums and h100sums */
473 series = 0;
474 table_entry = intable(md5sum_str, &h120pairs[0],
475 sizeof(h120pairs)/sizeof(struct sumpairs));
476 if (table_entry >= 0) {
477 series = 120;
479 else {
480 table_entry = intable(md5sum_str, &h100pairs[0],
481 sizeof(h100pairs)/sizeof(struct sumpairs));
482 if (table_entry >= 0) {
483 series = 100;
485 else {
486 table_entry =
487 intable(md5sum_str, &h300pairs[0],
488 sizeof(h300pairs)/sizeof(struct sumpairs));
489 if (table_entry >= 0)
490 series = 300;
493 if (series == 0) {
494 ERR_DIALOG(wxT("Could not detect firmware type"), wxT("Detect Player out of Firmware"));
495 return false;
497 else
499 //Download bootloader
500 src = gv->bootloader_url + wxT("/iriver/")
501 + bootloadername;
502 dest = gv->stdpaths->GetUserDataDir()
503 + wxT("" PATH_SEP "download" PATH_SEP)
504 + bootloadername;
505 if( DownloadURL(src, dest) )
507 wxRemoveFile(dest);
508 ERR_DIALOG(wxT("Unable to download ") + src,
509 wxT("Install"));
510 return false;
513 if(!PatchFirmware(firmware,dest,series, table_entry)) // Patch firmware
515 ERR_DIALOG(wxT("Patching Firmware failed"),
516 wxT("Patching Firmware"));
517 return false;
521 // Load patched Firmware to player
522 src = gv->stdpaths->GetUserDataDir()
523 + wxT("" PATH_SEP "download" PATH_SEP "new.hex");
525 if(gv->curplat == wxT("h100"))
526 dest = deviceDir + wxT("" PATH_SEP "ihp_100.hex");
527 else if(gv->curplat == wxT("h120"))
528 dest = deviceDir + wxT("" PATH_SEP "ihp_120.hex");
529 else if(gv->curplat == wxT("h300"))
530 dest = deviceDir + wxT("" PATH_SEP "H300.hex");
532 if(!wxRenameFile(src,dest))
534 ERR_DIALOG(wxT("Copying Firmware to Device failed"),
535 wxT("Copying Firmware"));
536 return false;
538 else
540 return true;
545 else
547 return false; //no uninstall possible