summaryrefslogtreecommitdiff
path: root/rbutil
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 /rbutil
parent018d55599571d118ef682f81c3fc7ab2f4534b40 (diff)
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
Diffstat (limited to 'rbutil')
-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 {
};
struct partinfo_t {
- unsigned long start; /* first sector (LBA) */
- unsigned long size; /* number of sectors */
- int type;
+ uint32_t start; /* first sector (LBA) */
+ uint32_t size; /* number of sectors */
+ uint32_t type;
};
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)
return -1;
}
+ memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
+
if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
/* DOS partition table */
ipod->macpod = 0;
@@ -1289,3 +1291,60 @@ int ipod_scan(struct ipod_t* ipod)
}
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;
+}
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);
int list_images(struct ipod_t* ipod);
int getmodel(struct ipod_t* ipod, int ipod_version);
int ipod_scan(struct ipod_t* ipod);
+int write_dos_partition_table(struct ipod_t* ipod);
off_t filesize(int fd);
#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 {
WRITE_FIRMWARE,
READ_PARTITION,
WRITE_PARTITION,
- FORMAT_PARTITION
+ FORMAT_PARTITION,
+ CONVERT_TO_FAT32
};
void print_macpod_warning(void)
@@ -87,6 +88,7 @@ void print_usage(void)
fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
fprintf(stderr," -d, --delete-bootloader\n");
fprintf(stderr," -f, --format\n");
+ fprintf(stderr," -c, --convert\n");
fprintf(stderr,"\n");
#ifdef __WIN32__
@@ -118,11 +120,11 @@ void display_partinfo(struct ipod_t* ipod)
if (ipod->pinfo[i].start != 0) {
printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n",
i,
- ipod->pinfo[i].start,
- ipod->pinfo[i].start+ipod->pinfo[i].size-1,
+ (long int)ipod->pinfo[i].start,
+ (long int)ipod->pinfo[i].start+ipod->pinfo[i].size-1,
ipod->pinfo[i].size/sectors_per_MB,
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)) {
action = FORMAT_PARTITION;
i++;
+ } else if ((strcmp(argv[i],"-c")==0) ||
+ (strcmp(argv[i],"--convert")==0)) {
+ action = CONVERT_TO_FAT32;
+ i++;
} else {
print_usage(); return 1;
}
@@ -470,8 +476,9 @@ int main(int argc, char* argv[])
close(infile);
} else if (action==FORMAT_PARTITION) {
- printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FORMATTING FEATURE.\n");
- printf("Are you sure you want to continue? (y/n):");
+ 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 format your ipod? (y/n):");
if (fgets(yesno,4,stdin)) {
if (yesno[0]=='y') {
@@ -486,6 +493,32 @@ int main(int argc, char* argv[])
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);