10 void *_openfile(const char *filename
, int flags
)
14 return fopen(filename
, "wb");
16 return fopen(filename
, "rb");
20 u64
_tellfile(void *handle
)
22 s64 cursize
= ftell(handle
);
26 cursize
= ftello(handle
);
30 cursize
&= 0xffffffff;
36 int _seekfile(void *handle
, u64 offset
, int whence
)
38 int seekerr
= fseeko(handle
, offset
, whence
);
40 if (seekerr
== -1) printf("failed to seek\n");
45 int _readfile(void *handle
, void *dst
, int size
)
47 return fread(dst
, 1, size
, handle
);
50 int _writefile(void *handle
, void *src
, int size
)
52 return fwrite(src
, 1, size
, handle
);
55 void _closefile(void *handle
)
61 int detect(struct isoFile
*iso
)
64 struct cdVolDesc
*volDesc
;
66 if (isoReadBlock(iso
, buf
+ iso
->blockofs
, 16) == -1) return -1;
68 volDesc
= (struct cdVolDesc
*)(buf
+ 24);
70 if (strncmp((char*)volDesc
->volID
, "CD001", 5)) return 0;
72 if (volDesc
->rootToc
.tocSize
== 2048)
73 iso
->type
= ISOTYPE_CD
;
75 iso
->type
= ISOTYPE_DVD
;
80 int _isoReadDtable(struct isoFile
*iso
)
85 _seekfile(iso
->handle
, 0, SEEK_END
);
86 iso
->dtablesize
= (_tellfile(iso
->handle
) - 16) / (iso
->blocksize
+ 4);
87 iso
->dtable
= (u32
*)malloc(iso
->dtablesize
* 4);
89 for (i
= 0; i
< iso
->dtablesize
; i
++)
91 _seekfile(iso
->handle
, 16 + (iso
->blocksize
+ 4)*i
, SEEK_SET
);
92 ret
= _readfile(iso
->handle
, &iso
->dtable
[i
], 4);
93 if (ret
< 4) return -1;
99 int isoDetect(struct isoFile
*iso
) // based on florin's CDVDbin detection code :)
104 iso
->type
= ISOTYPE_ILLEGAL
;
106 len
= strlen(iso
->filename
);
108 _seekfile(iso
->handle
, 0, SEEK_SET
);
109 _readfile(iso
->handle
, buf
, 4);
111 if (strncmp(buf
, "BDV2", 4) == 0)
113 iso
->flags
= ISOFLAGS_BLOCKDUMP
;
114 _readfile(iso
->handle
, &iso
->blocksize
, 4);
115 _readfile(iso
->handle
, &iso
->blocks
, 4);
116 _readfile(iso
->handle
, &iso
->blockofs
, 4);
118 return detect(iso
) == 1 ? 0 : -1;
126 iso
->blocksize
= 2048;
129 if (detect(iso
) == 1) return 0;
132 iso
->blocksize
= 2336;
135 if (detect(iso
) == 1) return 0;
138 iso
->blocksize
= 2352;
141 if (detect(iso
) == 1) return 0;
144 iso
->blocksize
= 2448;
147 if (detect(iso
) == 1) return 0;
150 iso
->blocksize
= 2048;
151 iso
->offset
= 150 * 2048;
153 if (detect(iso
) == 1) return 0;
156 iso
->blocksize
= 2352;
157 iso
->offset
= 150 * 2048;
159 if (detect(iso
) == 1) return 0;
162 iso
->blocksize
= 2448;
163 iso
->offset
= 150 * 2048;
165 if (detect(iso
) == 1) return 0;
168 iso
->blocksize
= 2048;
171 if (detect(iso
) == 1) return 0;
174 iso
->blocksize
= 2352;
177 if (detect(iso
) == 1) return 0;
180 iso
->blocksize
= 2448;
183 if (detect(iso
) == 1) return 0;
186 iso
->blocksize
= 2352;
187 iso
->type
= ISOTYPE_AUDIO
;
193 struct isoFile
*isoOpen(const char *filename
)
198 iso
= (struct isoFile
*)malloc(sizeof(struct isoFile
));
199 if (iso
== NULL
) return NULL
;
201 memset(iso
, 0, sizeof(struct isoFile
));
202 strcpy(iso
->filename
, filename
);
204 iso
->handle
= _openfile(iso
->filename
, O_RDONLY
);
205 if (iso
->handle
== NULL
)
207 printf("Error loading %s\n", iso
->filename
);
211 if (isoDetect(iso
) == -1) return NULL
;
213 //printf("detected blocksize = %d\n", iso->blocksize);
215 if (strlen(iso
->filename
) > 3 && strncmp(iso
->filename
+ (strlen(iso
->filename
) - 3), "I00", 3) == 0)
217 _closefile(iso
->handle
);
218 iso
->flags
|= ISOFLAGS_MULTI
;
220 for (i
= 0; i
< 8; i
++)
222 iso
->filename
[strlen(iso
->filename
) - 1] = '0' + i
;
223 iso
->multih
[i
].handle
= _openfile(iso
->filename
, O_RDONLY
);
224 if (iso
->multih
[i
].handle
== NULL
)
228 iso
->multih
[i
].slsn
= iso
->blocks
;
229 _seekfile(iso
->multih
[i
].handle
, 0, SEEK_END
);
230 iso
->blocks
+= (u32
)((_tellfile(iso
->multih
[i
].handle
) - iso
->offset
) /
232 iso
->multih
[i
].elsn
= iso
->blocks
- 1;
243 _seekfile(iso
->handle
, 0, SEEK_END
);
244 iso
->blocks
= (u32
)((_tellfile(iso
->handle
) - iso
->offset
) /
249 //printf("isoOpen: %s ok\n", iso->filename);
250 /*printf("offset = %d\n", iso->offset);
251 printf("blockofs = %d\n", iso->blockofs);
252 printf("blocksize = %d\n", iso->blocksize);
253 printf("blocks = %d\n", iso->blocks);*/
254 //printf("type = %d\n", iso->type);
259 struct isoFile
*isoCreate(const char *filename
, int flags
)
264 iso
= (struct isoFile
*)malloc(sizeof(struct isoFile
));
265 if (iso
== NULL
) return NULL
;
267 memset(iso
, 0, sizeof(struct isoFile
));
268 strcpy(iso
->filename
, filename
);
272 iso
->blocksize
= CD_FRAMESIZE_RAW
;
273 iso
->blocksize
= 2048;
275 if (iso
->flags
& (ISOFLAGS_Z
| ISOFLAGS_Z2
| ISOFLAGS_BZ2
))
277 sprintf(Zfile
, "%s.table", iso
->filename
);
278 iso
->htable
= _openfile(Zfile
, O_WRONLY
);
279 if (iso
->htable
== NULL
)
285 iso
->handle
= _openfile(iso
->filename
, O_WRONLY
| O_CREAT
);
286 if (iso
->handle
== NULL
)
288 printf("Error loading %s\n", iso
->filename
);
291 printf("isoCreate: %s ok\n", iso
->filename
);
292 printf("offset = %d\n", iso
->offset
);
297 int isoSetFormat(struct isoFile
*iso
, int blockofs
, int blocksize
, int blocks
)
299 iso
->blocksize
= blocksize
;
300 iso
->blocks
= blocks
;
301 iso
->blockofs
= blockofs
;
302 printf("blockofs = %d\n", iso
->blockofs
);
303 printf("blocksize = %d\n", iso
->blocksize
);
304 printf("blocks = %d\n", iso
->blocks
);
305 if (iso
->flags
& ISOFLAGS_BLOCKDUMP
)
307 if (_writefile(iso
->handle
, "BDV2", 4) < 4) return -1;
308 if (_writefile(iso
->handle
, &blocksize
, 4) < 4) return -1;
309 if (_writefile(iso
->handle
, &blocks
, 4) < 4) return -1;
310 if (_writefile(iso
->handle
, &blockofs
, 4) < 4) return -1;
316 s32
MSFtoLSN(u8
*Time
)
321 lsn
+= (Time
[1] - 2) * 75;
322 lsn
+= Time
[0] * 75 * 60;
326 void LSNtoMSF(u8
*Time
, s32 lsn
)
331 m
= lsn
/ 4500; // minuten
332 lsn
= lsn
- m
* 4500; // minuten rest
333 s
= lsn
/ 75; // sekunden
334 f
= lsn
- (s
* 75); // sekunden rest
340 int _isoReadBlock(struct isoFile
*iso
, u8
*dst
, int lsn
)
342 u64 ofs
= (u64
)lsn
* iso
->blocksize
+ iso
->offset
;
345 memset(dst
, 0, iso
->blockofs
);
346 _seekfile(iso
->handle
, ofs
, SEEK_SET
);
347 ret
= _readfile(iso
->handle
, dst
, iso
->blocksize
);
348 if (ret
< iso
->blocksize
)
350 printf("read error %d\n", ret
);
357 int _isoReadBlockD(struct isoFile
*iso
, u8
*dst
, u32 lsn
)
362 // printf("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs);
363 memset(dst
, 0, iso
->blockofs
);
364 for (i
= 0; i
< iso
->dtablesize
;i
++)
366 if (iso
->dtable
[i
] != lsn
) continue;
368 _seekfile(iso
->handle
, 16 + i
*(iso
->blocksize
+ 4) + 4, SEEK_SET
);
369 ret
= _readfile(iso
->handle
, dst
, iso
->blocksize
);
370 if (ret
< iso
->blocksize
) return -1;
374 printf("block %d not found in dump\n", lsn
);
379 int _isoReadBlockM(struct isoFile
*iso
, u8
*dst
, u32 lsn
)
385 for (i
= 0; i
< 8; i
++)
387 if (lsn
>= iso
->multih
[i
].slsn
&&
388 lsn
<= iso
->multih
[i
].elsn
)
393 if (i
== 8) return -1;
395 ofs
= (u64
)(lsn
- iso
->multih
[i
].slsn
) * iso
->blocksize
+ iso
->offset
;
396 // printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs);
397 memset(dst
, 0, iso
->blockofs
);
398 _seekfile(iso
->multih
[i
].handle
, ofs
, SEEK_SET
);
399 ret
= _readfile(iso
->multih
[i
].handle
, dst
, iso
->blocksize
);
401 if (ret
< iso
->blocksize
)
403 printf("read error %d\n", ret
);
410 int isoReadBlock(struct isoFile
*iso
, u8
*dst
, u32 lsn
)
414 if (lsn
> iso
->blocks
)
416 printf("isoReadBlock: %d > %d\n", lsn
, iso
->blocks
);
420 if (iso
->flags
& ISOFLAGS_BLOCKDUMP
)
421 ret
= _isoReadBlockD(iso
, dst
, lsn
);
422 else if (iso
->flags
& ISOFLAGS_MULTI
)
423 ret
= _isoReadBlockM(iso
, dst
, lsn
);
425 ret
= _isoReadBlock(iso
, dst
, lsn
);
427 if (ret
== -1) return ret
;
429 if (iso
->type
== ISOTYPE_CD
)
431 LSNtoMSF(dst
+ 12, lsn
);
439 int _isoWriteBlock(struct isoFile
*iso
, u8
*src
, u32 lsn
)
441 u64 ofs
= (u64
)lsn
* iso
->blocksize
+ iso
->offset
;
444 _seekfile(iso
->handle
, ofs
, SEEK_SET
);
445 ret
= _writefile(iso
->handle
, src
, iso
->blocksize
);
446 if (ret
< iso
->blocksize
) return -1;
451 int _isoWriteBlockD(struct isoFile
*iso
, u8
*src
, u32 lsn
)
455 // printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs);
456 ret
= _writefile(iso
->handle
, &lsn
, 4);
457 if (ret
< 4) return -1;
458 ret
= _writefile(iso
->handle
, src
, iso
->blocksize
);
459 // printf("_isoWriteBlock %d\n", ret);
460 if (ret
< iso
->blocksize
) return -1;
465 int isoWriteBlock(struct isoFile
*iso
, u8
*src
, u32 lsn
)
469 if (iso
->flags
& ISOFLAGS_BLOCKDUMP
)
470 ret
= _isoWriteBlockD(iso
, src
, lsn
);
472 ret
= _isoWriteBlock(iso
, src
, lsn
);
474 if (ret
== -1) return ret
;
478 void isoClose(struct isoFile
*iso
)
480 if (iso
->handle
) _closefile(iso
->handle
);
481 if (iso
->htable
) _closefile(iso
->htable
);
482 if (iso
->buffer
) free(iso
->buffer
);
487 void print_ps2image_info(const char *image_name
)
492 iso
= isoOpen(image_name
);
494 printf("\nImage info:\n\n");
496 printf("offset:\t\t %d\n", iso
->offset
);
497 printf("blockofs:\t %d\n", iso
->blockofs
);
498 printf("blocksize:\t %d\n", iso
->blocksize
);
499 printf("blocks:\t\t %d\n", iso
->blocks
);
501 if((iso
->blocksize
*iso
->blocks
) % 0x4000 == 0)
502 printf("image size:\t OK\n");
504 printf("image size:\t NG\n");
507 buffer
= (u8
*)malloc(iso
->blocksize
);
508 isoReadBlock(iso
, buffer
, iso
->blocks
- 8);
510 if(strncmp(buffer
, "LIMG", 4) && be32(buffer
+4) != 1 && be32(buffer
+8) != ((iso
->blocks
) - 8 / 0x800) && be32(buffer
+12) != 0x800)
511 printf("LIMG block:\t NG\n");
513 printf("LIMG block:\t OK\n");
519 void prepare_iso(char image_name
[])
527 u8 header_buffer
[0x10];
528 char limg_header
[4] = "LIMG";
530 memset(buffer
, 0, 0x4000);
532 in
= fopen(image_name
, "r+b");
534 printf("\nPreparing Image:\n\n");
537 fseeko(in
, 0, SEEK_END
);
538 data_size
= ftello(in
);
542 data_append
= 0x4000 - (data_size
% 0x4000);
544 if(data_append
!= 0x4000)
546 fwrite(buffer
, data_append
, 1, in
);
547 data_size
+= data_append
;
548 printf("\timage size:\t FIXED\n");
550 printf("\timage size:\t OK\n");
555 fseeko(in
, data_size
- 0x4000, SEEK_SET
);
556 ret
= fread(header_buffer
, 0x10, 1, in
);
558 if(memcmp(header_buffer
, limg_header
, 4) && be32(header_buffer
+4) != 1 && be32(header_buffer
+8) != (data_size
/0x800) && be32(header_buffer
+12) != 0x800)
560 memcpy(buffer
, limg_header
, 4);
561 wbe32(buffer
+8, data_size
/0x800);
562 wbe32(buffer
+12, 0x800);
565 if(memcmp(header_buffer
, limg_header
, 4))
566 fseeko(in
, 0, SEEK_END
);
568 fseeko(in
, data_size
- 0x4000, SEEK_SET
);
569 fwrite(buffer
, 0x4000, 1, in
);
570 printf("\tLIMG sector:\t ADDED/FIXED\n");
572 printf("\tLIMG sector:\t OK\n");