CD-i: Buffer overflow fix + Initial default NvRAM (#1106)
* CD-i: Fixed buffer overflow Fixed reintroduction of the buffer overflow by commit1addb89ffOriginally was fixed withc0171c9but not yet well understood. * CD-i: Mount root folder NvRAM after core load Instead of starting with an empty NvRAM, "saves/CD-i/CD-i.sav" will be loaded instead. Avoids machine reset by NvRAM change in case a root folder CD image shall be used
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <array>
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -40,7 +41,7 @@ struct subcode
|
||||
uint16_t mode1_crc0;
|
||||
uint16_t mode1_crc1;
|
||||
};
|
||||
static_assert(sizeof(struct subcode) == 24);
|
||||
static_assert(sizeof(struct subcode) == CDI_SUBCHANNEL_LEN);
|
||||
|
||||
struct toc_entry
|
||||
{
|
||||
@@ -51,8 +52,6 @@ struct toc_entry
|
||||
uint8_t f;
|
||||
};
|
||||
|
||||
#define CD_SECTOR_LEN 2352
|
||||
#define CDIC_BUFFER_SIZE (CD_SECTOR_LEN + sizeof(subcode))
|
||||
static std::array<struct toc_entry, 200> toc_buffer;
|
||||
uint32_t toc_entry_count = 0;
|
||||
static enum DiscType disc_type = DT_CDDA;
|
||||
@@ -233,7 +232,7 @@ static int load_cue(const char *filename, toc_t *table)
|
||||
bool modecdi{strstr(lptr, "CDI/2352") != nullptr};
|
||||
bool audio{strstr(lptr, "AUDIO") != nullptr};
|
||||
|
||||
table->tracks[table->last].sector_size = CD_SECTOR_LEN;
|
||||
table->tracks[table->last].sector_size = CDI_SECTOR_LEN;
|
||||
if (!table->last)
|
||||
table->end = 150; // implicit 2 seconds pregap for track 1
|
||||
|
||||
@@ -315,7 +314,7 @@ static int load_cd_image(const char *filename, toc_t *table)
|
||||
// The real source and how this is calculated is yet unknown
|
||||
// We use sector 00:02:16 as reference as it contains the boot block.
|
||||
// If this is a suitable MODE2 header, we assume it is a CD-i disc
|
||||
auto buffer = std::make_unique<uint8_t[]>(CDIC_BUFFER_SIZE);
|
||||
auto buffer = std::make_unique<uint8_t[]>(CDI_CDIC_BUFFER_SIZE);
|
||||
if (buffer)
|
||||
{
|
||||
cdi_read_cd(buffer.get(), 166, 1);
|
||||
@@ -631,7 +630,7 @@ const uint8_t s_sector_scramble[] =
|
||||
|
||||
void descramble_sector(uint8_t *buffer)
|
||||
{
|
||||
for (uint32_t i = 12; i < CD_SECTOR_LEN; i++)
|
||||
for (uint32_t i = 12; i < CDI_SECTOR_LEN; i++)
|
||||
{
|
||||
buffer[i] ^= s_sector_scramble[i - 12];
|
||||
}
|
||||
@@ -790,11 +789,15 @@ void cdi_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
{
|
||||
if (lba < 0 || !toc.last)
|
||||
{
|
||||
memset(buffer, 0, CD_SECTOR_LEN);
|
||||
// Probably TOC area
|
||||
memset(buffer, 0, CDI_SECTOR_LEN);
|
||||
buffer += CDI_SECTOR_LEN;
|
||||
subcode_data(lba, *reinterpret_cast<struct subcode *>(buffer));
|
||||
buffer += sizeof(struct subcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(buffer, 0xAA, CD_SECTOR_LEN);
|
||||
memset(buffer, 0xAA, CDI_SECTOR_LEN);
|
||||
|
||||
for (int i = 0; i < toc.last; i++)
|
||||
{
|
||||
@@ -804,11 +807,11 @@ void cdi_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
{
|
||||
if (toc.tracks[i].offset)
|
||||
{
|
||||
FileSeek(&toc.tracks[0].f, toc.tracks[i].offset + ((lba - toc.tracks[i].start + toc.tracks[i].pregap) * CD_SECTOR_LEN), SEEK_SET);
|
||||
FileSeek(&toc.tracks[0].f, toc.tracks[i].offset + ((lba - toc.tracks[i].start + toc.tracks[i].pregap) * CDI_SECTOR_LEN), SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start + toc.tracks[i].pregap) * CD_SECTOR_LEN, SEEK_SET);
|
||||
FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start + toc.tracks[i].pregap) * CDI_SECTOR_LEN, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,11 +821,11 @@ void cdi_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
{
|
||||
// The "fake" 150 sector pregap moves all the LBAs up by 150, so adjust here to read where the core actually wants data from
|
||||
int read_lba = lba - 150;
|
||||
if (mister_chd_read_sector(toc.chd_f, (read_lba + toc.tracks[i].offset), 0, 0, CD_SECTOR_LEN, buffer, chd_hunkbuf, &chd_hunknum) == CHDERR_NONE)
|
||||
if (mister_chd_read_sector(toc.chd_f, (read_lba + toc.tracks[i].offset), 0, 0, CDI_SECTOR_LEN, buffer, chd_hunkbuf, &chd_hunknum) == CHDERR_NONE)
|
||||
{
|
||||
if (!toc.tracks[i].type) // CHD requires byteswap of audio data
|
||||
{
|
||||
for (int swapidx = 0; swapidx < CD_SECTOR_LEN; swapidx += 2)
|
||||
for (int swapidx = 0; swapidx < CDI_SECTOR_LEN; swapidx += 2)
|
||||
{
|
||||
uint8_t temp = buffer[swapidx];
|
||||
buffer[swapidx] = buffer[swapidx + 1];
|
||||
@@ -838,15 +841,15 @@ void cdi_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
else
|
||||
{
|
||||
if (toc.tracks[i].offset)
|
||||
FileReadAdv(&toc.tracks[0].f, buffer, CD_SECTOR_LEN);
|
||||
FileReadAdv(&toc.tracks[0].f, buffer, CDI_SECTOR_LEN);
|
||||
else
|
||||
FileReadAdv(&toc.tracks[i].f, buffer, CD_SECTOR_LEN);
|
||||
FileReadAdv(&toc.tracks[i].f, buffer, CDI_SECTOR_LEN);
|
||||
}
|
||||
if ((lba + 1) > toc.tracks[i].end)
|
||||
break;
|
||||
|
||||
check_scramble(lba, buffer);
|
||||
buffer += CD_SECTOR_LEN;
|
||||
buffer += CDI_SECTOR_LEN;
|
||||
subcode_data(lba, *reinterpret_cast<struct subcode *>(buffer));
|
||||
buffer += sizeof(struct subcode);
|
||||
cnt--;
|
||||
@@ -857,8 +860,7 @@ void cdi_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
}
|
||||
}
|
||||
|
||||
buffer += CD_SECTOR_LEN;
|
||||
subcode_data(lba, *reinterpret_cast<struct subcode *>(buffer));
|
||||
buffer += CDI_SECTOR_LEN;
|
||||
buffer += sizeof(struct subcode);
|
||||
cnt--;
|
||||
lba++;
|
||||
@@ -875,14 +877,14 @@ static void mount_cd(int size, int index)
|
||||
user_io_bufferinvalidate(0);
|
||||
}
|
||||
|
||||
/// Last used directory for save file management
|
||||
/// Must be static to keep the value between mount calls
|
||||
static char last_dir[1024] = "";
|
||||
|
||||
void cdi_mount_cd(int s_index, const char *filename)
|
||||
{
|
||||
int loaded = 0;
|
||||
|
||||
/// Last used directory for save file management
|
||||
/// Must be static to keep the value between mount calls
|
||||
static char last_dir[1024] = {};
|
||||
|
||||
if (strlen(filename))
|
||||
{
|
||||
if (load_cd_image(filename, &toc) && toc.last)
|
||||
@@ -911,7 +913,7 @@ void cdi_mount_cd(int s_index, const char *filename)
|
||||
|
||||
prepare_toc_buffer(&toc);
|
||||
user_io_set_index(0);
|
||||
mount_cd(toc.end * CD_SECTOR_LEN, s_index);
|
||||
mount_cd(toc.end * CDI_SECTOR_LEN, s_index);
|
||||
loaded = 1;
|
||||
}
|
||||
}
|
||||
@@ -928,3 +930,9 @@ void cdi_mount_cd(int s_index, const char *filename)
|
||||
void cdi_poll()
|
||||
{
|
||||
}
|
||||
|
||||
void cdi_load_root_nvram()
|
||||
{
|
||||
strcpy(last_dir, "games/CD-i");
|
||||
cdi_mount_save(last_dir);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
#ifndef CDI_H
|
||||
#define CDI_H
|
||||
|
||||
#define CDI_SECTOR_LEN 2352
|
||||
#define CDI_SUBCHANNEL_LEN 24
|
||||
#define CDI_CDIC_BUFFER_SIZE (CDI_SECTOR_LEN + CDI_SUBCHANNEL_LEN)
|
||||
|
||||
void cdi_mount_cd(int s_index, const char *filename);
|
||||
void cdi_fill_blanksave(uint8_t *buffer, uint32_t lba, int cnt);
|
||||
void cdi_read_cd(uint8_t *buffer, int lba, int cnt);
|
||||
int cdi_chd_hunksize();
|
||||
const char* cdi_get_game_id();
|
||||
void cdi_poll();
|
||||
void cdi_load_root_nvram();
|
||||
|
||||
#endif
|
||||
|
||||
11
user_io.cpp
11
user_io.cpp
@@ -1552,6 +1552,7 @@ void user_io_init(const char *path, const char *xml)
|
||||
const char *home = HomeDir();
|
||||
|
||||
if (is_uneon()) x86_ide_set();
|
||||
if (is_cdi()) cdi_load_root_nvram();
|
||||
|
||||
if (!strlen(path) || !user_io_file_tx(path, 0, 0, 0, 1))
|
||||
{
|
||||
@@ -3107,7 +3108,7 @@ void user_io_poll()
|
||||
int disk = -1;
|
||||
int ack = 0;
|
||||
int op = 0;
|
||||
static uint8_t buffer[16][16384];
|
||||
static uint8_t buffer[16][UIO_BUFFER_SIZE];
|
||||
uint64_t lba = 0;
|
||||
uint32_t blksz, blks, sz;
|
||||
|
||||
@@ -3130,7 +3131,7 @@ void user_io_poll()
|
||||
if (disk == 1 && is_psx())
|
||||
blksz = 2352;
|
||||
else if (disk == 0 && is_cdi())
|
||||
blksz = (2352 + 24);
|
||||
blksz = CDI_CDIC_BUFFER_SIZE;
|
||||
else
|
||||
blksz = 128 << ((c >> 6) & 7);
|
||||
|
||||
@@ -3265,11 +3266,11 @@ void user_io_poll()
|
||||
unsigned int psx_blksz = psx_chd_hunksize();
|
||||
if (psx_blksz && psx_blksz <= sizeof(buffer[0])) buf_n = psx_blksz / blksz;
|
||||
}
|
||||
else if (is_cdi() && blksz == (2352 + 24))
|
||||
else if (is_cdi() && blksz == CDI_CDIC_BUFFER_SIZE)
|
||||
{
|
||||
//returns 0 if the mounted disk is not a chd, otherwise returns the chd hunksize in bytes
|
||||
unsigned int psx_blksz = cdi_chd_hunksize();
|
||||
if (psx_blksz && psx_blksz <= sizeof(buffer[0])) buf_n = psx_blksz / blksz;
|
||||
unsigned int cdi_blksz = cdi_chd_hunksize();
|
||||
if (cdi_blksz && cdi_blksz <= sizeof(buffer[0])) buf_n = cdi_blksz / blksz;
|
||||
}
|
||||
//printf("SD RD (%llu,%d) on %d, WIDE=%d\n", lba, blksz, disk, fio_size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user