From 334eef4514f07ae4a96f7155ca391f01a74dbf7a Mon Sep 17 00:00:00 2001 From: AKuHAK <621640+AKuHAK@users.noreply.github.com> Date: Sat, 5 Aug 2023 11:48:57 +0300 Subject: [PATCH] Revert "ZSO Cleanup" This reverts commit e9fe9b8ad5cda2aa38367fd672bddfd204189d04. --- modules/iopcore/cdvdman/cdvdman.c | 2 +- modules/isofs/isofs.c | 10 +++++++--- modules/isofs/zso.c | 22 +++++++++++++++------- modules/isofs/zso.h | 3 ++- src/hddsupport.c | 3 +-- src/supportbase.c | 10 +++++++--- src/util.c | 2 +- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/modules/iopcore/cdvdman/cdvdman.c b/modules/iopcore/cdvdman/cdvdman.c index d4cb5a565..6c91baa3c 100644 --- a/modules/iopcore/cdvdman/cdvdman.c +++ b/modules/iopcore/cdvdman/cdvdman.c @@ -245,7 +245,7 @@ static int ProbeZSO(u8 *buffer) probed = 1; if (*(u32 *)buffer == ZSO_MAGIC) { // initialize ZSO - ziso_init((ZISO_header *)buffer); + ziso_init((ZISO_header *)buffer, *(u32 *)(buffer + sizeof(ZISO_header))); // initialize cache initCache(); // redirect sector reader diff --git a/modules/isofs/isofs.c b/modules/isofs/isofs.c index 4aaf11727..df8c2ea73 100644 --- a/modules/isofs/isofs.c +++ b/modules/isofs/isofs.c @@ -507,11 +507,15 @@ static int IsofsLseek(iop_file_t *f, int offset, int where) static int ProbeZISO(int fd) { - ZISO_header header; + struct + { + ZISO_header header; + u32 first_block; + } ziso_data; longLseek(fd, 0); - if (read(fd, &header, sizeof(header)) == sizeof(header) && header.magic == ZSO_MAGIC) { + if (read(fd, &ziso_data, sizeof(ziso_data)) == sizeof(ziso_data) && ziso_data.header.magic == ZSO_MAGIC) { // initialize ZSO - ziso_init(&header); + ziso_init(&ziso_data.header, ziso_data.first_block); // redirect cdEmuRead function cdEmuRead = &cdEmuReadCompressed; return 1; diff --git a/modules/isofs/zso.c b/modules/isofs/zso.c index 54875aca3..556a03893 100644 --- a/modules/isofs/zso.c +++ b/modules/isofs/zso.c @@ -11,20 +11,22 @@ int ziso_idx_start_block = -1; // header data that we need for the reader u32 ziso_align; +u32 ziso_total_block; // block buffers u8 *ziso_tmp_buf = NULL; -void ziso_init(ZISO_header *header) +void ziso_init(ZISO_header *header, u32 first_block) { // read header information ziso_align = header->align; - // invalidate block offset cache ziso_idx_start_block = -1; + // calculate number of blocks without using uncompressed_size (avoid 64bit division) + ziso_total_block = ((((first_block & 0x7FFFFFFF) << ziso_align) - sizeof(ZISO_header)) / 4) - 1; // allocate memory if (ziso_tmp_buf == NULL) { ziso_tmp_buf = ziso_alloc(2048 + sizeof(u32) * ZISO_IDX_MAX_ENTRIES + 64); - if ((u32)ziso_tmp_buf & 63) // align 64 (is 64 needed? is 4 enough?) + if ((u32)ziso_tmp_buf & 63) // align 64 ziso_tmp_buf = (void *)(((u32)ziso_tmp_buf & (~63)) + 64); if (ziso_tmp_buf) { ziso_idx_cache = (u32 *)(ziso_tmp_buf + 2048); @@ -43,13 +45,16 @@ int ziso_read_sector(u8 *addr, u32 lsn, unsigned int count) u32 cur_block = lsn; + if (lsn >= ziso_total_block) { + return 0; // can't seek beyond file + } + // refresh index table if needed - if (ziso_idx_start_block < 0 || lsn < ziso_idx_start_block || (lsn + count) - ziso_idx_start_block >= ZISO_IDX_MAX_ENTRIES - 1) { + if (ziso_idx_start_block < 0 || lsn < ziso_idx_start_block || lsn + count >= ziso_idx_start_block + ZISO_IDX_MAX_ENTRIES - 1) { read_raw_data((u8 *)ziso_idx_cache, ZISO_IDX_MAX_ENTRIES * sizeof(u32), lsn * 4 + sizeof(ZISO_header), 0); ziso_idx_start_block = lsn; } - // calculate total size of compressed data u32 o_start = (ziso_idx_cache[cur_block - ziso_idx_start_block] & 0x7FFFFFFF); u32 o_end = (ziso_idx_cache[cur_block + count - ziso_idx_start_block] & 0x7FFFFFFF); u32 compressed_size = (o_end - o_start) << ziso_align; @@ -70,13 +75,16 @@ int ziso_read_sector(u8 *addr, u32 lsn, unsigned int count) b_size = (b_size & 0x7FFFFFFF); // remove top bit b_size = (b_size - b_offset) << ziso_align; // calculate size of compressed block + // prevent reading more than a sector (eliminates padding if any) + int r = MIN(b_size, 2048); + // check top bit to determine if block is compressed or raw if (topbit == 0) { // block is compressed - memcpy(ziso_tmp_buf, c_buff, b_size); // read compressed block into temp buffer + memcpy(ziso_tmp_buf, c_buff, r); // read compressed block into temp buffer LZ4_decompress_fast((char *)ziso_tmp_buf, (char *)addr, 2048); // decompress block } else { // move block to its correct position in the buffer - memcpy(addr, c_buff, 2048); + memcpy(addr, c_buff, r); } cur_block++; diff --git a/modules/isofs/zso.h b/modules/isofs/zso.h index 3e5072bb1..7e71d2732 100644 --- a/modules/isofs/zso.h +++ b/modules/isofs/zso.h @@ -33,11 +33,12 @@ extern int ziso_idx_start_block; // header data that we need for the reader extern u32 ziso_align; +extern u32 ziso_total_block; // temp block buffer (2048 bytes) extern u8 *ziso_tmp_buf; -void ziso_init(ZISO_header *header); +void ziso_init(ZISO_header *header, u32 first_block); int ziso_read_sector(u8 *buf, u32 sector, unsigned int count); // This must be implemented by isofs/cdvdman/frontend diff --git a/src/hddsupport.c b/src/hddsupport.c index 87fdac497..68219c105 100644 --- a/src/hddsupport.c +++ b/src/hddsupport.c @@ -499,10 +499,9 @@ void hddLaunchGame(int id, config_set_t *configSet) if (*(u32 *)IOBuffer == ZSO_MAGIC) { probed_fd = 0; probed_lba = game->start_sector + OPL_HDD_MODE_PS2LOGO_OFFSET; - ziso_init((ZISO_header *)IOBuffer); + ziso_init((ZISO_header *)IOBuffer, *(u32 *)((u8 *)IOBuffer + sizeof(ZISO_header))); ziso_read_sector(IOBuffer, 16, 1); u32 maxLBA = *(u32 *)(IOBuffer + 80); - u32 ziso_total_block = ((ZISO_header *)IOBuffer)->total_bytes / 2048; if (maxLBA > 0 && maxLBA < ziso_total_block) { // dual layer check settings->common.layer1_start = maxLBA - 16; // adjust second layer start } diff --git a/src/supportbase.c b/src/supportbase.c index b72984835..462607e6a 100644 --- a/src/supportbase.c +++ b/src/supportbase.c @@ -505,11 +505,15 @@ extern u8 IOBuffer[2048]; static int ProbeZISO(int fd) { - ZISO_header header; + struct + { + ZISO_header header; + u32 first_block; + } ziso_data; lseek(fd, 0, SEEK_SET); - if (read(fd, &header, sizeof(header)) == sizeof(header) && header.magic == ZSO_MAGIC) { + if (read(fd, &ziso_data, sizeof(ziso_data)) == sizeof(ziso_data) && ziso_data.header.magic == ZSO_MAGIC) { // initialize ZSO - ziso_init(&header); + ziso_init(&ziso_data.header, ziso_data.first_block); // set ISO file descriptor for ZSO reader probed_fd = fd; probed_lba = 0; diff --git a/src/util.c b/src/util.c index a4dbe4571..676cfbace 100644 --- a/src/util.c +++ b/src/util.c @@ -538,7 +538,7 @@ int CheckPS2Logo(int fd, u32 lba) if (*(u32 *)logo == ZSO_MAGIC) { // initialize ZSO - ziso_init((ZISO_header *)logo); + ziso_init((ZISO_header *)logo, *(u32 *)((u8 *)logo + sizeof(ZISO_header))); probed_fd = fd; probed_lba = lba; // read ZISO data