summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-07-27 20:51:36 +0000
committerDave Chapman <dave@dchapman.com>2007-07-27 20:51:36 +0000
commit35735c66e00df7951df57e81792f9fdd4823d34e (patch)
tree6e9db387d3b4be87bf31053f4920685cb52f05e2
parent018d55599571d118ef682f81c3fc7ab2f4534b40 (diff)
downloadrockbox-35735c66e00df7951df57e81792f9fdd4823d34e.tar.gz
rockbox-35735c66e00df7951df57e81792f9fdd4823d34e.zip
Initial attempt at a --convert option to convert HFS formatted ipods (Macpods) to FAT32 format. This needs testing (as well as the existing --format feature) before adding as an option in the interactive mode and fully documenting.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14030 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--rbutil/ipodpatcher/ipodio.h6
-rw-r--r--rbutil/ipodpatcher/ipodpatcher.c59
-rw-r--r--rbutil/ipodpatcher/ipodpatcher.h1
-rw-r--r--rbutil/ipodpatcher/main.c45
4 files changed, 102 insertions, 9 deletions
diff --git a/rbutil/ipodpatcher/ipodio.h b/rbutil/ipodpatcher/ipodio.h
index dadb5f8ad4..a4625f7bc7 100644
--- a/rbutil/ipodpatcher/ipodio.h
+++ b/rbutil/ipodpatcher/ipodio.h
@@ -53,9 +53,9 @@ struct ipod_directory_t {
53}; 53};
54 54
55struct partinfo_t { 55struct partinfo_t {
56 unsigned long start; /* first sector (LBA) */ 56 uint32_t start; /* first sector (LBA) */
57 unsigned long size; /* number of sectors */ 57 uint32_t size; /* number of sectors */
58 int type; 58 uint32_t type;
59}; 59};
60 60
61struct ipod_t { 61struct ipod_t {
diff --git a/rbutil/ipodpatcher/ipodpatcher.c b/rbutil/ipodpatcher/ipodpatcher.c
index 395fd6953d..567c5b9cce 100644
--- a/rbutil/ipodpatcher/ipodpatcher.c
+++ b/rbutil/ipodpatcher/ipodpatcher.c
@@ -171,6 +171,8 @@ int read_partinfo(struct ipod_t* ipod, int silent)
171 return -1; 171 return -1;
172 } 172 }
173 173
174 memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
175
174 if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) { 176 if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
175 /* DOS partition table */ 177 /* DOS partition table */
176 ipod->macpod = 0; 178 ipod->macpod = 0;
@@ -1289,3 +1291,60 @@ int ipod_scan(struct ipod_t* ipod)
1289 } 1291 }
1290 return n; 1292 return n;
1291} 1293}
1294
1295static void put_int32le(uint32_t x, unsigned char* p)
1296{
1297 p[0] = x & 0xff;
1298 p[1] = (x >> 8) & 0xff;
1299 p[2] = (x >> 16) & 0xff;
1300 p[3] = (x >> 24) & 0xff;
1301}
1302
1303int write_dos_partition_table(struct ipod_t* ipod)
1304{
1305 unsigned char* p;
1306 int i, n;
1307 uint32_t type;
1308
1309 /* Only support 512-byte sectors at the moment */
1310 if ( ipod->sector_size != 512 )
1311 {
1312 fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n");
1313 return -1;
1314 }
1315
1316 /* Firstly zero the entire MBR */
1317 memset(sectorbuf, 0, ipod->sector_size);
1318
1319 /* Now add the partition info */
1320 for (i=0; i < 4 ; i++)
1321 {
1322 p = sectorbuf + 0x1be + i*16;
1323
1324 /* Ensure first partition is type 0, and second is 0xb */
1325 if (i==0) { type = 0; }
1326 else if (i==1) { type = 0xb; }
1327 else { type = ipod->pinfo[i].type; }
1328
1329 put_int32le(type, p + 4);
1330 put_int32le(ipod->pinfo[i].start, p + 8);
1331 put_int32le(ipod->pinfo[i].size, p + 12);
1332 }
1333
1334 /* Finally add the magic */
1335 sectorbuf[0x1fe] = 0x55;
1336 sectorbuf[0x1ff] = 0xaa;
1337
1338 if (ipod_seek(ipod, 0) < 0) {
1339 fprintf(stderr,"[ERR] Seek failed writing MBR\n");
1340 return -1;
1341 }
1342
1343 /* Write MBR */
1344 if ((n = ipod_write(ipod, sectorbuf, ipod->sector_size)) < 0) {
1345 perror("[ERR] Write failed\n");
1346 return -1;
1347 }
1348
1349 return 0;
1350}
diff --git a/rbutil/ipodpatcher/ipodpatcher.h b/rbutil/ipodpatcher/ipodpatcher.h
index 2339687318..d816c68724 100644
--- a/rbutil/ipodpatcher/ipodpatcher.h
+++ b/rbutil/ipodpatcher/ipodpatcher.h
@@ -46,6 +46,7 @@ int read_directory(struct ipod_t* ipod);
46int list_images(struct ipod_t* ipod); 46int list_images(struct ipod_t* ipod);
47int getmodel(struct ipod_t* ipod, int ipod_version); 47int getmodel(struct ipod_t* ipod, int ipod_version);
48int ipod_scan(struct ipod_t* ipod); 48int ipod_scan(struct ipod_t* ipod);
49int write_dos_partition_table(struct ipod_t* ipod);
49off_t filesize(int fd); 50off_t filesize(int fd);
50 51
51#endif 52#endif
diff --git a/rbutil/ipodpatcher/main.c b/rbutil/ipodpatcher/main.c
index a4508abf57..24938931d6 100644
--- a/rbutil/ipodpatcher/main.c
+++ b/rbutil/ipodpatcher/main.c
@@ -47,7 +47,8 @@ enum {
47 WRITE_FIRMWARE, 47 WRITE_FIRMWARE,
48 READ_PARTITION, 48 READ_PARTITION,
49 WRITE_PARTITION, 49 WRITE_PARTITION,
50 FORMAT_PARTITION 50 FORMAT_PARTITION,
51 CONVERT_TO_FAT32
51}; 52};
52 53
53void print_macpod_warning(void) 54void print_macpod_warning(void)
@@ -87,6 +88,7 @@ void print_usage(void)
87 fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n"); 88 fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
88 fprintf(stderr," -d, --delete-bootloader\n"); 89 fprintf(stderr," -d, --delete-bootloader\n");
89 fprintf(stderr," -f, --format\n"); 90 fprintf(stderr," -f, --format\n");
91 fprintf(stderr," -c, --convert\n");
90 fprintf(stderr,"\n"); 92 fprintf(stderr,"\n");
91 93
92#ifdef __WIN32__ 94#ifdef __WIN32__
@@ -118,11 +120,11 @@ void display_partinfo(struct ipod_t* ipod)
118 if (ipod->pinfo[i].start != 0) { 120 if (ipod->pinfo[i].start != 0) {
119 printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n", 121 printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
120 i, 122 i,
121 ipod->pinfo[i].start, 123 (long int)ipod->pinfo[i].start,
122 ipod->pinfo[i].start+ipod->pinfo[i].size-1, 124 (long int)ipod->pinfo[i].start+ipod->pinfo[i].size-1,
123 ipod->pinfo[i].size/sectors_per_MB, 125 ipod->pinfo[i].size/sectors_per_MB,
124 get_parttype(ipod->pinfo[i].type), 126 get_parttype(ipod->pinfo[i].type),
125 ipod->pinfo[i].type); 127 (int)ipod->pinfo[i].type);
126 } 128 }
127 } 129 }
128} 130}
@@ -297,6 +299,10 @@ int main(int argc, char* argv[])
297 (strcmp(argv[i],"--format")==0)) { 299 (strcmp(argv[i],"--format")==0)) {
298 action = FORMAT_PARTITION; 300 action = FORMAT_PARTITION;
299 i++; 301 i++;
302 } else if ((strcmp(argv[i],"-c")==0) ||
303 (strcmp(argv[i],"--convert")==0)) {
304 action = CONVERT_TO_FAT32;
305 i++;
300 } else { 306 } else {
301 print_usage(); return 1; 307 print_usage(); return 1;
302 } 308 }
@@ -470,8 +476,9 @@ int main(int argc, char* argv[])
470 476
471 close(infile); 477 close(infile);
472 } else if (action==FORMAT_PARTITION) { 478 } else if (action==FORMAT_PARTITION) {
473 printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FORMATTING FEATURE.\n"); 479 printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
474 printf("Are you sure you want to continue? (y/n):"); 480 printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
481 printf("Are you sure you want to format your ipod? (y/n):");
475 482
476 if (fgets(yesno,4,stdin)) { 483 if (fgets(yesno,4,stdin)) {
477 if (yesno[0]=='y') { 484 if (yesno[0]=='y') {
@@ -486,6 +493,32 @@ int main(int argc, char* argv[])
486 fprintf(stderr,"[INFO] Format cancelled.\n"); 493 fprintf(stderr,"[INFO] Format cancelled.\n");
487 } 494 }
488 } 495 }
496 } else if (action==CONVERT_TO_FAT32) {
497 if (!ipod.macpod) {
498 printf("[ERR] Ipod is already FAT32, aborting\n");
499 } else {
500 printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
501 printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
502 printf("Are you sure you want to convert your ipod to FAT32? (y/n):");
503
504 if (fgets(yesno,4,stdin)) {
505 if (yesno[0]=='y') {
506 if (ipod_reopen_rw(&ipod) < 0) {
507 return 5;
508 }
509
510 if (write_dos_partition_table(&ipod) < 0) {
511 fprintf(stderr,"[ERR] Partition conversion failed.\n");
512 }
513
514 if (format_partition(&ipod,1) < 0) {
515 fprintf(stderr,"[ERR] Format failed.\n");
516 }
517 } else {
518 fprintf(stderr,"[INFO] Format cancelled.\n");
519 }
520 }
521 }
489 } 522 }
490 523
491 ipod_close(&ipod); 524 ipod_close(&ipod);