summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-12-17 23:00:15 +0000
committerDave Chapman <dave@dchapman.com>2006-12-17 23:00:15 +0000
commit57b84b69e943c2b11e5394540f0d6b16996144d4 (patch)
treeb2079e88a476c09ce5160a5aa1eace673a11c90f
parent5774709d15ca003384a2baaa95513a8302e27bf7 (diff)
downloadrockbox-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.c6
-rw-r--r--tools/ipodpatcher/ipodio-win32.c8
-rw-r--r--tools/ipodpatcher/ipodio.h2
-rw-r--r--tools/ipodpatcher/ipodpatcher.c195
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
50int ipod_open(HANDLE* dh, char* diskname, int* sector_size) 50int 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
69int ipod_open(HANDLE* dh, char* diskname, int* sector_size) 69int 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
30void print_error(char* msg); 30void print_error(char* msg);
31int ipod_open(HANDLE* dh, char* diskname, int* sector_size); 31int ipod_open(HANDLE* dh, char* diskname, int* sector_size, int silent);
32int ipod_reopen_rw(HANDLE* dh, char* diskname); 32int ipod_reopen_rw(HANDLE* dh, char* diskname);
33int ipod_close(HANDLE dh); 33int ipod_close(HANDLE dh);
34int ipod_seek(HANDLE dh, unsigned long pos); 34int 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
173int read_partinfo(HANDLE dh, int sector_size, struct partinfo_t* pinfo) 174int 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(&sectorbuf[71],"iPod",4) != 0) && 194 if ((memcmp(&sectorbuf[71],"iPod",4) != 0) &&
193 (memcmp(&sectorbuf[0x40],"This is your Apple iPod. You probably do not want to boot from it!",66) != 0) ) { 195 (memcmp(&sectorbuf[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
329void print_usage(void) { 331void 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
1068int 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
1114int 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, &sector_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
1067int main(int argc, char* argv[]) 1183int 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(&sectorbuf,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(&sectorbuf,BUFFER_SIZE) < 0) { 1288 if (ipod_open(&dh, devicename, &sector_size, 0) < 0) {
1163 fprintf(stderr,"Failed to allocate memory buffer\n");
1164 }
1165
1166 if (ipod_open(&dh, devicename, &sector_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) {