diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2012-12-23 23:30:57 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2013-01-01 15:05:52 +0100 |
commit | 24e37ddf57bac6a1c9786d50abbe3a1982930382 (patch) | |
tree | b34ae751986f185f51556a040f388025cac4c383 /rbutil | |
parent | 6803d7b10cd9651ded08674f1597d4511cabb7af (diff) | |
download | rockbox-24e37ddf57bac6a1c9786d50abbe3a1982930382.tar.gz rockbox-24e37ddf57bac6a1c9786d50abbe3a1982930382.zip |
ipodpatcher: move sectorbuf pointer into ipod_t structure.
The ipod_t structure holds all relevant information for ipodpatcher. Put the
global ipod_sectorbuf pointer into it as well. Allows the Rockbox Utility Ipod
class to be instanciated multiple times since each instance can now have its
own buffer.
Change-Id: Ie319cbadbc20c367ceadba9a46b4dc34b57a79a7
Diffstat (limited to 'rbutil')
-rw-r--r-- | rbutil/ipodpatcher/fat32format.c | 19 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodio-posix.c | 20 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodio-win32.c | 20 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodio.h | 7 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodpatcher.c | 262 | ||||
-rw-r--r-- | rbutil/ipodpatcher/ipodpatcher.h | 10 | ||||
-rw-r--r-- | rbutil/ipodpatcher/main.c | 2 | ||||
-rw-r--r-- | rbutil/rbutilqt/base/autodetection.cpp | 8 | ||||
-rw-r--r-- | rbutil/rbutilqt/base/bootloaderinstallipod.cpp | 23 |
9 files changed, 210 insertions, 161 deletions
diff --git a/rbutil/ipodpatcher/fat32format.c b/rbutil/ipodpatcher/fat32format.c index 9d2c538cd7..f47be60a97 100644 --- a/rbutil/ipodpatcher/fat32format.c +++ b/rbutil/ipodpatcher/fat32format.c | |||
@@ -87,9 +87,6 @@ static uint32_t rb_htole32(uint32_t x) | |||
87 | } | 87 | } |
88 | 88 | ||
89 | 89 | ||
90 | /* A large aligned buffer for disk I/O */ | ||
91 | extern unsigned char* ipod_sectorbuf; | ||
92 | |||
93 | /* TODO: Pass these as parameters to the various create_ functions */ | 90 | /* TODO: Pass these as parameters to the various create_ functions */ |
94 | 91 | ||
95 | /* can be zero for default or 1,2,4,8,16,32 or 64 */ | 92 | /* can be zero for default or 1,2,4,8,16,32 or 64 */ |
@@ -166,7 +163,7 @@ static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count) | |||
166 | return -1; | 163 | return -1; |
167 | } | 164 | } |
168 | 165 | ||
169 | memset(ipod_sectorbuf, 0, 128 * ipod->sector_size); | 166 | memset(ipod->sectorbuf, 0, 128 * ipod->sector_size); |
170 | 167 | ||
171 | /* Write 128 sectors at a time */ | 168 | /* Write 128 sectors at a time */ |
172 | while (count) { | 169 | while (count) { |
@@ -175,7 +172,7 @@ static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count) | |||
175 | else | 172 | else |
176 | n = count; | 173 | n = count; |
177 | 174 | ||
178 | if (ipod_write(ipod,ipod_sectorbuf,n * ipod->sector_size) < 0) { | 175 | if (ipod_write(ipod,n * ipod->sector_size) < 0) { |
179 | perror("[ERR] Write failed in zero_sectors\n"); | 176 | perror("[ERR] Write failed in zero_sectors\n"); |
180 | return -1; | 177 | return -1; |
181 | } | 178 | } |
@@ -484,15 +481,15 @@ int format_partition(struct ipod_t* ipod, int partition) | |||
484 | fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" ); | 481 | fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" ); |
485 | 482 | ||
486 | /* Create the boot sector structure */ | 483 | /* Create the boot sector structure */ |
487 | create_boot_sector(ipod_sectorbuf, ipod, partition); | 484 | create_boot_sector(ipod->sectorbuf, ipod, partition); |
488 | create_fsinfo(ipod_sectorbuf + 512); | 485 | create_fsinfo(ipod->sectorbuf + 512); |
489 | 486 | ||
490 | /* Write boot sector and fsinfo at start of partition */ | 487 | /* Write boot sector and fsinfo at start of partition */ |
491 | if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) { | 488 | if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) { |
492 | fprintf(stderr,"[ERR] Seek failed\n"); | 489 | fprintf(stderr,"[ERR] Seek failed\n"); |
493 | return -1; | 490 | return -1; |
494 | } | 491 | } |
495 | if (ipod_write(ipod,ipod_sectorbuf,512 * 2) < 0) { | 492 | if (ipod_write(ipod,512 * 2) < 0) { |
496 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); | 493 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); |
497 | return -1; | 494 | return -1; |
498 | } | 495 | } |
@@ -502,13 +499,13 @@ int format_partition(struct ipod_t* ipod, int partition) | |||
502 | fprintf(stderr,"[ERR] Seek failed\n"); | 499 | fprintf(stderr,"[ERR] Seek failed\n"); |
503 | return -1; | 500 | return -1; |
504 | } | 501 | } |
505 | if (ipod_write(ipod,ipod_sectorbuf,512 * 2) < 0) { | 502 | if (ipod_write(ipod,512 * 2) < 0) { |
506 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); | 503 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); |
507 | return -1; | 504 | return -1; |
508 | } | 505 | } |
509 | 506 | ||
510 | /* Create the first FAT sector */ | 507 | /* Create the first FAT sector */ |
511 | create_firstfatsector(ipod_sectorbuf); | 508 | create_firstfatsector(ipod->sectorbuf); |
512 | 509 | ||
513 | /* Write the first fat sector in the right places */ | 510 | /* Write the first fat sector in the right places */ |
514 | for ( i=0; i<NumFATs; i++ ) { | 511 | for ( i=0; i<NumFATs; i++ ) { |
@@ -519,7 +516,7 @@ int format_partition(struct ipod_t* ipod, int partition) | |||
519 | return -1; | 516 | return -1; |
520 | } | 517 | } |
521 | 518 | ||
522 | if (ipod_write(ipod,ipod_sectorbuf,512) < 0) { | 519 | if (ipod_write(ipod,512) < 0) { |
523 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); | 520 | perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); |
524 | return -1; | 521 | return -1; |
525 | } | 522 | } |
diff --git a/rbutil/ipodpatcher/ipodio-posix.c b/rbutil/ipodpatcher/ipodio-posix.c index 8d43de2d60..377510912a 100644 --- a/rbutil/ipodpatcher/ipodio-posix.c +++ b/rbutil/ipodpatcher/ipodio-posix.c | |||
@@ -358,10 +358,10 @@ int ipod_close(struct ipod_t* ipod) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize) | 361 | int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize) |
362 | { | 362 | { |
363 | *sectorbuf=malloc(bufsize); | 363 | ipod->sectorbuf = malloc(bufsize); |
364 | if (*sectorbuf == NULL) { | 364 | if (ipod->sectorbuf== NULL) { |
365 | return -1; | 365 | return -1; |
366 | } | 366 | } |
367 | return 0; | 367 | return 0; |
@@ -379,14 +379,20 @@ int ipod_seek(struct ipod_t* ipod, unsigned long pos) | |||
379 | return 0; | 379 | return 0; |
380 | } | 380 | } |
381 | 381 | ||
382 | ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes) | 382 | ssize_t ipod_read(struct ipod_t* ipod, int nbytes) |
383 | { | 383 | { |
384 | return read(ipod->dh, buf, nbytes); | 384 | if(ipod->sectorbuf == NULL) { |
385 | return -1; | ||
386 | } | ||
387 | return read(ipod->dh, ipod->sectorbuf, nbytes); | ||
385 | } | 388 | } |
386 | 389 | ||
387 | ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes) | 390 | ssize_t ipod_write(struct ipod_t* ipod, int nbytes) |
388 | { | 391 | { |
389 | return write(ipod->dh, buf, nbytes); | 392 | if(ipod->sectorbuf == NULL) { |
393 | return -1; | ||
394 | } | ||
395 | return write(ipod->dh, ipod->sectorbuf, nbytes); | ||
390 | } | 396 | } |
391 | 397 | ||
392 | #endif | 398 | #endif |
diff --git a/rbutil/ipodpatcher/ipodio-win32.c b/rbutil/ipodpatcher/ipodio-win32.c index 27c1b24f01..d4bdbf0173 100644 --- a/rbutil/ipodpatcher/ipodio-win32.c +++ b/rbutil/ipodpatcher/ipodio-win32.c | |||
@@ -158,12 +158,12 @@ int ipod_close(struct ipod_t* ipod) | |||
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
161 | int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize) | 161 | int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize) |
162 | { | 162 | { |
163 | /* The ReadFile function requires a memory buffer aligned to a multiple of | 163 | /* The ReadFile function requires a memory buffer aligned to a multiple of |
164 | the disk sector size. */ | 164 | the disk sector size. */ |
165 | *sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE); | 165 | ipod->sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE); |
166 | if (*sectorbuf == NULL) { | 166 | if (ipod->sectorbuf== NULL) { |
167 | ipod_print_error(" Error allocating a buffer: "); | 167 | ipod_print_error(" Error allocating a buffer: "); |
168 | return -1; | 168 | return -1; |
169 | } | 169 | } |
@@ -179,11 +179,14 @@ int ipod_seek(struct ipod_t* ipod, unsigned long pos) | |||
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
181 | 181 | ||
182 | ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes) | 182 | ssize_t ipod_read(struct ipod_t* ipod, int nbytes) |
183 | { | 183 | { |
184 | unsigned long count; | 184 | unsigned long count; |
185 | 185 | ||
186 | if (!ReadFile(ipod->dh, buf, nbytes, &count, NULL)) { | 186 | if(ipod->sectorbuf == NULL) { |
187 | return -1; | ||
188 | } | ||
189 | if (!ReadFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) { | ||
187 | ipod_print_error(" Error reading from disk: "); | 190 | ipod_print_error(" Error reading from disk: "); |
188 | return -1; | 191 | return -1; |
189 | } | 192 | } |
@@ -191,11 +194,14 @@ ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes) | |||
191 | return count; | 194 | return count; |
192 | } | 195 | } |
193 | 196 | ||
194 | ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes) | 197 | ssize_t ipod_write(struct ipod_t* ipod, int nbytes) |
195 | { | 198 | { |
196 | unsigned long count; | 199 | unsigned long count; |
197 | 200 | ||
198 | if (!WriteFile(ipod->dh, buf, nbytes, &count, NULL)) { | 201 | if(ipod->sectorbuf == NULL) { |
202 | return -1; | ||
203 | } | ||
204 | if (!WriteFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) { | ||
199 | ipod_print_error(" Error writing to disk: "); | 205 | ipod_print_error(" Error writing to disk: "); |
200 | return -1; | 206 | return -1; |
201 | } | 207 | } |
diff --git a/rbutil/ipodpatcher/ipodio.h b/rbutil/ipodpatcher/ipodio.h index e08d74a785..8a2f06cf20 100644 --- a/rbutil/ipodpatcher/ipodio.h +++ b/rbutil/ipodpatcher/ipodio.h | |||
@@ -70,6 +70,7 @@ struct partinfo_t { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct ipod_t { | 72 | struct ipod_t { |
73 | unsigned char* sectorbuf; | ||
73 | HANDLE dh; | 74 | HANDLE dh; |
74 | char diskname[4096]; | 75 | char diskname[4096]; |
75 | int sector_size; | 76 | int sector_size; |
@@ -103,9 +104,9 @@ int ipod_close(struct ipod_t* ipod); | |||
103 | int ipod_seek(struct ipod_t* ipod, unsigned long pos); | 104 | int ipod_seek(struct ipod_t* ipod, unsigned long pos); |
104 | int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, | 105 | int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, |
105 | unsigned char* buf, int bufsize); | 106 | unsigned char* buf, int bufsize); |
106 | ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes); | 107 | ssize_t ipod_read(struct ipod_t* ipod, int nbytes); |
107 | ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes); | 108 | ssize_t ipod_write(struct ipod_t* ipod, int nbytes); |
108 | int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize); | 109 | int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize); |
109 | 110 | ||
110 | /* In fat32format.c */ | 111 | /* In fat32format.c */ |
111 | int format_partition(struct ipod_t* ipod, int partition); | 112 | int format_partition(struct ipod_t* ipod, int partition); |
diff --git a/rbutil/ipodpatcher/ipodpatcher.c b/rbutil/ipodpatcher/ipodpatcher.c index 542e078605..55f501dc6c 100644 --- a/rbutil/ipodpatcher/ipodpatcher.c +++ b/rbutil/ipodpatcher/ipodpatcher.c | |||
@@ -51,7 +51,6 @@ | |||
51 | 51 | ||
52 | int ipod_verbose = 0; | 52 | int ipod_verbose = 0; |
53 | 53 | ||
54 | unsigned char* ipod_sectorbuf = NULL; | ||
55 | 54 | ||
56 | /* The following string appears at the start of the firmware partition */ | 55 | /* The following string appears at the start of the firmware partition */ |
57 | static const char *apple_stop_sign = "{{~~ /-----\\ "\ | 56 | static const char *apple_stop_sign = "{{~~ /-----\\ "\ |
@@ -172,7 +171,12 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
172 | int i; | 171 | int i; |
173 | unsigned long count; | 172 | unsigned long count; |
174 | 173 | ||
175 | count = ipod_read(ipod,ipod_sectorbuf, ipod->sector_size); | 174 | if(ipod->sectorbuf == NULL) { |
175 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
176 | return -1; | ||
177 | } | ||
178 | |||
179 | count = ipod_read(ipod,ipod->sector_size); | ||
176 | 180 | ||
177 | if (count <= 0) { | 181 | if (count <= 0) { |
178 | ipod_print_error(" Error reading from disk: "); | 182 | ipod_print_error(" Error reading from disk: "); |
@@ -181,12 +185,12 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
181 | 185 | ||
182 | memset(ipod->pinfo, 0, sizeof(ipod->pinfo)); | 186 | memset(ipod->pinfo, 0, sizeof(ipod->pinfo)); |
183 | 187 | ||
184 | if ((ipod_sectorbuf[510] == 0x55) && (ipod_sectorbuf[511] == 0xaa)) { | 188 | if ((ipod->sectorbuf[510] == 0x55) && (ipod->sectorbuf[511] == 0xaa)) { |
185 | /* DOS partition table */ | 189 | /* DOS partition table */ |
186 | ipod->macpod = 0; | 190 | ipod->macpod = 0; |
187 | /* parse partitions */ | 191 | /* parse partitions */ |
188 | for ( i = 0; i < 4; i++ ) { | 192 | for ( i = 0; i < 4; i++ ) { |
189 | unsigned char* ptr = ipod_sectorbuf + 0x1be + 16*i; | 193 | unsigned char* ptr = ipod->sectorbuf + 0x1be + 16*i; |
190 | ipod->pinfo[i].type = ptr[4]; | 194 | ipod->pinfo[i].type = ptr[4]; |
191 | ipod->pinfo[i].start = BYTES2INT32(ptr, 8); | 195 | ipod->pinfo[i].start = BYTES2INT32(ptr, 8); |
192 | ipod->pinfo[i].size = BYTES2INT32(ptr, 12); | 196 | ipod->pinfo[i].size = BYTES2INT32(ptr, 12); |
@@ -196,7 +200,7 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
196 | /* not handled yet */ | 200 | /* not handled yet */ |
197 | } | 201 | } |
198 | } | 202 | } |
199 | } else if ((ipod_sectorbuf[0] == 'E') && (ipod_sectorbuf[1] == 'R')) { | 203 | } else if ((ipod->sectorbuf[0] == 'E') && (ipod->sectorbuf[1] == 'R')) { |
200 | /* Apple Partition Map */ | 204 | /* Apple Partition Map */ |
201 | 205 | ||
202 | /* APM parsing code based on the check_mac_partitions() function in | 206 | /* APM parsing code based on the check_mac_partitions() function in |
@@ -205,7 +209,7 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
205 | 209 | ||
206 | int blkNo = 1; | 210 | int blkNo = 1; |
207 | int partBlkCount = 1; | 211 | int partBlkCount = 1; |
208 | int partBlkSizMul = ipod_sectorbuf[2] / 2; | 212 | int partBlkSizMul = ipod->sectorbuf[2] / 2; |
209 | 213 | ||
210 | int pmMapBlkCnt; /* # of blks in partition map */ | 214 | int pmMapBlkCnt; /* # of blks in partition map */ |
211 | int pmPyPartStart; /* physical start blk of partition */ | 215 | int pmPyPartStart; /* physical start blk of partition */ |
@@ -222,7 +226,7 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
222 | return -1; | 226 | return -1; |
223 | } | 227 | } |
224 | 228 | ||
225 | count = ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 229 | count = ipod_read(ipod, ipod->sector_size); |
226 | 230 | ||
227 | if (count <= 0) { | 231 | if (count <= 0) { |
228 | ipod_print_error(" Error reading from disk: "); | 232 | ipod_print_error(" Error reading from disk: "); |
@@ -230,26 +234,26 @@ int read_partinfo(struct ipod_t* ipod, int silent) | |||
230 | } | 234 | } |
231 | 235 | ||
232 | /* see if it's a partition entry */ | 236 | /* see if it's a partition entry */ |
233 | if ((ipod_sectorbuf[0] != 'P') || (ipod_sectorbuf[1] != 'M')) { | 237 | if ((ipod->sectorbuf[0] != 'P') || (ipod->sectorbuf[1] != 'M')) { |
234 | /* end of partition table -> leave the loop */ | 238 | /* end of partition table -> leave the loop */ |
235 | break; | 239 | break; |
236 | } | 240 | } |
237 | 241 | ||
238 | /* Extract the interesting entries */ | 242 | /* Extract the interesting entries */ |
239 | pmMapBlkCnt = be2int(ipod_sectorbuf + 4); | 243 | pmMapBlkCnt = be2int(ipod->sectorbuf + 4); |
240 | pmPyPartStart = be2int(ipod_sectorbuf + 8); | 244 | pmPyPartStart = be2int(ipod->sectorbuf + 8); |
241 | pmPartBlkCnt = be2int(ipod_sectorbuf + 12); | 245 | pmPartBlkCnt = be2int(ipod->sectorbuf + 12); |
242 | 246 | ||
243 | /* update the number of part map blocks */ | 247 | /* update the number of part map blocks */ |
244 | partBlkCount = pmMapBlkCnt; | 248 | partBlkCount = pmMapBlkCnt; |
245 | 249 | ||
246 | if (strncmp((char*)(ipod_sectorbuf + 48), "Apple_MDFW", 32)==0) { | 250 | if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_MDFW", 32)==0) { |
247 | /* A Firmware partition */ | 251 | /* A Firmware partition */ |
248 | ipod->pinfo[i].start = pmPyPartStart; | 252 | ipod->pinfo[i].start = pmPyPartStart; |
249 | ipod->pinfo[i].size = pmPartBlkCnt; | 253 | ipod->pinfo[i].size = pmPartBlkCnt; |
250 | ipod->pinfo[i].type = 0; | 254 | ipod->pinfo[i].type = 0; |
251 | i++; | 255 | i++; |
252 | } else if (strncmp((char*)(ipod_sectorbuf + 48), "Apple_HFS", 32)==0) { | 256 | } else if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_HFS", 32)==0) { |
253 | /* A HFS partition */ | 257 | /* A HFS partition */ |
254 | ipod->pinfo[i].start = pmPyPartStart; | 258 | ipod->pinfo[i].start = pmPyPartStart; |
255 | ipod->pinfo[i].size = pmPartBlkCnt; | 259 | ipod->pinfo[i].size = pmPartBlkCnt; |
@@ -290,6 +294,10 @@ int read_partition(struct ipod_t* ipod, int outfile) | |||
290 | if (ipod_seek(ipod, ipod->start) < 0) { | 294 | if (ipod_seek(ipod, ipod->start) < 0) { |
291 | return -1; | 295 | return -1; |
292 | } | 296 | } |
297 | if(ipod->sectorbuf == NULL) { | ||
298 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
299 | return -1; | ||
300 | } | ||
293 | 301 | ||
294 | fprintf(stderr,"[INFO] Writing %d sectors to output file\n",count); | 302 | fprintf(stderr,"[INFO] Writing %d sectors to output file\n",count); |
295 | 303 | ||
@@ -301,7 +309,7 @@ int read_partition(struct ipod_t* ipod, int outfile) | |||
301 | chunksize = bytesleft; | 309 | chunksize = bytesleft; |
302 | } | 310 | } |
303 | 311 | ||
304 | n = ipod_read(ipod, ipod_sectorbuf, chunksize); | 312 | n = ipod_read(ipod, chunksize); |
305 | 313 | ||
306 | if (n < 0) { | 314 | if (n < 0) { |
307 | return -1; | 315 | return -1; |
@@ -316,7 +324,7 @@ int read_partition(struct ipod_t* ipod, int outfile) | |||
316 | 324 | ||
317 | bytesleft -= n; | 325 | bytesleft -= n; |
318 | 326 | ||
319 | res = write(outfile,ipod_sectorbuf,n); | 327 | res = write(outfile,ipod->sectorbuf,n); |
320 | 328 | ||
321 | if (res < 0) { | 329 | if (res < 0) { |
322 | perror("[ERR] write in disk_read"); | 330 | perror("[ERR] write in disk_read"); |
@@ -346,12 +354,16 @@ int write_partition(struct ipod_t* ipod, int infile) | |||
346 | if (ipod_seek(ipod, ipod->start) < 0) { | 354 | if (ipod_seek(ipod, ipod->start) < 0) { |
347 | return -1; | 355 | return -1; |
348 | } | 356 | } |
357 | if(ipod->sectorbuf == NULL) { | ||
358 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
359 | return -1; | ||
360 | } | ||
349 | 361 | ||
350 | fprintf(stderr,"[INFO] Writing input file to device\n"); | 362 | fprintf(stderr,"[INFO] Writing input file to device\n"); |
351 | bytesread = 0; | 363 | bytesread = 0; |
352 | eof = 0; | 364 | eof = 0; |
353 | while (!eof) { | 365 | while (!eof) { |
354 | n = read(infile,ipod_sectorbuf,BUFFER_SIZE); | 366 | n = read(infile,ipod->sectorbuf,BUFFER_SIZE); |
355 | 367 | ||
356 | if (n < 0) { | 368 | if (n < 0) { |
357 | perror("[ERR] read in disk_write"); | 369 | perror("[ERR] read in disk_write"); |
@@ -369,7 +381,7 @@ int write_partition(struct ipod_t* ipod, int infile) | |||
369 | 381 | ||
370 | bytesread += n; | 382 | bytesread += n; |
371 | 383 | ||
372 | res = ipod_write(ipod, ipod_sectorbuf, n); | 384 | res = ipod_write(ipod, n); |
373 | 385 | ||
374 | if (res < 0) { | 386 | if (res < 0) { |
375 | ipod_print_error(" Error writing to disk: "); | 387 | ipod_print_error(" Error writing to disk: "); |
@@ -437,7 +449,7 @@ int diskmove(struct ipod_t* ipod, int delta) | |||
437 | return -1; | 449 | return -1; |
438 | } | 450 | } |
439 | 451 | ||
440 | if ((n = ipod_read(ipod,ipod_sectorbuf,chunksize)) < 0) { | 452 | if ((n = ipod_read(ipod,chunksize)) < 0) { |
441 | perror("[ERR] Write failed\n"); | 453 | perror("[ERR] Write failed\n"); |
442 | return -1; | 454 | return -1; |
443 | } | 455 | } |
@@ -453,7 +465,7 @@ int diskmove(struct ipod_t* ipod, int delta) | |||
453 | return -1; | 465 | return -1; |
454 | } | 466 | } |
455 | 467 | ||
456 | if ((n = ipod_write(ipod,ipod_sectorbuf,chunksize)) < 0) { | 468 | if ((n = ipod_write(ipod,chunksize)) < 0) { |
457 | perror("[ERR] Write failed\n"); | 469 | perror("[ERR] Write failed\n"); |
458 | return -1; | 470 | return -1; |
459 | } | 471 | } |
@@ -482,19 +494,23 @@ static int rename_image(struct ipod_t* ipod, char* from, char* to) | |||
482 | /* diroffset may not be sector-aligned */ | 494 | /* diroffset may not be sector-aligned */ |
483 | x = ipod->diroffset % ipod->sector_size; | 495 | x = ipod->diroffset % ipod->sector_size; |
484 | 496 | ||
497 | if(ipod->sectorbuf == NULL) { | ||
498 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
499 | return -1; | ||
500 | } | ||
485 | /* Read directory */ | 501 | /* Read directory */ |
486 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { | 502 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { |
487 | fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); | 503 | fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); |
488 | return -1; | 504 | return -1; |
489 | } | 505 | } |
490 | 506 | ||
491 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 507 | n=ipod_read(ipod, ipod->sector_size); |
492 | if (n < 0) { | 508 | if (n < 0) { |
493 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 509 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
494 | return -1; | 510 | return -1; |
495 | } | 511 | } |
496 | 512 | ||
497 | p = ipod_sectorbuf + x; | 513 | p = ipod->sectorbuf + x; |
498 | 514 | ||
499 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ | 515 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ |
500 | if (p[0] == 0) | 516 | if (p[0] == 0) |
@@ -502,12 +518,12 @@ static int rename_image(struct ipod_t* ipod, char* from, char* to) | |||
502 | /* Adjust diroffset */ | 518 | /* Adjust diroffset */ |
503 | ipod->diroffset += ipod->sector_size - x; | 519 | ipod->diroffset += ipod->sector_size - x; |
504 | 520 | ||
505 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 521 | n=ipod_read(ipod, ipod->sector_size); |
506 | if (n < 0) { | 522 | if (n < 0) { |
507 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 523 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
508 | return -1; | 524 | return -1; |
509 | } | 525 | } |
510 | p = ipod_sectorbuf; | 526 | p = ipod->sectorbuf; |
511 | } | 527 | } |
512 | 528 | ||
513 | found = 0; | 529 | found = 0; |
@@ -531,7 +547,7 @@ static int rename_image(struct ipod_t* ipod, char* from, char* to) | |||
531 | return -1; | 547 | return -1; |
532 | } | 548 | } |
533 | 549 | ||
534 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 550 | n=ipod_write(ipod, ipod->sector_size); |
535 | if (n < 0) { | 551 | if (n < 0) { |
536 | fprintf(stderr,"[ERR] Write of directory failed in rename_image.\n"); | 552 | fprintf(stderr,"[ERR] Write of directory failed in rename_image.\n"); |
537 | return -1; | 553 | return -1; |
@@ -557,13 +573,13 @@ static int delete_image(struct ipod_t* ipod, char* name) | |||
557 | return -1; | 573 | return -1; |
558 | } | 574 | } |
559 | 575 | ||
560 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 576 | n=ipod_read(ipod, ipod->sector_size); |
561 | if (n < 0) { | 577 | if (n < 0) { |
562 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 578 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
563 | return -1; | 579 | return -1; |
564 | } | 580 | } |
565 | 581 | ||
566 | p = ipod_sectorbuf + x; | 582 | p = ipod->sectorbuf + x; |
567 | 583 | ||
568 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ | 584 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ |
569 | if (p[0] == 0) | 585 | if (p[0] == 0) |
@@ -571,12 +587,12 @@ static int delete_image(struct ipod_t* ipod, char* name) | |||
571 | /* Adjust diroffset */ | 587 | /* Adjust diroffset */ |
572 | ipod->diroffset += ipod->sector_size - x; | 588 | ipod->diroffset += ipod->sector_size - x; |
573 | 589 | ||
574 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 590 | n=ipod_read(ipod, ipod->sector_size); |
575 | if (n < 0) { | 591 | if (n < 0) { |
576 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 592 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
577 | return -1; | 593 | return -1; |
578 | } | 594 | } |
579 | p = ipod_sectorbuf; | 595 | p = ipod->sectorbuf; |
580 | } | 596 | } |
581 | 597 | ||
582 | found = 0; | 598 | found = 0; |
@@ -599,7 +615,7 @@ static int delete_image(struct ipod_t* ipod, char* name) | |||
599 | return -1; | 615 | return -1; |
600 | } | 616 | } |
601 | 617 | ||
602 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 618 | n=ipod_write(ipod, ipod->sector_size); |
603 | if (n < 0) { | 619 | if (n < 0) { |
604 | fprintf(stderr,"[ERR] Write of directory failed in delete_image.\n"); | 620 | fprintf(stderr,"[ERR] Write of directory failed in delete_image.\n"); |
605 | return -1; | 621 | return -1; |
@@ -623,6 +639,10 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
623 | unsigned char header[8]; /* Header for .ipod file */ | 639 | unsigned char header[8]; /* Header for .ipod file */ |
624 | unsigned char* p; | 640 | unsigned char* p; |
625 | 641 | ||
642 | if(ipod->sectorbuf == NULL) { | ||
643 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
644 | return -1; | ||
645 | } | ||
626 | #ifdef WITH_BOOTOBJS | 646 | #ifdef WITH_BOOTOBJS |
627 | if (type == FILETYPE_INTERNAL) { | 647 | if (type == FILETYPE_INTERNAL) { |
628 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); | 648 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); |
@@ -677,14 +697,14 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
677 | 697 | ||
678 | #ifdef WITH_BOOTOBJS | 698 | #ifdef WITH_BOOTOBJS |
679 | if (type == FILETYPE_INTERNAL) { | 699 | if (type == FILETYPE_INTERNAL) { |
680 | memcpy(ipod_sectorbuf,ipod->bootloader,ipod->bootloader_len); | 700 | memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len); |
681 | } | 701 | } |
682 | else | 702 | else |
683 | #endif | 703 | #endif |
684 | { | 704 | { |
685 | fprintf(stderr,"[INFO] Reading input file...\n"); | 705 | fprintf(stderr,"[INFO] Reading input file...\n"); |
686 | 706 | ||
687 | n = read(infile,ipod_sectorbuf,length); | 707 | n = read(infile,ipod->sectorbuf,length); |
688 | if (n < 0) { | 708 | if (n < 0) { |
689 | fprintf(stderr,"[ERR] Couldn't read input file\n"); | 709 | fprintf(stderr,"[ERR] Couldn't read input file\n"); |
690 | close(infile); | 710 | close(infile); |
@@ -694,13 +714,13 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
694 | } | 714 | } |
695 | 715 | ||
696 | /* Pad the data with zeros */ | 716 | /* Pad the data with zeros */ |
697 | memset(ipod_sectorbuf+length,0,newsize-length); | 717 | memset(ipod->sectorbuf+length,0,newsize-length); |
698 | 718 | ||
699 | if (type==FILETYPE_DOT_IPOD) { | 719 | if (type==FILETYPE_DOT_IPOD) { |
700 | chksum = ipod->modelnum; | 720 | chksum = ipod->modelnum; |
701 | for (i = 0; i < length; i++) { | 721 | for (i = 0; i < length; i++) { |
702 | /* add 8 unsigned bits but keep a 32 bit sum */ | 722 | /* add 8 unsigned bits but keep a 32 bit sum */ |
703 | chksum += ipod_sectorbuf[i]; | 723 | chksum += ipod->sectorbuf[i]; |
704 | } | 724 | } |
705 | 725 | ||
706 | if (chksum == filechksum) { | 726 | if (chksum == filechksum) { |
@@ -725,7 +745,7 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
725 | return -1; | 745 | return -1; |
726 | } | 746 | } |
727 | 747 | ||
728 | if ((n = ipod_write(ipod,ipod_sectorbuf,newsize)) < 0) { | 748 | if ((n = ipod_write(ipod,newsize)) < 0) { |
729 | perror("[ERR] Write failed\n"); | 749 | perror("[ERR] Write failed\n"); |
730 | return -1; | 750 | return -1; |
731 | } | 751 | } |
@@ -748,7 +768,7 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
748 | chksum = 0; | 768 | chksum = 0; |
749 | for (i = 0; i < length; i++) { | 769 | for (i = 0; i < length; i++) { |
750 | /* add 8 unsigned bits but keep a 32 bit sum */ | 770 | /* add 8 unsigned bits but keep a 32 bit sum */ |
751 | chksum += ipod_sectorbuf[i]; | 771 | chksum += ipod->sectorbuf[i]; |
752 | } | 772 | } |
753 | 773 | ||
754 | x = ipod->diroffset % ipod->sector_size; | 774 | x = ipod->diroffset % ipod->sector_size; |
@@ -756,13 +776,13 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
756 | /* Read directory */ | 776 | /* Read directory */ |
757 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 777 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
758 | 778 | ||
759 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 779 | n=ipod_read(ipod, ipod->sector_size); |
760 | if (n < 0) { return -1; } | 780 | if (n < 0) { return -1; } |
761 | 781 | ||
762 | /* Create a new directory entry */ | 782 | /* Create a new directory entry */ |
763 | 783 | ||
764 | /* Copy OSOS or OSBK details - we assume one of them exists */ | 784 | /* Copy OSOS or OSBK details - we assume one of them exists */ |
765 | p = ipod_sectorbuf + x; | 785 | p = ipod->sectorbuf + x; |
766 | found = 0; | 786 | found = 0; |
767 | for (i = 0; !found && i < ipod->nimages; i++) { | 787 | for (i = 0; !found && i < ipod->nimages; i++) { |
768 | if ((memcmp(p + 4, "soso", 4)==0) || (memcmp(p + 4, "kbso", 4)==0)) { | 788 | if ((memcmp(p + 4, "soso", 4)==0) || (memcmp(p + 4, "kbso", 4)==0)) { |
@@ -778,8 +798,8 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
778 | } | 798 | } |
779 | 799 | ||
780 | /* Copy directory image */ | 800 | /* Copy directory image */ |
781 | memcpy(ipod_sectorbuf + x + (ipod->nimages * 40), p, 40); | 801 | memcpy(ipod->sectorbuf + x + (ipod->nimages * 40), p, 40); |
782 | p = ipod_sectorbuf + x + (ipod->nimages * 40); | 802 | p = ipod->sectorbuf + x + (ipod->nimages * 40); |
783 | 803 | ||
784 | /* Modify directory. */ | 804 | /* Modify directory. */ |
785 | memcpy(p + 4, imagename, 4); | 805 | memcpy(p + 4, imagename, 4); |
@@ -789,7 +809,7 @@ int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type | |||
789 | 809 | ||
790 | /* Write directory */ | 810 | /* Write directory */ |
791 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 811 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
792 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 812 | n=ipod_write(ipod, ipod->sector_size); |
793 | if (n < 0) { return -1; } | 813 | if (n < 0) { return -1; } |
794 | 814 | ||
795 | return 0; | 815 | return 0; |
@@ -895,6 +915,10 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
895 | if (ipod->modelnum == 62) { | 915 | if (ipod->modelnum == 62) { |
896 | return add_bootloader_nano2g(ipod, filename, type); | 916 | return add_bootloader_nano2g(ipod, filename, type); |
897 | } | 917 | } |
918 | if(ipod->sectorbuf == NULL) { | ||
919 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
920 | return -1; | ||
921 | } | ||
898 | 922 | ||
899 | /* Calculate the position in the OSOS image where our bootloader will go. */ | 923 | /* Calculate the position in the OSOS image where our bootloader will go. */ |
900 | if (ipod->ipod_directory[0].entryOffset>0) { | 924 | if (ipod->ipod_directory[0].entryOffset>0) { |
@@ -907,7 +931,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
907 | #ifdef WITH_BOOTOBJS | 931 | #ifdef WITH_BOOTOBJS |
908 | if (type == FILETYPE_INTERNAL) { | 932 | if (type == FILETYPE_INTERNAL) { |
909 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); | 933 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); |
910 | memcpy(ipod_sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); | 934 | memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); |
911 | length = ipod->bootloader_len; | 935 | length = ipod->bootloader_len; |
912 | paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1); | 936 | paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1); |
913 | } | 937 | } |
@@ -1005,14 +1029,14 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
1005 | 1029 | ||
1006 | /* We have moved the partitions, now we can write our bootloader */ | 1030 | /* We have moved the partitions, now we can write our bootloader */ |
1007 | 1031 | ||
1008 | /* Firstly read the original firmware into ipod_sectorbuf */ | 1032 | /* Firstly read the original firmware into ipod->sectorbuf */ |
1009 | fprintf(stderr,"[INFO] Reading original firmware...\n"); | 1033 | fprintf(stderr,"[INFO] Reading original firmware...\n"); |
1010 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { | 1034 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { |
1011 | fprintf(stderr,"[ERR] Seek failed\n"); | 1035 | fprintf(stderr,"[ERR] Seek failed\n"); |
1012 | return -1; | 1036 | return -1; |
1013 | } | 1037 | } |
1014 | 1038 | ||
1015 | if ((n = ipod_read(ipod,ipod_sectorbuf,entryOffset)) < 0) { | 1039 | if ((n = ipod_read(ipod,entryOffset)) < 0) { |
1016 | perror("[ERR] Read failed\n"); | 1040 | perror("[ERR] Read failed\n"); |
1017 | return -1; | 1041 | return -1; |
1018 | } | 1042 | } |
@@ -1025,19 +1049,19 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
1025 | 1049 | ||
1026 | #ifdef WITH_BOOTOBJS | 1050 | #ifdef WITH_BOOTOBJS |
1027 | if (type == FILETYPE_INTERNAL) { | 1051 | if (type == FILETYPE_INTERNAL) { |
1028 | memcpy(ipod_sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); | 1052 | memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); |
1029 | } | 1053 | } |
1030 | else | 1054 | else |
1031 | #endif | 1055 | #endif |
1032 | { | 1056 | { |
1033 | memcpy(ipod_sectorbuf+entryOffset,bootloader_buf,length); | 1057 | memcpy(ipod->sectorbuf+entryOffset,bootloader_buf,length); |
1034 | free(bootloader_buf); | 1058 | free(bootloader_buf); |
1035 | } | 1059 | } |
1036 | 1060 | ||
1037 | /* Calculate new checksum for combined image */ | 1061 | /* Calculate new checksum for combined image */ |
1038 | chksum = 0; | 1062 | chksum = 0; |
1039 | for (i=0;i<entryOffset + length; i++) { | 1063 | for (i=0;i<entryOffset + length; i++) { |
1040 | chksum += ipod_sectorbuf[i]; | 1064 | chksum += ipod->sectorbuf[i]; |
1041 | } | 1065 | } |
1042 | 1066 | ||
1043 | /* Now write the combined firmware image to the disk */ | 1067 | /* Now write the combined firmware image to the disk */ |
@@ -1047,7 +1071,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
1047 | return -1; | 1071 | return -1; |
1048 | } | 1072 | } |
1049 | 1073 | ||
1050 | if ((n = ipod_write(ipod,ipod_sectorbuf,entryOffset+paddedlength)) < 0) { | 1074 | if ((n = ipod_write(ipod,entryOffset+paddedlength)) < 0) { |
1051 | perror("[ERR] Write failed\n"); | 1075 | perror("[ERR] Write failed\n"); |
1052 | return -1; | 1076 | return -1; |
1053 | } | 1077 | } |
@@ -1068,22 +1092,22 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
1068 | return -1; | 1092 | return -1; |
1069 | } | 1093 | } |
1070 | 1094 | ||
1071 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1095 | n=ipod_read(ipod, ipod->sector_size); |
1072 | if (n < 0) { | 1096 | if (n < 0) { |
1073 | fprintf(stderr,"[ERR] Directory read failed\n"); | 1097 | fprintf(stderr,"[ERR] Directory read failed\n"); |
1074 | return -1; | 1098 | return -1; |
1075 | } | 1099 | } |
1076 | 1100 | ||
1077 | /* Update entries for image 0 */ | 1101 | /* Update entries for image 0 */ |
1078 | int2le(entryOffset+length,ipod_sectorbuf+x+16); | 1102 | int2le(entryOffset+length,ipod->sectorbuf+x+16); |
1079 | int2le(entryOffset,ipod_sectorbuf+x+24); | 1103 | int2le(entryOffset,ipod->sectorbuf+x+24); |
1080 | int2le(chksum,ipod_sectorbuf+x+28); | 1104 | int2le(chksum,ipod->sectorbuf+x+28); |
1081 | int2le(0xffffffff,ipod_sectorbuf+x+36); /* loadAddr */ | 1105 | int2le(0xffffffff,ipod->sectorbuf+x+36); /* loadAddr */ |
1082 | 1106 | ||
1083 | /* Update devOffset entries for other images, if we have moved them */ | 1107 | /* Update devOffset entries for other images, if we have moved them */ |
1084 | if (delta > 0) { | 1108 | if (delta > 0) { |
1085 | for (i=1;i<ipod->nimages;i++) { | 1109 | for (i=1;i<ipod->nimages;i++) { |
1086 | int2le(le2int(ipod_sectorbuf+x+i*40+12)+delta,ipod_sectorbuf+x+i*40+12); | 1110 | int2le(le2int(ipod->sectorbuf+x+i*40+12)+delta,ipod->sectorbuf+x+i*40+12); |
1087 | } | 1111 | } |
1088 | } | 1112 | } |
1089 | 1113 | ||
@@ -1092,7 +1116,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) | |||
1092 | fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x)); | 1116 | fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x)); |
1093 | return -1; | 1117 | return -1; |
1094 | } | 1118 | } |
1095 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 1119 | n=ipod_write(ipod, ipod->sector_size); |
1096 | if (n < 0) { | 1120 | if (n < 0) { |
1097 | fprintf(stderr,"[ERR] Directory write failed\n"); | 1121 | fprintf(stderr,"[ERR] Directory write failed\n"); |
1098 | return -1; | 1122 | return -1; |
@@ -1113,6 +1137,10 @@ int delete_bootloader(struct ipod_t* ipod) | |||
1113 | if (ipod->modelnum == 62) { | 1137 | if (ipod->modelnum == 62) { |
1114 | return delete_bootloader_nano2g(ipod); | 1138 | return delete_bootloader_nano2g(ipod); |
1115 | } | 1139 | } |
1140 | if(ipod->sectorbuf == NULL) { | ||
1141 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
1142 | return -1; | ||
1143 | } | ||
1116 | 1144 | ||
1117 | /* Removing the bootloader involves adjusting the "length", | 1145 | /* Removing the bootloader involves adjusting the "length", |
1118 | "chksum" and "entryOffset" values in the osos image's directory | 1146 | "chksum" and "entryOffset" values in the osos image's directory |
@@ -1138,7 +1166,7 @@ int delete_bootloader(struct ipod_t* ipod) | |||
1138 | fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n", | 1166 | fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n", |
1139 | length,i); | 1167 | length,i); |
1140 | 1168 | ||
1141 | if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) { | 1169 | if ((n = ipod_read(ipod,i)) < 0) { |
1142 | return -1; | 1170 | return -1; |
1143 | } | 1171 | } |
1144 | 1172 | ||
@@ -1151,7 +1179,7 @@ int delete_bootloader(struct ipod_t* ipod) | |||
1151 | chksum = 0; | 1179 | chksum = 0; |
1152 | for (i = 0; i < length; i++) { | 1180 | for (i = 0; i < length; i++) { |
1153 | /* add 8 unsigned bits but keep a 32 bit sum */ | 1181 | /* add 8 unsigned bits but keep a 32 bit sum */ |
1154 | chksum += ipod_sectorbuf[i]; | 1182 | chksum += ipod->sectorbuf[i]; |
1155 | } | 1183 | } |
1156 | 1184 | ||
1157 | /* Now write back the updated directory entry */ | 1185 | /* Now write back the updated directory entry */ |
@@ -1163,17 +1191,17 @@ int delete_bootloader(struct ipod_t* ipod) | |||
1163 | /* Read directory */ | 1191 | /* Read directory */ |
1164 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 1192 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
1165 | 1193 | ||
1166 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1194 | n=ipod_read(ipod, ipod->sector_size); |
1167 | if (n < 0) { return -1; } | 1195 | if (n < 0) { return -1; } |
1168 | 1196 | ||
1169 | /* Update entries for image 0 */ | 1197 | /* Update entries for image 0 */ |
1170 | int2le(length,ipod_sectorbuf+x+16); | 1198 | int2le(length,ipod->sectorbuf+x+16); |
1171 | int2le(0,ipod_sectorbuf+x+24); | 1199 | int2le(0,ipod->sectorbuf+x+24); |
1172 | int2le(chksum,ipod_sectorbuf+x+28); | 1200 | int2le(chksum,ipod->sectorbuf+x+28); |
1173 | 1201 | ||
1174 | /* Write directory */ | 1202 | /* Write directory */ |
1175 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 1203 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
1176 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 1204 | n=ipod_write(ipod, ipod->sector_size); |
1177 | if (n < 0) { return -1; } | 1205 | if (n < 0) { return -1; } |
1178 | 1206 | ||
1179 | return 0; | 1207 | return 0; |
@@ -1194,6 +1222,10 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1194 | unsigned char header[8]; /* Header for .ipod file */ | 1222 | unsigned char header[8]; /* Header for .ipod file */ |
1195 | unsigned char* p; | 1223 | unsigned char* p; |
1196 | 1224 | ||
1225 | if(ipod->sectorbuf == NULL) { | ||
1226 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
1227 | return -1; | ||
1228 | } | ||
1197 | #ifdef WITH_BOOTOBJS | 1229 | #ifdef WITH_BOOTOBJS |
1198 | if (type == FILETYPE_INTERNAL) { | 1230 | if (type == FILETYPE_INTERNAL) { |
1199 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); | 1231 | fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); |
@@ -1260,14 +1292,14 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1260 | 1292 | ||
1261 | #ifdef WITH_BOOTOBJS | 1293 | #ifdef WITH_BOOTOBJS |
1262 | if (type == FILETYPE_INTERNAL) { | 1294 | if (type == FILETYPE_INTERNAL) { |
1263 | memcpy(ipod_sectorbuf,ipod->bootloader,ipod->bootloader_len); | 1295 | memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len); |
1264 | } | 1296 | } |
1265 | else | 1297 | else |
1266 | #endif | 1298 | #endif |
1267 | { | 1299 | { |
1268 | fprintf(stderr,"[INFO] Reading input file...\n"); | 1300 | fprintf(stderr,"[INFO] Reading input file...\n"); |
1269 | /* We now know we have enough space, so write it. */ | 1301 | /* We now know we have enough space, so write it. */ |
1270 | n = read(infile,ipod_sectorbuf,length); | 1302 | n = read(infile,ipod->sectorbuf,length); |
1271 | if (n < 0) { | 1303 | if (n < 0) { |
1272 | fprintf(stderr,"[ERR] Couldn't read input file\n"); | 1304 | fprintf(stderr,"[ERR] Couldn't read input file\n"); |
1273 | close(infile); | 1305 | close(infile); |
@@ -1277,13 +1309,13 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1277 | } | 1309 | } |
1278 | 1310 | ||
1279 | /* Pad the data with zeros */ | 1311 | /* Pad the data with zeros */ |
1280 | memset(ipod_sectorbuf+length,0,newsize-length); | 1312 | memset(ipod->sectorbuf+length,0,newsize-length); |
1281 | 1313 | ||
1282 | if (type==FILETYPE_DOT_IPOD) { | 1314 | if (type==FILETYPE_DOT_IPOD) { |
1283 | chksum = ipod->modelnum; | 1315 | chksum = ipod->modelnum; |
1284 | for (i = 0; i < length; i++) { | 1316 | for (i = 0; i < length; i++) { |
1285 | /* add 8 unsigned bits but keep a 32 bit sum */ | 1317 | /* add 8 unsigned bits but keep a 32 bit sum */ |
1286 | chksum += ipod_sectorbuf[i]; | 1318 | chksum += ipod->sectorbuf[i]; |
1287 | } | 1319 | } |
1288 | 1320 | ||
1289 | if (chksum == filechksum) { | 1321 | if (chksum == filechksum) { |
@@ -1315,7 +1347,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1315 | return -1; | 1347 | return -1; |
1316 | } | 1348 | } |
1317 | 1349 | ||
1318 | if ((n = ipod_write(ipod,ipod_sectorbuf,newsize)) < 0) { | 1350 | if ((n = ipod_write(ipod,newsize)) < 0) { |
1319 | perror("[ERR] Write failed\n"); | 1351 | perror("[ERR] Write failed\n"); |
1320 | return -1; | 1352 | return -1; |
1321 | } | 1353 | } |
@@ -1338,7 +1370,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1338 | chksum = 0; | 1370 | chksum = 0; |
1339 | for (i = 0; i < length; i++) { | 1371 | for (i = 0; i < length; i++) { |
1340 | /* add 8 unsigned bits but keep a 32 bit sum */ | 1372 | /* add 8 unsigned bits but keep a 32 bit sum */ |
1341 | chksum += ipod_sectorbuf[i]; | 1373 | chksum += ipod->sectorbuf[i]; |
1342 | } | 1374 | } |
1343 | 1375 | ||
1344 | x = ipod->diroffset % ipod->sector_size; | 1376 | x = ipod->diroffset % ipod->sector_size; |
@@ -1346,18 +1378,18 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1346 | /* Read directory */ | 1378 | /* Read directory */ |
1347 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 1379 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
1348 | 1380 | ||
1349 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1381 | n=ipod_read(ipod, ipod->sector_size); |
1350 | if (n < 0) { return -1; } | 1382 | if (n < 0) { return -1; } |
1351 | 1383 | ||
1352 | /* Update entries for image */ | 1384 | /* Update entries for image */ |
1353 | p = ipod_sectorbuf + x + (ipod->ososimage * 40); | 1385 | p = ipod->sectorbuf + x + (ipod->ososimage * 40); |
1354 | int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16); | 1386 | int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16); |
1355 | int2le(0, p + 24); | 1387 | int2le(0, p + 24); |
1356 | int2le(chksum, p + 28); | 1388 | int2le(chksum, p + 28); |
1357 | 1389 | ||
1358 | /* Write directory */ | 1390 | /* Write directory */ |
1359 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 1391 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
1360 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 1392 | n=ipod_write(ipod, ipod->sector_size); |
1361 | if (n < 0) { return -1; } | 1393 | if (n < 0) { return -1; } |
1362 | 1394 | ||
1363 | return 0; | 1395 | return 0; |
@@ -1373,6 +1405,10 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1373 | unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/ | 1405 | unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/ |
1374 | unsigned char header[8]; /* Header for .ipod file */ | 1406 | unsigned char header[8]; /* Header for .ipod file */ |
1375 | 1407 | ||
1408 | if(ipod->sectorbuf == NULL) { | ||
1409 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
1410 | return -1; | ||
1411 | } | ||
1376 | if (ipod->ipod_directory[ipod->ososimage].entryOffset != 0) { | 1412 | if (ipod->ipod_directory[ipod->ososimage].entryOffset != 0) { |
1377 | /* We have a bootloader... */ | 1413 | /* We have a bootloader... */ |
1378 | length = ipod->ipod_directory[ipod->ososimage].entryOffset; | 1414 | length = ipod->ipod_directory[ipod->ososimage].entryOffset; |
@@ -1399,7 +1435,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1399 | return -1; | 1435 | return -1; |
1400 | } | 1436 | } |
1401 | 1437 | ||
1402 | if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) { | 1438 | if ((n = ipod_read(ipod,i)) < 0) { |
1403 | return -1; | 1439 | return -1; |
1404 | } | 1440 | } |
1405 | 1441 | ||
@@ -1419,7 +1455,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1419 | chksum = ipod->modelnum; | 1455 | chksum = ipod->modelnum; |
1420 | for (i = 0; i < length; i++) { | 1456 | for (i = 0; i < length; i++) { |
1421 | /* add 8 unsigned bits but keep a 32 bit sum */ | 1457 | /* add 8 unsigned bits but keep a 32 bit sum */ |
1422 | chksum += ipod_sectorbuf[i]; | 1458 | chksum += ipod->sectorbuf[i]; |
1423 | } | 1459 | } |
1424 | 1460 | ||
1425 | int2be(chksum,header); | 1461 | int2be(chksum,header); |
@@ -1431,7 +1467,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type) | |||
1431 | } | 1467 | } |
1432 | } | 1468 | } |
1433 | 1469 | ||
1434 | n = write(outfile,ipod_sectorbuf,length); | 1470 | n = write(outfile,ipod->sectorbuf,length); |
1435 | if (n != length) { | 1471 | if (n != length) { |
1436 | fprintf(stderr,"[ERR] Write error - %d\n",n); | 1472 | fprintf(stderr,"[ERR] Write error - %d\n",n); |
1437 | } | 1473 | } |
@@ -1458,28 +1494,28 @@ int read_directory(struct ipod_t* ipod) | |||
1458 | return -1; | 1494 | return -1; |
1459 | } | 1495 | } |
1460 | 1496 | ||
1461 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1497 | n=ipod_read(ipod, ipod->sector_size); |
1462 | if (n < 0) { | 1498 | if (n < 0) { |
1463 | fprintf(stderr,"[ERR] ipod_read(ipod,buf,0x%08x) failed in read_directory()\n", ipod->sector_size); | 1499 | fprintf(stderr,"[ERR] ipod_read(ipod,0x%08x) failed in read_directory()\n", ipod->sector_size); |
1464 | return -1; | 1500 | return -1; |
1465 | } | 1501 | } |
1466 | 1502 | ||
1467 | if (memcmp(ipod_sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) { | 1503 | if (memcmp(ipod->sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) { |
1468 | fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n"); | 1504 | fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n"); |
1469 | return -1; | 1505 | return -1; |
1470 | } | 1506 | } |
1471 | 1507 | ||
1472 | if (memcmp(ipod_sectorbuf+0x100,"]ih[",4)!=0) { | 1508 | if (memcmp(ipod->sectorbuf+0x100,"]ih[",4)!=0) { |
1473 | fprintf(stderr,"[ERR] Bad firmware directory\n"); | 1509 | fprintf(stderr,"[ERR] Bad firmware directory\n"); |
1474 | return -1; | 1510 | return -1; |
1475 | } | 1511 | } |
1476 | 1512 | ||
1477 | version = le2ushort(ipod_sectorbuf+0x10a); | 1513 | version = le2ushort(ipod->sectorbuf+0x10a); |
1478 | if ((version != 2) && (version != 3)) { | 1514 | if ((version != 2) && (version != 3)) { |
1479 | fprintf(stderr,"[ERR] Unknown firmware format version %04x\n", | 1515 | fprintf(stderr,"[ERR] Unknown firmware format version %04x\n", |
1480 | version); | 1516 | version); |
1481 | } | 1517 | } |
1482 | ipod->diroffset=le2int(ipod_sectorbuf+0x104) + 0x200; | 1518 | ipod->diroffset=le2int(ipod->sectorbuf+0x104) + 0x200; |
1483 | 1519 | ||
1484 | /* diroffset may not be sector-aligned */ | 1520 | /* diroffset may not be sector-aligned */ |
1485 | x = ipod->diroffset % ipod->sector_size; | 1521 | x = ipod->diroffset % ipod->sector_size; |
@@ -1490,13 +1526,13 @@ int read_directory(struct ipod_t* ipod) | |||
1490 | return -1; | 1526 | return -1; |
1491 | } | 1527 | } |
1492 | 1528 | ||
1493 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1529 | n=ipod_read(ipod, ipod->sector_size); |
1494 | if (n < 0) { | 1530 | if (n < 0) { |
1495 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 1531 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
1496 | return -1; | 1532 | return -1; |
1497 | } | 1533 | } |
1498 | 1534 | ||
1499 | p = ipod_sectorbuf + x; | 1535 | p = ipod->sectorbuf + x; |
1500 | 1536 | ||
1501 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ | 1537 | /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ |
1502 | if (p[0] == 0) | 1538 | if (p[0] == 0) |
@@ -1504,16 +1540,16 @@ int read_directory(struct ipod_t* ipod) | |||
1504 | /* Adjust diroffset */ | 1540 | /* Adjust diroffset */ |
1505 | ipod->diroffset += ipod->sector_size - x; | 1541 | ipod->diroffset += ipod->sector_size - x; |
1506 | 1542 | ||
1507 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 1543 | n=ipod_read(ipod, ipod->sector_size); |
1508 | if (n < 0) { | 1544 | if (n < 0) { |
1509 | fprintf(stderr,"[ERR] Read of directory failed.\n"); | 1545 | fprintf(stderr,"[ERR] Read of directory failed.\n"); |
1510 | return -1; | 1546 | return -1; |
1511 | } | 1547 | } |
1512 | p = ipod_sectorbuf; | 1548 | p = ipod->sectorbuf; |
1513 | } | 1549 | } |
1514 | 1550 | ||
1515 | ipod->ososimage = -1; | 1551 | ipod->ososimage = -1; |
1516 | while ((ipod->nimages < MAX_IMAGES) && (p < (ipod_sectorbuf + x + 400)) && | 1552 | while ((ipod->nimages < MAX_IMAGES) && (p < (ipod->sectorbuf + x + 400)) && |
1517 | ((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) { | 1553 | ((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) { |
1518 | p+=4; | 1554 | p+=4; |
1519 | if (memcmp(p,"soso",4)==0) { | 1555 | if (memcmp(p,"soso",4)==0) { |
@@ -1840,14 +1876,18 @@ int write_dos_partition_table(struct ipod_t* ipod) | |||
1840 | fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n"); | 1876 | fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n"); |
1841 | return -1; | 1877 | return -1; |
1842 | } | 1878 | } |
1879 | if(ipod->sectorbuf == NULL) { | ||
1880 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
1881 | return -1; | ||
1882 | } | ||
1843 | 1883 | ||
1844 | /* Firstly zero the entire MBR */ | 1884 | /* Firstly zero the entire MBR */ |
1845 | memset(ipod_sectorbuf, 0, ipod->sector_size); | 1885 | memset(ipod->sectorbuf, 0, ipod->sector_size); |
1846 | 1886 | ||
1847 | /* Now add the partition info */ | 1887 | /* Now add the partition info */ |
1848 | for (i=0; i < 4 ; i++) | 1888 | for (i=0; i < 4 ; i++) |
1849 | { | 1889 | { |
1850 | p = ipod_sectorbuf + 0x1be + i*16; | 1890 | p = ipod->sectorbuf + 0x1be + i*16; |
1851 | 1891 | ||
1852 | /* Ensure first partition is type 0, and second is 0xb */ | 1892 | /* Ensure first partition is type 0, and second is 0xb */ |
1853 | if (i==0) { type = 0; } | 1893 | if (i==0) { type = 0; } |
@@ -1860,8 +1900,8 @@ int write_dos_partition_table(struct ipod_t* ipod) | |||
1860 | } | 1900 | } |
1861 | 1901 | ||
1862 | /* Finally add the magic */ | 1902 | /* Finally add the magic */ |
1863 | ipod_sectorbuf[0x1fe] = 0x55; | 1903 | ipod->sectorbuf[0x1fe] = 0x55; |
1864 | ipod_sectorbuf[0x1ff] = 0xaa; | 1904 | ipod->sectorbuf[0x1ff] = 0xaa; |
1865 | 1905 | ||
1866 | if (ipod_seek(ipod, 0) < 0) { | 1906 | if (ipod_seek(ipod, 0) < 0) { |
1867 | fprintf(stderr,"[ERR] Seek failed writing MBR\n"); | 1907 | fprintf(stderr,"[ERR] Seek failed writing MBR\n"); |
@@ -1869,7 +1909,7 @@ int write_dos_partition_table(struct ipod_t* ipod) | |||
1869 | } | 1909 | } |
1870 | 1910 | ||
1871 | /* Write MBR */ | 1911 | /* Write MBR */ |
1872 | if ((n = ipod_write(ipod, ipod_sectorbuf, ipod->sector_size)) < 0) { | 1912 | if ((n = ipod_write(ipod, ipod->sector_size)) < 0) { |
1873 | perror("[ERR] Write failed\n"); | 1913 | perror("[ERR] Write failed\n"); |
1874 | return -1; | 1914 | return -1; |
1875 | } | 1915 | } |
@@ -2072,16 +2112,20 @@ static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key) | |||
2072 | /* Firstly read the security block and find the RC4 key. This is | 2112 | /* Firstly read the security block and find the RC4 key. This is |
2073 | in the sector preceeding the AUPD image. */ | 2113 | in the sector preceeding the AUPD image. */ |
2074 | 2114 | ||
2115 | if(ipod->sectorbuf == NULL) { | ||
2116 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
2117 | return -1; | ||
2118 | } | ||
2075 | fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size); | 2119 | fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size); |
2076 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) { | 2120 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) { |
2077 | return -1; | 2121 | return -1; |
2078 | } | 2122 | } |
2079 | 2123 | ||
2080 | if ((n = ipod_read(ipod, ipod_sectorbuf, 512)) < 0) { | 2124 | if ((n = ipod_read(ipod, 512)) < 0) { |
2081 | return -1; | 2125 | return -1; |
2082 | } | 2126 | } |
2083 | 2127 | ||
2084 | n = GetSecurityBlockKey(ipod_sectorbuf, key); | 2128 | n = GetSecurityBlockKey(ipod->sectorbuf, key); |
2085 | 2129 | ||
2086 | if (n != 1) | 2130 | if (n != 1) |
2087 | { | 2131 | { |
@@ -2103,6 +2147,10 @@ int read_aupd(struct ipod_t* ipod, char* filename) | |||
2103 | unsigned char key[4]; | 2147 | unsigned char key[4]; |
2104 | unsigned long chksum=0; | 2148 | unsigned long chksum=0; |
2105 | 2149 | ||
2150 | if(ipod->sectorbuf == NULL) { | ||
2151 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
2152 | return -1; | ||
2153 | } | ||
2106 | aupd = 0; | 2154 | aupd = 0; |
2107 | while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) | 2155 | while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) |
2108 | { | 2156 | { |
@@ -2132,7 +2180,7 @@ int read_aupd(struct ipod_t* ipod, char* filename) | |||
2132 | 2180 | ||
2133 | i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); | 2181 | i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); |
2134 | 2182 | ||
2135 | if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) { | 2183 | if ((n = ipod_read(ipod,i)) < 0) { |
2136 | return -1; | 2184 | return -1; |
2137 | } | 2185 | } |
2138 | 2186 | ||
@@ -2144,12 +2192,12 @@ int read_aupd(struct ipod_t* ipod, char* filename) | |||
2144 | 2192 | ||
2145 | /* Perform the decryption - this is standard (A)RC4 */ | 2193 | /* Perform the decryption - this is standard (A)RC4 */ |
2146 | matrixArc4Init(&rc4, key, 4); | 2194 | matrixArc4Init(&rc4, key, 4); |
2147 | matrixArc4(&rc4, ipod_sectorbuf, ipod_sectorbuf, length); | 2195 | matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); |
2148 | 2196 | ||
2149 | chksum = 0; | 2197 | chksum = 0; |
2150 | for (i = 0; i < (int)length; i++) { | 2198 | for (i = 0; i < (int)length; i++) { |
2151 | /* add 8 unsigned bits but keep a 32 bit sum */ | 2199 | /* add 8 unsigned bits but keep a 32 bit sum */ |
2152 | chksum += ipod_sectorbuf[i]; | 2200 | chksum += ipod->sectorbuf[i]; |
2153 | } | 2201 | } |
2154 | 2202 | ||
2155 | if (chksum != ipod->ipod_directory[aupd].chksum) | 2203 | if (chksum != ipod->ipod_directory[aupd].chksum) |
@@ -2165,7 +2213,7 @@ int read_aupd(struct ipod_t* ipod, char* filename) | |||
2165 | return -1; | 2213 | return -1; |
2166 | } | 2214 | } |
2167 | 2215 | ||
2168 | n = write(outfile,ipod_sectorbuf,length); | 2216 | n = write(outfile,ipod->sectorbuf,length); |
2169 | if (n != length) { | 2217 | if (n != length) { |
2170 | fprintf(stderr,"[ERR] Write error - %d\n",n); | 2218 | fprintf(stderr,"[ERR] Write error - %d\n",n); |
2171 | } | 2219 | } |
@@ -2187,6 +2235,10 @@ int write_aupd(struct ipod_t* ipod, char* filename) | |||
2187 | struct rc4_key_t rc4; | 2235 | struct rc4_key_t rc4; |
2188 | unsigned char key[4]; | 2236 | unsigned char key[4]; |
2189 | 2237 | ||
2238 | if(ipod->sectorbuf == NULL) { | ||
2239 | fprintf(stderr,"[ERR] Buffer not initialized."); | ||
2240 | return -1; | ||
2241 | } | ||
2190 | /* First check that the input file is the correct type for this ipod. */ | 2242 | /* First check that the input file is the correct type for this ipod. */ |
2191 | infile=open(filename,O_RDONLY); | 2243 | infile=open(filename,O_RDONLY); |
2192 | if (infile < 0) { | 2244 | if (infile < 0) { |
@@ -2236,7 +2288,7 @@ int write_aupd(struct ipod_t* ipod, char* filename) | |||
2236 | /* We now know we have enough space, so write it. */ | 2288 | /* We now know we have enough space, so write it. */ |
2237 | 2289 | ||
2238 | fprintf(stderr,"[INFO] Reading input file...\n"); | 2290 | fprintf(stderr,"[INFO] Reading input file...\n"); |
2239 | n = read(infile,ipod_sectorbuf,length); | 2291 | n = read(infile,ipod->sectorbuf,length); |
2240 | if (n < 0) { | 2292 | if (n < 0) { |
2241 | fprintf(stderr,"[ERR] Couldn't read input file\n"); | 2293 | fprintf(stderr,"[ERR] Couldn't read input file\n"); |
2242 | close(infile); | 2294 | close(infile); |
@@ -2245,25 +2297,25 @@ int write_aupd(struct ipod_t* ipod, char* filename) | |||
2245 | close(infile); | 2297 | close(infile); |
2246 | 2298 | ||
2247 | /* Pad the data with zeros */ | 2299 | /* Pad the data with zeros */ |
2248 | memset(ipod_sectorbuf+length,0,newsize-length); | 2300 | memset(ipod->sectorbuf+length,0,newsize-length); |
2249 | 2301 | ||
2250 | /* Calculate the new checksum (before we encrypt) */ | 2302 | /* Calculate the new checksum (before we encrypt) */ |
2251 | chksum = 0; | 2303 | chksum = 0; |
2252 | for (i = 0; i < (int)length; i++) { | 2304 | for (i = 0; i < (int)length; i++) { |
2253 | /* add 8 unsigned bits but keep a 32 bit sum */ | 2305 | /* add 8 unsigned bits but keep a 32 bit sum */ |
2254 | chksum += ipod_sectorbuf[i]; | 2306 | chksum += ipod->sectorbuf[i]; |
2255 | } | 2307 | } |
2256 | 2308 | ||
2257 | /* Perform the encryption - this is standard (A)RC4 */ | 2309 | /* Perform the encryption - this is standard (A)RC4 */ |
2258 | matrixArc4Init(&rc4, key, 4); | 2310 | matrixArc4Init(&rc4, key, 4); |
2259 | matrixArc4(&rc4, ipod_sectorbuf, ipod_sectorbuf, length); | 2311 | matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); |
2260 | 2312 | ||
2261 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { | 2313 | if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { |
2262 | fprintf(stderr,"[ERR] Seek failed\n"); | 2314 | fprintf(stderr,"[ERR] Seek failed\n"); |
2263 | return -1; | 2315 | return -1; |
2264 | } | 2316 | } |
2265 | 2317 | ||
2266 | if ((n = ipod_write(ipod,ipod_sectorbuf,newsize)) < 0) { | 2318 | if ((n = ipod_write(ipod,newsize)) < 0) { |
2267 | perror("[ERR] Write failed\n"); | 2319 | perror("[ERR] Write failed\n"); |
2268 | return -1; | 2320 | return -1; |
2269 | } | 2321 | } |
@@ -2280,16 +2332,16 @@ int write_aupd(struct ipod_t* ipod, char* filename) | |||
2280 | /* Read directory */ | 2332 | /* Read directory */ |
2281 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 2333 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
2282 | 2334 | ||
2283 | n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size); | 2335 | n=ipod_read(ipod, ipod->sector_size); |
2284 | if (n < 0) { return -1; } | 2336 | if (n < 0) { return -1; } |
2285 | 2337 | ||
2286 | /* Update checksum */ | 2338 | /* Update checksum */ |
2287 | fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod_sectorbuf + x + aupd*40 + 28)); | 2339 | fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod->sectorbuf + x + aupd*40 + 28)); |
2288 | int2le(chksum,ipod_sectorbuf+x+aupd*40+28); | 2340 | int2le(chksum,ipod->sectorbuf+x+aupd*40+28); |
2289 | 2341 | ||
2290 | /* Write directory */ | 2342 | /* Write directory */ |
2291 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } | 2343 | if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } |
2292 | n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size); | 2344 | n=ipod_write(ipod, ipod->sector_size); |
2293 | if (n < 0) { return -1; } | 2345 | if (n < 0) { return -1; } |
2294 | 2346 | ||
2295 | return 0; | 2347 | return 0; |
diff --git a/rbutil/ipodpatcher/ipodpatcher.h b/rbutil/ipodpatcher/ipodpatcher.h index dc3f100520..01f5a1bb26 100644 --- a/rbutil/ipodpatcher/ipodpatcher.h +++ b/rbutil/ipodpatcher/ipodpatcher.h | |||
@@ -32,16 +32,6 @@ extern "C" { | |||
32 | of the Apple firmware, but not the Nano's RSRC image. */ | 32 | of the Apple firmware, but not the Nano's RSRC image. */ |
33 | #define BUFFER_SIZE 8*1024*1024 | 33 | #define BUFFER_SIZE 8*1024*1024 |
34 | 34 | ||
35 | #ifndef _MSC_VER | ||
36 | extern unsigned char* ipod_sectorbuf; | ||
37 | #else | ||
38 | /* MSVC needs to use dllimport to allow using it directly from a DLL. | ||
39 | * See http://support.microsoft.com/kb/90530 | ||
40 | * Building with MSVC is only when using as DLL. | ||
41 | */ | ||
42 | _declspec(dllimport) unsigned char* ipod_sectorbuf; | ||
43 | #endif | ||
44 | |||
45 | extern int ipod_verbose; | 35 | extern int ipod_verbose; |
46 | 36 | ||
47 | #define FILETYPE_DOT_IPOD 0 | 37 | #define FILETYPE_DOT_IPOD 0 |
diff --git a/rbutil/ipodpatcher/main.c b/rbutil/ipodpatcher/main.c index 2d4ad3a796..12c38de704 100644 --- a/rbutil/ipodpatcher/main.c +++ b/rbutil/ipodpatcher/main.c | |||
@@ -164,7 +164,7 @@ int main(int argc, char* argv[]) | |||
164 | return 1; | 164 | return 1; |
165 | } | 165 | } |
166 | 166 | ||
167 | if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) { | 167 | if (ipod_alloc_buffer(&ipod,BUFFER_SIZE) < 0) { |
168 | fprintf(stderr,"Failed to allocate memory buffer\n"); | 168 | fprintf(stderr,"Failed to allocate memory buffer\n"); |
169 | } | 169 | } |
170 | 170 | ||
diff --git a/rbutil/rbutilqt/base/autodetection.cpp b/rbutil/rbutilqt/base/autodetection.cpp index 0206502202..8fba1d8cea 100644 --- a/rbutil/rbutilqt/base/autodetection.cpp +++ b/rbutil/rbutilqt/base/autodetection.cpp | |||
@@ -137,9 +137,9 @@ bool Autodetection::detect() | |||
137 | int n; | 137 | int n; |
138 | // try ipodpatcher | 138 | // try ipodpatcher |
139 | // initialize sector buffer. Needed. | 139 | // initialize sector buffer. Needed. |
140 | ipod_sectorbuf = NULL; | ||
141 | ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE); | ||
142 | struct ipod_t ipod; | 140 | struct ipod_t ipod; |
141 | ipod.sectorbuf = NULL; | ||
142 | ipod_alloc_buffer(&ipod, BUFFER_SIZE); | ||
143 | n = ipod_scan(&ipod); | 143 | n = ipod_scan(&ipod); |
144 | if(n == 1) { | 144 | if(n == 1) { |
145 | qDebug() << "[Autodetect] Ipod found:" << ipod.modelstr << "at" << ipod.diskname; | 145 | qDebug() << "[Autodetect] Ipod found:" << ipod.modelstr << "at" << ipod.diskname; |
@@ -162,8 +162,8 @@ bool Autodetection::detect() | |||
162 | else { | 162 | else { |
163 | qDebug() << "[Autodetect] ipodpatcher: no Ipod found." << n; | 163 | qDebug() << "[Autodetect] ipodpatcher: no Ipod found." << n; |
164 | } | 164 | } |
165 | free(ipod_sectorbuf); | 165 | free(ipod.sectorbuf); |
166 | ipod_sectorbuf = NULL; | 166 | ipod.sectorbuf = NULL; |
167 | 167 | ||
168 | // try sansapatcher | 168 | // try sansapatcher |
169 | // initialize sector buffer. Needed. | 169 | // initialize sector buffer. Needed. |
diff --git a/rbutil/rbutilqt/base/bootloaderinstallipod.cpp b/rbutil/rbutilqt/base/bootloaderinstallipod.cpp index 249da13735..3d90663392 100644 --- a/rbutil/rbutilqt/base/bootloaderinstallipod.cpp +++ b/rbutil/rbutilqt/base/bootloaderinstallipod.cpp | |||
@@ -28,33 +28,32 @@ BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent) | |||
28 | : BootloaderInstallBase(parent) | 28 | : BootloaderInstallBase(parent) |
29 | { | 29 | { |
30 | (void)parent; | 30 | (void)parent; |
31 | // initialize sector buffer. ipod_sectorbuf is defined in ipodpatcher. | 31 | // initialize sector buffer. The sector buffer is part of the ipod_t |
32 | // The buffer itself is only present once, so make sure to not allocate | 32 | // structure, so a second instance of this class will have its own buffer. |
33 | // it if it was already allocated. The application needs to take care | 33 | ipod_alloc_buffer(&ipod, BUFFER_SIZE); |
34 | // no concurrent (i.e. multiple objects of this class running) requests | ||
35 | // are done. | ||
36 | if(ipod_sectorbuf == NULL) | ||
37 | ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE); | ||
38 | } | 34 | } |
39 | 35 | ||
40 | 36 | ||
41 | BootloaderInstallIpod::~BootloaderInstallIpod() | 37 | BootloaderInstallIpod::~BootloaderInstallIpod() |
42 | { | 38 | { |
43 | if(ipod_sectorbuf) { | 39 | if(ipod.sectorbuf) { |
44 | free(ipod_sectorbuf); | 40 | free(ipod.sectorbuf); |
45 | ipod_sectorbuf = NULL; | 41 | ipod.sectorbuf = NULL; |
46 | } | 42 | } |
47 | } | 43 | } |
48 | 44 | ||
49 | 45 | ||
50 | bool BootloaderInstallIpod::install(void) | 46 | bool BootloaderInstallIpod::install(void) |
51 | { | 47 | { |
52 | if(ipod_sectorbuf == NULL) { | 48 | if(ipod.sectorbuf == NULL) { |
53 | emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); | 49 | emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); |
54 | emit done(true); | 50 | emit done(true); |
55 | return false; | 51 | return false; |
56 | } | 52 | } |
53 | // save buffer pointer before cleaning up ipod_t structure | ||
54 | unsigned char* sb = ipod.sectorbuf; | ||
57 | memset(&ipod, 0, sizeof(struct ipod_t)); | 55 | memset(&ipod, 0, sizeof(struct ipod_t)); |
56 | ipod.sectorbuf = sb; | ||
58 | 57 | ||
59 | if(!ipodInitialize(&ipod)) { | 58 | if(!ipodInitialize(&ipod)) { |
60 | emit done(true); | 59 | emit done(true); |
@@ -139,7 +138,6 @@ void BootloaderInstallIpod::installStage3(bool mounted) | |||
139 | 138 | ||
140 | bool BootloaderInstallIpod::uninstall(void) | 139 | bool BootloaderInstallIpod::uninstall(void) |
141 | { | 140 | { |
142 | struct ipod_t ipod; | ||
143 | emit logItem(tr("Uninstalling bootloader"), LOGINFO); | 141 | emit logItem(tr("Uninstalling bootloader"), LOGINFO); |
144 | QCoreApplication::processEvents(); | 142 | QCoreApplication::processEvents(); |
145 | 143 | ||
@@ -190,7 +188,6 @@ bool BootloaderInstallIpod::uninstall(void) | |||
190 | 188 | ||
191 | BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void) | 189 | BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void) |
192 | { | 190 | { |
193 | struct ipod_t ipod; | ||
194 | BootloaderInstallBase::BootloaderType result = BootloaderRockbox; | 191 | BootloaderInstallBase::BootloaderType result = BootloaderRockbox; |
195 | 192 | ||
196 | if(!ipodInitialize(&ipod)) { | 193 | if(!ipodInitialize(&ipod)) { |