summaryrefslogtreecommitdiff
path: root/tools/ipodpatcher/ipodpatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ipodpatcher/ipodpatcher.c')
-rw-r--r--tools/ipodpatcher/ipodpatcher.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/tools/ipodpatcher/ipodpatcher.c b/tools/ipodpatcher/ipodpatcher.c
index 51592c8fb8..2614849260 100644
--- a/tools/ipodpatcher/ipodpatcher.c
+++ b/tools/ipodpatcher/ipodpatcher.c
@@ -103,6 +103,7 @@ off_t filesize(int fd) {
103 103
104/* Partition table parsing code taken from Rockbox */ 104/* Partition table parsing code taken from Rockbox */
105 105
106#define MAX_SECTOR_SIZE 2048
106#define SECTOR_SIZE 512 107#define SECTOR_SIZE 512
107 108
108struct partinfo { 109struct partinfo {
@@ -115,26 +116,27 @@ struct partinfo {
115 ((long)array[pos] | ((long)array[pos+1] << 8 ) | \ 116 ((long)array[pos] | ((long)array[pos+1] << 8 ) | \
116 ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 )) 117 ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
117 118
118void display_partinfo(struct partinfo* pinfo) 119void display_partinfo(struct partinfo* pinfo, int sector_size)
119{ 120{
120 int i; 121 int i;
122 double sectors_per_MB = (1024.0*1024.0)/sector_size;
121 123
122 printf("Part Start Sector End Sector Size (MB) Type\n"); 124 printf("Part Start Sector End Sector Size (MB) Type\n");
123 for ( i = 0; i < 4; i++ ) { 125 for ( i = 0; i < 4; i++ ) {
124 if (pinfo[i].start != 0) { 126 if (pinfo[i].start != 0) {
125 printf(" %d %10ld %10ld %10.1f %s (0x%02x)\n",i,pinfo[i].start,pinfo[i].start+pinfo[i].size-1,pinfo[i].size/2048.0,get_parttype(pinfo[i].type),pinfo[i].type); 127 printf(" %d %10ld %10ld %10.1f %s (0x%02x)\n",i,pinfo[i].start,pinfo[i].start+pinfo[i].size-1,pinfo[i].size/sectors_per_MB,get_parttype(pinfo[i].type),pinfo[i].type);
126 } 128 }
127 } 129 }
128} 130}
129 131
130 132
131int read_partinfo(HANDLE dh, struct partinfo* pinfo) 133int read_partinfo(HANDLE dh, int sector_size, struct partinfo* pinfo)
132{ 134{
133 int i; 135 int i;
134 unsigned char sector[SECTOR_SIZE]; 136 unsigned char sector[MAX_SECTOR_SIZE];
135 unsigned long count; 137 unsigned long count;
136 138
137 if (!ReadFile(dh, sector, SECTOR_SIZE, &count, NULL)) { 139 if (!ReadFile(dh, sector, sector_size, &count, NULL)) {
138 error(" Error reading from disk: "); 140 error(" Error reading from disk: ");
139 return -1; 141 return -1;
140 } 142 }
@@ -168,7 +170,8 @@ int read_partinfo(HANDLE dh, struct partinfo* pinfo)
168 return 0; 170 return 0;
169} 171}
170 172
171int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count) 173int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count,
174 int sector_size)
172{ 175{
173 int res; 176 int res;
174 unsigned long n; 177 unsigned long n;
@@ -177,14 +180,14 @@ int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count)
177 180
178 fprintf(stderr,"[INFO] Seeking to sector %ld\n",start); 181 fprintf(stderr,"[INFO] Seeking to sector %ld\n",start);
179 182
180 if (SetFilePointer(dh, start*SECTOR_SIZE, NULL, FILE_BEGIN)==0xffffffff) { 183 if (SetFilePointer(dh, start*sector_size, NULL, FILE_BEGIN)==0xffffffff) {
181 error(" Seek error "); 184 error(" Seek error ");
182 return -1; 185 return -1;
183 } 186 }
184 187
185 fprintf(stderr,"[INFO] Writing %ld sectors to output file\n",count); 188 fprintf(stderr,"[INFO] Writing %ld sectors to output file\n",count);
186 189
187 bytesleft = count * SECTOR_SIZE; 190 bytesleft = count * sector_size;
188 while (bytesleft > 0) { 191 while (bytesleft > 0) {
189 if (bytesleft > BUFFER_SIZE) { 192 if (bytesleft > BUFFER_SIZE) {
190 chunksize = BUFFER_SIZE; 193 chunksize = BUFFER_SIZE;
@@ -212,7 +215,7 @@ int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count)
212 } 215 }
213 216
214 if (res != n) { 217 if (res != n) {
215 fprintf(stderr,"Short write - requested %d, received %d - aborting.\n",SECTOR_SIZE,res); 218 fprintf(stderr,"Short write - requested %lu, received %d - aborting.\n",n,res);
216 return -1; 219 return -1;
217 } 220 }
218 } 221 }
@@ -221,7 +224,7 @@ int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count)
221 return 0; 224 return 0;
222} 225}
223 226
224int disk_write(HANDLE dh, int infile,unsigned long start) 227int disk_write(HANDLE dh, int infile,unsigned long start, int sector_size)
225{ 228{
226 unsigned long res; 229 unsigned long res;
227 int n; 230 int n;
@@ -230,7 +233,7 @@ int disk_write(HANDLE dh, int infile,unsigned long start)
230 int eof; 233 int eof;
231 int padding = 0; 234 int padding = 0;
232 235
233 if (SetFilePointer(dh, start*SECTOR_SIZE, NULL, FILE_BEGIN)==0xffffffff) { 236 if (SetFilePointer(dh, start*sector_size, NULL, FILE_BEGIN)==0xffffffff) {
234 error(" Seek error "); 237 error(" Seek error ");
235 return -1; 238 return -1;
236 } 239 }
@@ -249,8 +252,8 @@ int disk_write(HANDLE dh, int infile,unsigned long start)
249 if (n < BUFFER_SIZE) { 252 if (n < BUFFER_SIZE) {
250 eof = 1; 253 eof = 1;
251 /* We need to pad the last write to a multiple of SECTOR_SIZE */ 254 /* We need to pad the last write to a multiple of SECTOR_SIZE */
252 if ((n % SECTOR_SIZE) != 0) { 255 if ((n % sector_size) != 0) {
253 padding = (SECTOR_SIZE-(n % SECTOR_SIZE)); 256 padding = (sector_size-(n % sector_size));
254 n += padding; 257 n += padding;
255 } 258 }
256 } 259 }
@@ -301,17 +304,20 @@ int main(int argc, char* argv[])
301 int i; 304 int i;
302 struct partinfo pinfo[4]; /* space for 4 partitions on 1 drive */ 305 struct partinfo pinfo[4]; /* space for 4 partitions on 1 drive */
303 int res; 306 int res;
307 unsigned long n;
304 int outfile; 308 int outfile;
305 int infile; 309 int infile;
306 int mode = SHOW_INFO; 310 int mode = SHOW_INFO;
307 int p = 0; 311 int p = 0;
308 int diskno = -1; 312 int diskno = -1;
313 int sector_size;
314 DISK_GEOMETRY_EX diskgeometry;
309 char diskname[32]; 315 char diskname[32];
310 HANDLE dh; 316 HANDLE dh;
311 char* filename = NULL; 317 char* filename = NULL;
312 off_t inputsize; 318 off_t inputsize;
313 319
314 fprintf(stderr,"ipodpatcher v0.3 - (C) Dave Chapman 2006\n"); 320 fprintf(stderr,"ipodpatcher v0.4 - (C) Dave Chapman 2006\n");
315 fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); 321 fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
316 fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); 322 fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
317 323
@@ -353,8 +359,6 @@ int main(int argc, char* argv[])
353 359
354 snprintf(diskname,sizeof(diskname),"\\\\.\\PhysicalDrive%d",diskno); 360 snprintf(diskname,sizeof(diskname),"\\\\.\\PhysicalDrive%d",diskno);
355 361
356 fprintf(stderr,"[INFO] Reading partition table from %s\n",diskname);
357
358 /* The ReadFile function requires a memory buffer aligned to a multiple of 362 /* The ReadFile function requires a memory buffer aligned to a multiple of
359 the disk sector size. */ 363 the disk sector size. */
360 sectorbuf = VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE); 364 sectorbuf = VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
@@ -377,15 +381,32 @@ int main(int argc, char* argv[])
377 return 2; 381 return 2;
378 } 382 }
379 383
380 if (read_partinfo(dh,pinfo) < 0) { 384 if (!DeviceIoControl(dh,
385 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
386 NULL,
387 0,
388 &diskgeometry,
389 sizeof(diskgeometry),
390 &n,
391 NULL)) {
392 error(" Error reading disk geometry: ");
393 return 2;
394 }
395
396 sector_size=diskgeometry.Geometry.BytesPerSector;
397
398 fprintf(stderr,"[INFO] Reading partition table from %s\n",diskname);
399 fprintf(stderr,"[INFO] Sector size is %d bytes\n",sector_size);
400
401 if (read_partinfo(dh,sector_size,pinfo) < 0) {
381 return 2; 402 return 2;
382 } 403 }
383 404
384 display_partinfo(pinfo); 405 display_partinfo(pinfo, sector_size);
385 406
386 if (pinfo[p].start==0) { 407 if (pinfo[p].start==0) {
387 fprintf(stderr,"[ERR] Specified partition (%d) does not exist:\n",p); 408 fprintf(stderr,"[ERR] Specified partition (%d) does not exist:\n",p);
388 display_partinfo(pinfo); 409 display_partinfo(pinfo, sector_size);
389 return 3; 410 return 3;
390 } 411 }
391 412
@@ -396,7 +417,7 @@ int main(int argc, char* argv[])
396 return 4; 417 return 4;
397 } 418 }
398 419
399 res = disk_read(dh,outfile,pinfo[p].start,pinfo[p].size); 420 res = disk_read(dh,outfile,pinfo[p].start,pinfo[p].size,sector_size);
400 421
401 close(outfile); 422 close(outfile);
402 } else if (mode==WRITE) { 423 } else if (mode==WRITE) {
@@ -427,9 +448,9 @@ int main(int argc, char* argv[])
427 /* Check filesize is <= partition size */ 448 /* Check filesize is <= partition size */
428 inputsize=filesize(infile); 449 inputsize=filesize(infile);
429 if (inputsize > 0) { 450 if (inputsize > 0) {
430 if (inputsize <= (pinfo[p].size*SECTOR_SIZE)) { 451 if (inputsize <= (pinfo[p].size*sector_size)) {
431 fprintf(stderr,"[INFO] Input file is %lu bytes\n",inputsize); 452 fprintf(stderr,"[INFO] Input file is %lu bytes\n",inputsize);
432 res = disk_write(dh,infile,pinfo[p].start); 453 res = disk_write(dh,infile,pinfo[p].start,sector_size);
433 } else { 454 } else {
434 fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n"); 455 fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n");
435 } 456 }