X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fcdriso.c;h=515370f756d2a0ec88d232fa9e8ea8382709dc1f;hp=21203da8d1ec3ef5ee1ff21c9c27f3b73eb1e439;hb=1edfcc68047e356a9c57c4734cc3bbe084922ce7;hpb=22bbabf6807d704b1a8c9231d55f139e3e00b8dd diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 21203da8..515370f7 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -26,16 +26,21 @@ #include "ppf.h" #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN #include #include #define strcasecmp _stricmp +#define usleep(x) Sleep((x) / 1000) #else #include #include #include #endif +#include #include +#define OFF_T_MSB ((off_t)1 << (sizeof(off_t) * 8 - 1)) + unsigned int cdrIsoMultidiskCount; unsigned int cdrIsoMultidiskSelect; @@ -80,7 +85,7 @@ static unsigned int pregapOffset; static struct { unsigned char buff_raw[16][CD_FRAMESIZE_RAW]; unsigned char buff_compressed[CD_FRAMESIZE_RAW * 16 + 100]; - unsigned int *index_table; + off_t *index_table; unsigned int index_len; unsigned int block_shift; unsigned int current_block; @@ -327,6 +332,14 @@ static int parsetoc(const char *isofile) { return -1; } } + // check if it's really a TOC named as a .cue + fgets(linebuf, sizeof(linebuf), fi); + token = strtok(linebuf, " "); + if (token && strncmp(token, "CD", 2) != 0 && strcmp(token, "CATALOG") != 0) { + fclose(fi); + return -1; + } + fseek(fi, 0, SEEK_SET); } memset(&ti, 0, sizeof(ti)); @@ -543,9 +556,9 @@ static int parsecue(const char *isofile) { pregapOffset = -1; // mark to fill track start_offset } else if (!strcmp(token, "FILE")) { - t = sscanf(linebuf, " FILE \"%256[^\"]\"", tmpb); + t = sscanf(linebuf, " FILE \"%255[^\"]\"", tmpb); if (t != 1) - sscanf(linebuf, " FILE %256s", tmpb); + sscanf(linebuf, " FILE %255s", tmpb); // absolute path? ti[numtracks + 1].handle = fopen(tmpb, "rb"); @@ -776,8 +789,9 @@ static int handlepbp(const char *isofile) { unsigned int dontcare[6]; } index_entry; char psar_sig[11]; - unsigned int t, cd_length, cdimg_base; - unsigned int offsettab[8], psisoimg_offs; + off_t psisoimg_offs, cdimg_base; + unsigned int t, cd_length; + unsigned int offsettab[8]; const char *ext = NULL; int i, ret; @@ -786,6 +800,8 @@ static int handlepbp(const char *isofile) { if (ext == NULL || (strcmp(ext, ".pbp") != 0 && strcmp(ext, ".PBP") != 0)) return -1; + fseeko(cdHandle, 0, SEEK_SET); + numtracks = 0; ret = fread(&pbp_hdr, 1, sizeof(pbp_hdr), cdHandle); @@ -794,7 +810,7 @@ static int handlepbp(const char *isofile) { goto fail_io; } - ret = fseek(cdHandle, pbp_hdr.psar_offs, SEEK_SET); + ret = fseeko(cdHandle, pbp_hdr.psar_offs, SEEK_SET); if (ret != 0) { SysPrintf("failed to seek to %x\n", pbp_hdr.psar_offs); goto fail_io; @@ -805,7 +821,7 @@ static int handlepbp(const char *isofile) { psar_sig[10] = 0; if (strcmp(psar_sig, "PSTITLEIMG") == 0) { // multidisk image? - ret = fseek(cdHandle, pbp_hdr.psar_offs + 0x200, SEEK_SET); + ret = fseeko(cdHandle, pbp_hdr.psar_offs + 0x200, SEEK_SET); if (ret != 0) { SysPrintf("failed to seek to %x\n", pbp_hdr.psar_offs + 0x200); goto fail_io; @@ -831,9 +847,9 @@ static int handlepbp(const char *isofile) { psisoimg_offs += offsettab[cdrIsoMultidiskSelect]; - ret = fseek(cdHandle, psisoimg_offs, SEEK_SET); + ret = fseeko(cdHandle, psisoimg_offs, SEEK_SET); if (ret != 0) { - SysPrintf("failed to seek to %x\n", psisoimg_offs); + SysPrintf("failed to seek to %llx\n", (long long)psisoimg_offs); goto fail_io; } @@ -847,9 +863,9 @@ static int handlepbp(const char *isofile) { } // seek to TOC - ret = fseek(cdHandle, psisoimg_offs + 0x800, SEEK_SET); + ret = fseeko(cdHandle, psisoimg_offs + 0x800, SEEK_SET); if (ret != 0) { - SysPrintf("failed to seek to %x\n", psisoimg_offs + 0x800); + SysPrintf("failed to seek to %llx\n", (long long)psisoimg_offs + 0x800); goto fail_io; } @@ -883,7 +899,7 @@ static int handlepbp(const char *isofile) { sec2msf(t, ti[numtracks].length); // seek to ISO index - ret = fseek(cdHandle, psisoimg_offs + 0x4000, SEEK_SET); + ret = fseeko(cdHandle, psisoimg_offs + 0x4000, SEEK_SET); if (ret != 0) { SysPrintf("failed to seek to ISO index\n"); goto fail_io; @@ -941,6 +957,7 @@ static int handlecbin(const char *isofile) { unsigned char rsv_06[2]; } ciso_hdr; const char *ext = NULL; + unsigned int *index_table = NULL; unsigned int index = 0, plain; int i, ret; @@ -949,6 +966,8 @@ static int handlecbin(const char *isofile) { if (ext == NULL || (strcasecmp(ext + 1, ".cbn") != 0 && strcasecmp(ext, ".cbin") != 0)) return -1; + fseek(cdHandle, 0, SEEK_SET); + ret = fread(&ciso_hdr, 1, sizeof(ciso_hdr), cdHandle); if (ret != sizeof(ciso_hdr)) { SysPrintf("failed to read ciso header\n"); @@ -960,7 +979,7 @@ static int handlecbin(const char *isofile) { return -1; } if (ciso_hdr.header_size != 0 && ciso_hdr.header_size != sizeof(ciso_hdr)) { - ret = fseek(cdHandle, ciso_hdr.header_size, SEEK_SET); + ret = fseeko(cdHandle, ciso_hdr.header_size, SEEK_SET); if (ret != 0) { SysPrintf("failed to seek to %x\n", ciso_hdr.header_size); return -1; @@ -975,30 +994,33 @@ static int handlecbin(const char *isofile) { compr_img->current_block = (unsigned int)-1; compr_img->index_len = ciso_hdr.total_bytes / ciso_hdr.block_size; - compr_img->index_table = malloc((compr_img->index_len + 1) * sizeof(compr_img->index_table[0])); - if (compr_img->index_table == NULL) + index_table = malloc((compr_img->index_len + 1) * sizeof(index_table[0])); + if (index_table == NULL) goto fail_io; - ret = fread(compr_img->index_table, sizeof(compr_img->index_table[0]), compr_img->index_len, cdHandle); + ret = fread(index_table, sizeof(index_table[0]), compr_img->index_len, cdHandle); if (ret != compr_img->index_len) { SysPrintf("failed to read index table\n"); goto fail_index; } + compr_img->index_table = malloc((compr_img->index_len + 1) * sizeof(compr_img->index_table[0])); + if (compr_img->index_table == NULL) + goto fail_index; + for (i = 0; i < compr_img->index_len + 1; i++) { - index = compr_img->index_table[i]; + index = index_table[i]; plain = index & 0x80000000; index &= 0x7fffffff; - compr_img->index_table[i] = (index << ciso_hdr.align) | plain; + compr_img->index_table[i] = (off_t)index << ciso_hdr.align; + if (plain) + compr_img->index_table[i] |= OFF_T_MSB; } - if ((long long)index << ciso_hdr.align >= 0x80000000ll) - SysPrintf("warning: ciso img too large, expect problems\n"); return 0; fail_index: - free(compr_img->index_table); - compr_img->index_table = NULL; + free(index_table); fail_io: if (compr_img != NULL) { free(compr_img); @@ -1101,8 +1123,9 @@ static int uncompress2(void *out, unsigned long *out_size, void *in, unsigned lo static int cdread_compressed(FILE *f, unsigned int base, void *dest, int sector) { unsigned long cdbuffer_size, cdbuffer_size_expect; - unsigned int start_byte, size; + unsigned int size; int is_compressed; + off_t start_byte; int ret, block; if (base) @@ -1121,16 +1144,16 @@ static int cdread_compressed(FILE *f, unsigned int base, void *dest, int sector) return -1; } - start_byte = compr_img->index_table[block] & 0x7fffffff; - if (fseek(cdHandle, start_byte, SEEK_SET) != 0) { - SysPrintf("seek error for block %d at %x: ", - block, start_byte); + start_byte = compr_img->index_table[block] & ~OFF_T_MSB; + if (fseeko(cdHandle, start_byte, SEEK_SET) != 0) { + SysPrintf("seek error for block %d at %llx: ", + block, (long long)start_byte); perror(NULL); return -1; } - is_compressed = !(compr_img->index_table[block] & 0x80000000); - size = (compr_img->index_table[block + 1] & 0x7fffffff) - start_byte; + is_compressed = !(compr_img->index_table[block] & OFF_T_MSB); + size = (compr_img->index_table[block + 1] & ~OFF_T_MSB) - start_byte; if (size > sizeof(compr_img->buff_compressed)) { SysPrintf("block %d is too large: %u\n", block, size); return -1; @@ -1205,6 +1228,8 @@ static void PrintTracks(void) { // file for playback static long CALLBACK ISOopen(void) { boolean isMode1ISO = FALSE; + char alt_bin_filename[MAXPATHLEN]; + const char *bin_filename; if (cdHandle != NULL) { return 0; // it's already open @@ -1212,6 +1237,8 @@ static long CALLBACK ISOopen(void) { cdHandle = fopen(GetIsoFile(), "rb"); if (cdHandle == NULL) { + SysPrintf(_("Could't open '%s' for reading: %s\n"), + GetIsoFile(), strerror(errno)); return -1; } @@ -1227,10 +1254,7 @@ static long CALLBACK ISOopen(void) { CDR_getBuffer = ISOgetBuffer; cdimg_read_func = cdread_normal; - if (parsecue(GetIsoFile()) == 0) { - SysPrintf("[+cue]"); - } - else if (parsetoc(GetIsoFile()) == 0) { + if (parsetoc(GetIsoFile()) == 0) { SysPrintf("[+toc]"); } else if (parseccd(GetIsoFile()) == 0) { @@ -1239,6 +1263,9 @@ static long CALLBACK ISOopen(void) { else if (parsemds(GetIsoFile()) == 0) { SysPrintf("[+mds]"); } + else if (parsecue(GetIsoFile()) == 0) { + SysPrintf("[+cue]"); + } if (handlepbp(GetIsoFile()) == 0) { SysPrintf("[pbp]"); CDR_getBuffer = ISOgetBuffer_compr; @@ -1257,9 +1284,37 @@ static long CALLBACK ISOopen(void) { SysPrintf("[+sbi]"); } + fseeko(cdHandle, 0, SEEK_END); + + // maybe user selected metadata file instead of main .bin .. + bin_filename = GetIsoFile(); + if (ftello(cdHandle) < 2352 * 0x10) { + static const char *exts[] = { ".bin", ".BIN", ".img", ".IMG" }; + FILE *tmpf = NULL; + size_t i; + char *p; + + strncpy(alt_bin_filename, bin_filename, sizeof(alt_bin_filename)); + alt_bin_filename[MAXPATHLEN - 1] = '\0'; + if (strlen(alt_bin_filename) >= 4) { + p = alt_bin_filename + strlen(alt_bin_filename) - 4; + for (i = 0; i < sizeof(exts) / sizeof(exts[0]); i++) { + strcpy(p, exts[i]); + tmpf = fopen(alt_bin_filename, "rb"); + if (tmpf != NULL) + break; + } + } + if (tmpf != NULL) { + bin_filename = alt_bin_filename; + fclose(cdHandle); + cdHandle = tmpf; + fseeko(cdHandle, 0, SEEK_END); + } + } + // guess whether it is mode1/2048 - fseek(cdHandle, 0, SEEK_END); - if (ftell(cdHandle) % 2048 == 0) { + if (ftello(cdHandle) % 2048 == 0) { unsigned int modeTest = 0; fseek(cdHandle, 0, SEEK_SET); fread(&modeTest, 4, 1, cdHandle); @@ -1281,7 +1336,7 @@ static long CALLBACK ISOopen(void) { // make sure we have another handle open for cdda if (numtracks > 1 && ti[1].handle == NULL) { - ti[1].handle = fopen(GetIsoFile(), "rb"); + ti[1].handle = fopen(bin_filename, "rb"); } cdda_cur_sector = 0; cdda_file_offset = 0; @@ -1316,8 +1371,12 @@ static long CALLBACK ISOclose(void) { } } numtracks = 0; + ti[1].type = 0; UnloadSBI(); + memset(cdbuffer, 0, sizeof(cdbuffer)); + CDR_getBuffer = ISOgetBuffer; + return 0; } @@ -1400,6 +1459,7 @@ static void DecodeRawSubData(void) { // uses bcd format static long CALLBACK ISOreadTrack(unsigned char *time) { int sector = MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])); + long ret; if (cdHandle == NULL) { return -1; @@ -1414,7 +1474,9 @@ static long CALLBACK ISOreadTrack(unsigned char *time) { } } - cdimg_read_func(cdHandle, 0, cdbuffer, sector); + ret = cdimg_read_func(cdHandle, 0, cdbuffer, sector); + if (ret < 0) + return -1; if (subHandle != NULL) { fseek(subHandle, sector * SUB_FRAMESIZE, SEEK_SET);