forked from len0rd/rockbox
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
This commit is contained in:
parent
018d555995
commit
35735c66e0
4 changed files with 102 additions and 9 deletions
|
@ -53,9 +53,9 @@ struct ipod_directory_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct partinfo_t {
|
struct partinfo_t {
|
||||||
unsigned long start; /* first sector (LBA) */
|
uint32_t start; /* first sector (LBA) */
|
||||||
unsigned long size; /* number of sectors */
|
uint32_t size; /* number of sectors */
|
||||||
int type;
|
uint32_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipod_t {
|
struct ipod_t {
|
||||||
|
|
|
@ -171,6 +171,8 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
|
||||||
|
|
||||||
if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
|
if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
|
||||||
/* DOS partition table */
|
/* DOS partition table */
|
||||||
ipod->macpod = 0;
|
ipod->macpod = 0;
|
||||||
|
@ -1289,3 +1291,60 @@ int ipod_scan(struct ipod_t* ipod)
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void put_int32le(uint32_t x, unsigned char* p)
|
||||||
|
{
|
||||||
|
p[0] = x & 0xff;
|
||||||
|
p[1] = (x >> 8) & 0xff;
|
||||||
|
p[2] = (x >> 16) & 0xff;
|
||||||
|
p[3] = (x >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_dos_partition_table(struct ipod_t* ipod)
|
||||||
|
{
|
||||||
|
unsigned char* p;
|
||||||
|
int i, n;
|
||||||
|
uint32_t type;
|
||||||
|
|
||||||
|
/* Only support 512-byte sectors at the moment */
|
||||||
|
if ( ipod->sector_size != 512 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Firstly zero the entire MBR */
|
||||||
|
memset(sectorbuf, 0, ipod->sector_size);
|
||||||
|
|
||||||
|
/* Now add the partition info */
|
||||||
|
for (i=0; i < 4 ; i++)
|
||||||
|
{
|
||||||
|
p = sectorbuf + 0x1be + i*16;
|
||||||
|
|
||||||
|
/* Ensure first partition is type 0, and second is 0xb */
|
||||||
|
if (i==0) { type = 0; }
|
||||||
|
else if (i==1) { type = 0xb; }
|
||||||
|
else { type = ipod->pinfo[i].type; }
|
||||||
|
|
||||||
|
put_int32le(type, p + 4);
|
||||||
|
put_int32le(ipod->pinfo[i].start, p + 8);
|
||||||
|
put_int32le(ipod->pinfo[i].size, p + 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally add the magic */
|
||||||
|
sectorbuf[0x1fe] = 0x55;
|
||||||
|
sectorbuf[0x1ff] = 0xaa;
|
||||||
|
|
||||||
|
if (ipod_seek(ipod, 0) < 0) {
|
||||||
|
fprintf(stderr,"[ERR] Seek failed writing MBR\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write MBR */
|
||||||
|
if ((n = ipod_write(ipod, sectorbuf, ipod->sector_size)) < 0) {
|
||||||
|
perror("[ERR] Write failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ int read_directory(struct ipod_t* ipod);
|
||||||
int list_images(struct ipod_t* ipod);
|
int list_images(struct ipod_t* ipod);
|
||||||
int getmodel(struct ipod_t* ipod, int ipod_version);
|
int getmodel(struct ipod_t* ipod, int ipod_version);
|
||||||
int ipod_scan(struct ipod_t* ipod);
|
int ipod_scan(struct ipod_t* ipod);
|
||||||
|
int write_dos_partition_table(struct ipod_t* ipod);
|
||||||
off_t filesize(int fd);
|
off_t filesize(int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,7 +47,8 @@ enum {
|
||||||
WRITE_FIRMWARE,
|
WRITE_FIRMWARE,
|
||||||
READ_PARTITION,
|
READ_PARTITION,
|
||||||
WRITE_PARTITION,
|
WRITE_PARTITION,
|
||||||
FORMAT_PARTITION
|
FORMAT_PARTITION,
|
||||||
|
CONVERT_TO_FAT32
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_macpod_warning(void)
|
void print_macpod_warning(void)
|
||||||
|
@ -87,6 +88,7 @@ void print_usage(void)
|
||||||
fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
|
fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
|
||||||
fprintf(stderr," -d, --delete-bootloader\n");
|
fprintf(stderr," -d, --delete-bootloader\n");
|
||||||
fprintf(stderr," -f, --format\n");
|
fprintf(stderr," -f, --format\n");
|
||||||
|
fprintf(stderr," -c, --convert\n");
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -118,11 +120,11 @@ void display_partinfo(struct ipod_t* ipod)
|
||||||
if (ipod->pinfo[i].start != 0) {
|
if (ipod->pinfo[i].start != 0) {
|
||||||
printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
|
printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
|
||||||
i,
|
i,
|
||||||
ipod->pinfo[i].start,
|
(long int)ipod->pinfo[i].start,
|
||||||
ipod->pinfo[i].start+ipod->pinfo[i].size-1,
|
(long int)ipod->pinfo[i].start+ipod->pinfo[i].size-1,
|
||||||
ipod->pinfo[i].size/sectors_per_MB,
|
ipod->pinfo[i].size/sectors_per_MB,
|
||||||
get_parttype(ipod->pinfo[i].type),
|
get_parttype(ipod->pinfo[i].type),
|
||||||
ipod->pinfo[i].type);
|
(int)ipod->pinfo[i].type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,6 +299,10 @@ int main(int argc, char* argv[])
|
||||||
(strcmp(argv[i],"--format")==0)) {
|
(strcmp(argv[i],"--format")==0)) {
|
||||||
action = FORMAT_PARTITION;
|
action = FORMAT_PARTITION;
|
||||||
i++;
|
i++;
|
||||||
|
} else if ((strcmp(argv[i],"-c")==0) ||
|
||||||
|
(strcmp(argv[i],"--convert")==0)) {
|
||||||
|
action = CONVERT_TO_FAT32;
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
print_usage(); return 1;
|
print_usage(); return 1;
|
||||||
}
|
}
|
||||||
|
@ -470,8 +476,9 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
close(infile);
|
close(infile);
|
||||||
} else if (action==FORMAT_PARTITION) {
|
} else if (action==FORMAT_PARTITION) {
|
||||||
printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FORMATTING FEATURE.\n");
|
printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
|
||||||
printf("Are you sure you want to continue? (y/n):");
|
printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
|
||||||
|
printf("Are you sure you want to format your ipod? (y/n):");
|
||||||
|
|
||||||
if (fgets(yesno,4,stdin)) {
|
if (fgets(yesno,4,stdin)) {
|
||||||
if (yesno[0]=='y') {
|
if (yesno[0]=='y') {
|
||||||
|
@ -486,6 +493,32 @@ int main(int argc, char* argv[])
|
||||||
fprintf(stderr,"[INFO] Format cancelled.\n");
|
fprintf(stderr,"[INFO] Format cancelled.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (action==CONVERT_TO_FAT32) {
|
||||||
|
if (!ipod.macpod) {
|
||||||
|
printf("[ERR] Ipod is already FAT32, aborting\n");
|
||||||
|
} else {
|
||||||
|
printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n");
|
||||||
|
printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n");
|
||||||
|
printf("Are you sure you want to convert your ipod to FAT32? (y/n):");
|
||||||
|
|
||||||
|
if (fgets(yesno,4,stdin)) {
|
||||||
|
if (yesno[0]=='y') {
|
||||||
|
if (ipod_reopen_rw(&ipod) < 0) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_dos_partition_table(&ipod) < 0) {
|
||||||
|
fprintf(stderr,"[ERR] Partition conversion failed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format_partition(&ipod,1) < 0) {
|
||||||
|
fprintf(stderr,"[ERR] Format failed.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"[INFO] Format cancelled.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ipod_close(&ipod);
|
ipod_close(&ipod);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue