diff options
Diffstat (limited to 'rbutil/ipodpatcher')
-rw-r--r-- | rbutil/ipodpatcher/ipodio.h | 6 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodpatcher.c | 59 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodpatcher.h | 1 | ||||
-rw-r--r-- | rbutil/ipodpatcher/main.c | 45 |
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 | ||
55 | struct partinfo_t { | 55 | struct 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 | ||
61 | struct ipod_t { | 61 | struct 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 | |||
1295 | static 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 | |||
1303 | int 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); | |||
46 | int list_images(struct ipod_t* ipod); | 46 | int list_images(struct ipod_t* ipod); |
47 | int getmodel(struct ipod_t* ipod, int ipod_version); | 47 | int getmodel(struct ipod_t* ipod, int ipod_version); |
48 | int ipod_scan(struct ipod_t* ipod); | 48 | int ipod_scan(struct ipod_t* ipod); |
49 | int write_dos_partition_table(struct ipod_t* ipod); | ||
49 | off_t filesize(int fd); | 50 | off_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 | ||
53 | void print_macpod_warning(void) | 54 | void 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); |