diff options
Diffstat (limited to 'tools/ipodpatcher')
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.c | 65 |
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 | ||
108 | struct partinfo { | 109 | struct 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 | ||
118 | void display_partinfo(struct partinfo* pinfo) | 119 | void 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 | ||
131 | int read_partinfo(HANDLE dh, struct partinfo* pinfo) | 133 | int 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 | ||
171 | int disk_read(HANDLE dh, int outfile,unsigned long start, unsigned long count) | 173 | int 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 | ||
224 | int disk_write(HANDLE dh, int infile,unsigned long start) | 227 | int 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 | } |