diff options
author | Dave Chapman <dave@dchapman.com> | 2006-12-17 23:00:15 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-12-17 23:00:15 +0000 |
commit | 57b84b69e943c2b11e5394540f0d6b16996144d4 (patch) | |
tree | b2079e88a476c09ce5160a5aa1eace673a11c90f | |
parent | 5774709d15ca003384a2baaa95513a8302e27bf7 (diff) | |
download | rockbox-57b84b69e943c2b11e5394540f0d6b16996144d4.tar.gz rockbox-57b84b69e943c2b11e5394540f0d6b16996144d4.zip |
Add a simple --scan option which tests all disks from 0 to 25 to see if they look like an ipod.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11792 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | tools/ipodpatcher/ipodio-posix.c | 6 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodio-win32.c | 8 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodio.h | 2 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.c | 195 |
4 files changed, 149 insertions, 62 deletions
diff --git a/tools/ipodpatcher/ipodio-posix.c b/tools/ipodpatcher/ipodio-posix.c index dd0a2b041b..071a540017 100644 --- a/tools/ipodpatcher/ipodio-posix.c +++ b/tools/ipodpatcher/ipodio-posix.c | |||
@@ -47,17 +47,17 @@ void print_error(char* msg) | |||
47 | perror(msg); | 47 | perror(msg); |
48 | } | 48 | } |
49 | 49 | ||
50 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size) | 50 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size, int silent) |
51 | { | 51 | { |
52 | *dh=open(diskname,O_RDONLY); | 52 | *dh=open(diskname,O_RDONLY); |
53 | if (*dh < 0) { | 53 | if (*dh < 0) { |
54 | perror(diskname); | 54 | if (!silent) perror(diskname); |
55 | return -1; | 55 | return -1; |
56 | } | 56 | } |
57 | 57 | ||
58 | if(ioctl(*dh,IPOD_SECTORSIZE_IOCTL,sector_size) < 0) { | 58 | if(ioctl(*dh,IPOD_SECTORSIZE_IOCTL,sector_size) < 0) { |
59 | *sector_size=512; | 59 | *sector_size=512; |
60 | fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n",*sector_size); | 60 | if (!silent) fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n",*sector_size); |
61 | } | 61 | } |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
diff --git a/tools/ipodpatcher/ipodio-win32.c b/tools/ipodpatcher/ipodio-win32.c index 5292047180..97e3fb6fec 100644 --- a/tools/ipodpatcher/ipodio-win32.c +++ b/tools/ipodpatcher/ipodio-win32.c | |||
@@ -66,7 +66,7 @@ void print_error(char* msg) | |||
66 | LocalFree(pMsgBuf); | 66 | LocalFree(pMsgBuf); |
67 | } | 67 | } |
68 | 68 | ||
69 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size) | 69 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size, int silent) |
70 | { | 70 | { |
71 | DISK_GEOMETRY_EX diskgeometry_ex; | 71 | DISK_GEOMETRY_EX diskgeometry_ex; |
72 | DISK_GEOMETRY diskgeometry; | 72 | DISK_GEOMETRY diskgeometry; |
@@ -77,12 +77,12 @@ int ipod_open(HANDLE* dh, char* diskname, int* sector_size) | |||
77 | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); | 77 | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); |
78 | 78 | ||
79 | if (*dh == INVALID_HANDLE_VALUE) { | 79 | if (*dh == INVALID_HANDLE_VALUE) { |
80 | print_error(" Error opening disk: "); | 80 | if (!silent) print_error(" Error opening disk: "); |
81 | return -1; | 81 | return -1; |
82 | } | 82 | } |
83 | 83 | ||
84 | if (!lock_volume(*dh)) { | 84 | if (!lock_volume(*dh)) { |
85 | print_error(" Error locking disk: "); | 85 | if (!silent) print_error(" Error locking disk: "); |
86 | return -1; | 86 | return -1; |
87 | } | 87 | } |
88 | 88 | ||
@@ -102,7 +102,7 @@ int ipod_open(HANDLE* dh, char* diskname, int* sector_size) | |||
102 | sizeof(diskgeometry), | 102 | sizeof(diskgeometry), |
103 | &n, | 103 | &n, |
104 | NULL)) { | 104 | NULL)) { |
105 | print_error(" Error reading disk geometry: "); | 105 | if (!silent) print_error(" Error reading disk geometry: "); |
106 | return -1; | 106 | return -1; |
107 | } else { | 107 | } else { |
108 | *sector_size=diskgeometry.BytesPerSector; | 108 | *sector_size=diskgeometry.BytesPerSector; |
diff --git a/tools/ipodpatcher/ipodio.h b/tools/ipodpatcher/ipodio.h index 8496766b76..585ca90e16 100644 --- a/tools/ipodpatcher/ipodio.h +++ b/tools/ipodpatcher/ipodio.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | void print_error(char* msg); | 30 | void print_error(char* msg); |
31 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size); | 31 | int ipod_open(HANDLE* dh, char* diskname, int* sector_size, int silent); |
32 | int ipod_reopen_rw(HANDLE* dh, char* diskname); | 32 | int ipod_reopen_rw(HANDLE* dh, char* diskname); |
33 | int ipod_close(HANDLE dh); | 33 | int ipod_close(HANDLE dh); |
34 | int ipod_seek(HANDLE dh, unsigned long pos); | 34 | int ipod_seek(HANDLE dh, unsigned long pos); |
diff --git a/tools/ipodpatcher/ipodpatcher.c b/tools/ipodpatcher/ipodpatcher.c index d4b7731747..518935b176 100644 --- a/tools/ipodpatcher/ipodpatcher.c +++ b/tools/ipodpatcher/ipodpatcher.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <inttypes.h> | 25 | #include <inttypes.h> |
26 | #include <sys/types.h> | 26 | #include <sys/types.h> |
27 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
28 | #include <dirent.h> | ||
28 | 29 | ||
29 | #include "parttypes.h" | 30 | #include "parttypes.h" |
30 | #include "ipodio.h" | 31 | #include "ipodio.h" |
@@ -170,7 +171,8 @@ void display_partinfo(struct partinfo_t* pinfo, int sector_size) | |||
170 | } | 171 | } |
171 | 172 | ||
172 | 173 | ||
173 | int read_partinfo(HANDLE dh, int sector_size, struct partinfo_t* pinfo) | 174 | int read_partinfo(HANDLE dh, int sector_size, struct partinfo_t* pinfo, |
175 | int silent) | ||
174 | { | 176 | { |
175 | int i; | 177 | int i; |
176 | unsigned long count; | 178 | unsigned long count; |
@@ -185,13 +187,13 @@ int read_partinfo(HANDLE dh, int sector_size, struct partinfo_t* pinfo) | |||
185 | /* check that the boot sector is initialized */ | 187 | /* check that the boot sector is initialized */ |
186 | if ( (sectorbuf[510] != 0x55) || | 188 | if ( (sectorbuf[510] != 0x55) || |
187 | (sectorbuf[511] != 0xaa)) { | 189 | (sectorbuf[511] != 0xaa)) { |
188 | fprintf(stderr,"[ERR] Bad boot sector signature\n"); | 190 | if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n"); |
189 | return -1; | 191 | return -1; |
190 | } | 192 | } |
191 | 193 | ||
192 | if ((memcmp(§orbuf[71],"iPod",4) != 0) && | 194 | if ((memcmp(§orbuf[71],"iPod",4) != 0) && |
193 | (memcmp(§orbuf[0x40],"This is your Apple iPod. You probably do not want to boot from it!",66) != 0) ) { | 195 | (memcmp(§orbuf[0x40],"This is your Apple iPod. You probably do not want to boot from it!",66) != 0) ) { |
194 | fprintf(stderr,"[ERR] Drive is not an iPod, aborting\n"); | 196 | if (!silent) fprintf(stderr,"[ERR] Drive is not an iPod, aborting\n"); |
195 | return -1; | 197 | return -1; |
196 | } | 198 | } |
197 | 199 | ||
@@ -327,14 +329,16 @@ int write_partition(HANDLE dh, int infile,unsigned long start_sector, | |||
327 | 329 | ||
328 | 330 | ||
329 | void print_usage(void) { | 331 | void print_usage(void) { |
332 | fprintf(stderr,"Usage: ipodpatcher --scan\n"); | ||
330 | #ifdef __WIN32__ | 333 | #ifdef __WIN32__ |
331 | fprintf(stderr,"Usage: ipodpatcher DISKNO [action]\n"); | 334 | fprintf(stderr," or ipodpatcher DISKNO [action]\n"); |
332 | #else | 335 | #else |
333 | fprintf(stderr,"Usage: ipodpatcher device [action]\n"); | 336 | fprintf(stderr," or ipodpatcher device [action]\n"); |
334 | #endif | 337 | #endif |
335 | fprintf(stderr,"\n"); | 338 | fprintf(stderr,"\n"); |
336 | fprintf(stderr,"Where [action] is one of the following options:\n"); | 339 | fprintf(stderr,"Where [action] is one of the following options:\n"); |
337 | fprintf(stderr," -l, --list\n"); | 340 | fprintf(stderr," -l, --list\n"); |
341 | fprintf(stderr," -l, --list\n"); | ||
338 | fprintf(stderr," -r, --read-partition bootpartition.bin\n"); | 342 | fprintf(stderr," -r, --read-partition bootpartition.bin\n"); |
339 | fprintf(stderr," -w, --write-partition bootpartition.bin\n"); | 343 | fprintf(stderr," -w, --write-partition bootpartition.bin\n"); |
340 | fprintf(stderr," -rf, --read-firmware filename.ipod\n"); | 344 | fprintf(stderr," -rf, --read-firmware filename.ipod\n"); |
@@ -1061,19 +1065,132 @@ int list_images(int nimages, struct ipod_directory_t* ipod_directory, | |||
1061 | return 0; | 1065 | return 0; |
1062 | } | 1066 | } |
1063 | 1067 | ||
1068 | int getmodel(int ipod_version, char** modelstr, char** modelname, int* modelnum) | ||
1069 | { | ||
1070 | switch (ipod_version) { | ||
1071 | case 0x3: | ||
1072 | *modelstr="3rd Generation"; | ||
1073 | *modelnum = 7; | ||
1074 | *modelname = "ip3g"; | ||
1075 | break; | ||
1076 | case 0x4: | ||
1077 | *modelstr="1st Generation Mini"; | ||
1078 | *modelnum = 9; | ||
1079 | *modelname = "mini"; | ||
1080 | break; | ||
1081 | case 0x5: | ||
1082 | *modelstr="4th Generation"; | ||
1083 | *modelnum = 8; | ||
1084 | *modelname = "ip4g"; | ||
1085 | break; | ||
1086 | case 0x6: | ||
1087 | *modelstr="Photo/Color"; | ||
1088 | *modelnum = 3; | ||
1089 | *modelname = "ipco"; | ||
1090 | break; | ||
1091 | case 0x7: | ||
1092 | *modelstr="2nd Generation Mini"; | ||
1093 | *modelnum = 11; | ||
1094 | *modelname = "mn2g"; | ||
1095 | break; | ||
1096 | case 0xc: | ||
1097 | *modelstr="1st Generation Nano"; | ||
1098 | *modelnum = 4; | ||
1099 | *modelname = "nano"; | ||
1100 | break; | ||
1101 | case 0xb: | ||
1102 | *modelstr="Video (aka 5th Generation)"; | ||
1103 | *modelnum = 5; | ||
1104 | *modelname = "ipvd"; | ||
1105 | break; | ||
1106 | default: | ||
1107 | *modelname = NULL; | ||
1108 | *modelnum = 0; | ||
1109 | return -1; | ||
1110 | } | ||
1111 | return 0; | ||
1112 | } | ||
1064 | 1113 | ||
1114 | int ipod_scan(void) | ||
1115 | { | ||
1116 | int i; | ||
1117 | int n = 0; | ||
1118 | char devicename[96]; | ||
1119 | HANDLE dh; | ||
1120 | int nimages; | ||
1121 | struct partinfo_t pinfo[4]; /* space for 4 partitions on 1 drive */ | ||
1122 | int ipod_version; | ||
1123 | off_t diroffset; | ||
1124 | char* modelname; | ||
1125 | char* modelstr; | ||
1126 | int modelnum; | ||
1127 | struct ipod_directory_t ipod_directory[MAX_IMAGES]; | ||
1128 | int sector_size; | ||
1129 | |||
1130 | printf("[INFO] Scanning disk devices...\n"); | ||
1065 | 1131 | ||
1132 | for (i = 0; i < 25 ; i++) { | ||
1133 | #ifdef __WIN32__ | ||
1134 | sprintf(devicename,"\\\\.\\PhysicalDrive%d",i); | ||
1135 | #elif defined(linux) || defined (__linux) | ||
1136 | sprintf(devicename,"/dev/sd%c",'a'+i); | ||
1137 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \ | ||
1138 | || defined(__bsdi__) || defined(__DragonFly__) | ||
1139 | sprintf(devicename,"/dev/da%d",i); | ||
1140 | #elif defined(__APPLE__) && defined(__MACH__) | ||
1141 | sprintf(devicename,"/dev/disk%d",i); | ||
1142 | #else | ||
1143 | #error No disk paths defined for this platform | ||
1144 | #endif | ||
1145 | if (ipod_open(&dh, devicename, §or_size, 1) < 0) { | ||
1146 | continue; | ||
1147 | } | ||
1148 | |||
1149 | if (read_partinfo(dh,sector_size,pinfo,1) < 0) { | ||
1150 | continue; | ||
1151 | } | ||
1152 | |||
1153 | if ((pinfo[0].start==0) || (pinfo[0].type != 0)) { | ||
1154 | continue; | ||
1155 | } | ||
1156 | |||
1157 | nimages=read_directory(dh, pinfo[0].start*sector_size, sector_size, | ||
1158 | ipod_directory, &diroffset); | ||
1159 | |||
1160 | if (nimages < 0) { | ||
1161 | continue; | ||
1162 | } | ||
1163 | |||
1164 | ipod_version=(ipod_directory[0].vers>>12) & 0x0f; | ||
1165 | if (getmodel(ipod_version,&modelstr,&modelname,&modelnum) < 0) { | ||
1166 | continue; | ||
1167 | } | ||
1168 | |||
1169 | #ifdef __WIN32__ | ||
1170 | printf("[INFO] Ipod found - %s - disk device %d\n",modelstr,i); | ||
1171 | #else | ||
1172 | printf("[INFO] Ipod found - %s - %s\n",modelstr,devicename); | ||
1173 | #endif | ||
1174 | n++; | ||
1175 | } | ||
1176 | |||
1177 | if (n==0) { | ||
1178 | fprintf(stderr,"[ERR] No ipods found.\n"); | ||
1179 | } | ||
1180 | return 0; | ||
1181 | } | ||
1066 | 1182 | ||
1067 | int main(int argc, char* argv[]) | 1183 | int main(int argc, char* argv[]) |
1068 | { | 1184 | { |
1069 | int i; | 1185 | int i; |
1070 | int infile, outfile; | 1186 | int infile, outfile; |
1071 | int ipod_version; | ||
1072 | unsigned int inputsize; | 1187 | unsigned int inputsize; |
1073 | struct partinfo_t pinfo[4]; /* space for 4 partitions on 1 drive */ | 1188 | struct partinfo_t pinfo[4]; /* space for 4 partitions on 1 drive */ |
1189 | int ipod_version; | ||
1074 | int nimages; | 1190 | int nimages; |
1075 | off_t diroffset; | 1191 | off_t diroffset; |
1076 | char* modelname; | 1192 | char* modelname; |
1193 | char* modelstr; | ||
1077 | int modelnum; | 1194 | int modelnum; |
1078 | char* filename; | 1195 | char* filename; |
1079 | struct ipod_directory_t ipod_directory[MAX_IMAGES]; | 1196 | struct ipod_directory_t ipod_directory[MAX_IMAGES]; |
@@ -1085,13 +1202,22 @@ int main(int argc, char* argv[]) | |||
1085 | fprintf(stderr,"ipodpatcher v" VERSION " - (C) Dave Chapman 2006\n"); | 1202 | fprintf(stderr,"ipodpatcher v" VERSION " - (C) Dave Chapman 2006\n"); |
1086 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | 1203 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); |
1087 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | 1204 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); |
1088 | 1205 | ||
1089 | if ((argc < 2) || (strcmp(argv[1],"-h")==0) || | 1206 | if ((argc < 2) || (strcmp(argv[1],"-h")==0) || |
1090 | (strcmp(argv[1],"--help")==0)) { | 1207 | (strcmp(argv[1],"--help")==0)) { |
1091 | print_usage(); | 1208 | print_usage(); |
1092 | return 1; | 1209 | return 1; |
1093 | } | 1210 | } |
1094 | 1211 | ||
1212 | if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) { | ||
1213 | fprintf(stderr,"Failed to allocate memory buffer\n"); | ||
1214 | } | ||
1215 | |||
1216 | if (strcmp(argv[1],"--scan")==0) { | ||
1217 | ipod_scan(); | ||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1095 | i = 1; | 1221 | i = 1; |
1096 | devicename[0]=0; | 1222 | devicename[0]=0; |
1097 | 1223 | ||
@@ -1159,18 +1285,14 @@ int main(int argc, char* argv[]) | |||
1159 | return 1; | 1285 | return 1; |
1160 | } | 1286 | } |
1161 | 1287 | ||
1162 | if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) { | 1288 | if (ipod_open(&dh, devicename, §or_size, 0) < 0) { |
1163 | fprintf(stderr,"Failed to allocate memory buffer\n"); | ||
1164 | } | ||
1165 | |||
1166 | if (ipod_open(&dh, devicename, §or_size) < 0) { | ||
1167 | return 1; | 1289 | return 1; |
1168 | } | 1290 | } |
1169 | 1291 | ||
1170 | fprintf(stderr,"[INFO] Reading partition table from %s\n",devicename); | 1292 | fprintf(stderr,"[INFO] Reading partition table from %s\n",devicename); |
1171 | fprintf(stderr,"[INFO] Sector size is %d bytes\n",sector_size); | 1293 | fprintf(stderr,"[INFO] Sector size is %d bytes\n",sector_size); |
1172 | 1294 | ||
1173 | if (read_partinfo(dh,sector_size,pinfo) < 0) { | 1295 | if (read_partinfo(dh,sector_size,pinfo,0) < 0) { |
1174 | return 2; | 1296 | return 2; |
1175 | } | 1297 | } |
1176 | 1298 | ||
@@ -1190,49 +1312,14 @@ int main(int argc, char* argv[]) | |||
1190 | } | 1312 | } |
1191 | 1313 | ||
1192 | ipod_version=(ipod_directory[0].vers>>12) & 0x0f; | 1314 | ipod_version=(ipod_directory[0].vers>>12) & 0x0f; |
1193 | printf("[INFO] Ipod model: "); | 1315 | if (getmodel(ipod_version,&modelstr,&modelname,&modelnum) < 0) { |
1194 | switch (ipod_version) { | 1316 | fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n", |
1195 | case 0x3: | 1317 | ipod_version); |
1196 | printf("3rd Generation\n"); | 1318 | return -1; |
1197 | modelnum = 7; | ||
1198 | modelname = "ip3g"; | ||
1199 | break; | ||
1200 | case 0x4: | ||
1201 | printf("1st Generation Mini\n"); | ||
1202 | modelnum = 9; | ||
1203 | modelname = "mini"; | ||
1204 | break; | ||
1205 | case 0x5: | ||
1206 | printf("4th Generation\n"); | ||
1207 | modelnum = 8; | ||
1208 | modelname = "ip4g"; | ||
1209 | break; | ||
1210 | case 0x6: | ||
1211 | printf("Photo/Color\n"); | ||
1212 | modelnum = 3; | ||
1213 | modelname = "ipco"; | ||
1214 | break; | ||
1215 | case 0x7: | ||
1216 | printf("2nd Generation Mini\n"); | ||
1217 | modelnum = 11; | ||
1218 | modelname = "mn2g"; | ||
1219 | break; | ||
1220 | case 0xc: | ||
1221 | printf("1st Generation Nano\n"); | ||
1222 | modelnum = 4; | ||
1223 | modelname = "nano"; | ||
1224 | break; | ||
1225 | case 0xb: | ||
1226 | printf("Video (aka 5th Generation)\n"); | ||
1227 | modelnum = 5; | ||
1228 | modelname = "ipvd"; | ||
1229 | break; | ||
1230 | default: | ||
1231 | printf("[ERR] Unknown firmware version (0x%08x)\n", | ||
1232 | ipod_directory[0].vers); | ||
1233 | return -1; | ||
1234 | } | 1319 | } |
1235 | 1320 | ||
1321 | printf("[INFO] Ipod model: %s\n",modelstr); | ||
1322 | |||
1236 | if (action==LIST_IMAGES) { | 1323 | if (action==LIST_IMAGES) { |
1237 | list_images(nimages,ipod_directory,sector_size); | 1324 | list_images(nimages,ipod_directory,sector_size); |
1238 | } else if (action==DELETE_BOOTLOADER) { | 1325 | } else if (action==DELETE_BOOTLOADER) { |