From dbc147eb78a26639dc99ae0ffb40052b579e1194 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Fri, 17 Nov 2017 18:19:06 -0500 Subject: [PATCH] updated to latest libchdr --- deps/chdr/src/chd.c | 64 +++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/deps/chdr/src/chd.c b/deps/chdr/src/chd.c index 1789d3a5..a14b8844 100644 --- a/deps/chdr/src/chd.c +++ b/deps/chdr/src/chd.c @@ -337,7 +337,7 @@ static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 }; /* internal header operations */ static chd_error header_validate(const chd_header *header); -static chd_error header_read(core_file *file, chd_header *header); +static chd_error header_read(chd_file *chd, chd_header *header); /* internal hunk read/write */ @@ -1269,7 +1269,7 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** newchd->file = file; /* now attempt to read the header */ - err = header_read(newchd->file, &newchd->header); + err = header_read(newchd, &newchd->header); if (err != CHDERR_NONE) EARLY_EXIT(err); @@ -1783,13 +1783,37 @@ static chd_error header_validate(const chd_header *header) return CHDERR_NONE; } +/*------------------------------------------------- + header_guess_unitbytes - for older CHD formats, + guess at the bytes/unit based on metadata +-------------------------------------------------*/ + +static UINT32 header_guess_unitbytes(chd_file *chd) +{ + // look for hard disk metadata; if found, then the unit size == sector size + char metadata[512]; + int i0, i1, i2, i3; + if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE && + sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4) + return i3; + + // look for CD-ROM metadata; if found, then the unit size == CD frame size + if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE || + chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE || + chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE || + chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE) + return CD_FRAME_SIZE; + + // otherwise, just map 1:1 with the hunk size + return chd->header.hunkbytes; +} /*------------------------------------------------- header_read - read a CHD header into the internal data structure -------------------------------------------------*/ -static chd_error header_read(core_file *file, chd_header *header) +static chd_error header_read(chd_file *chd, chd_header *header) { UINT8 rawheader[CHD_MAX_HEADER_SIZE]; UINT32 count; @@ -1799,12 +1823,12 @@ static chd_error header_read(core_file *file, chd_header *header) return CHDERR_INVALID_PARAMETER; /* punt if invalid file */ - if (file == NULL) + if (chd->file == NULL) return CHDERR_INVALID_FILE; /* seek and read */ - core_fseek(file, 0, SEEK_SET); - count = core_fread(file, rawheader, sizeof(rawheader)); + core_fseek(chd->file, 0, SEEK_SET); + count = core_fread(chd->file, rawheader, sizeof(rawheader)); if (count != sizeof(rawheader)) return CHDERR_READ_ERROR; @@ -1847,6 +1871,8 @@ static chd_error header_read(core_file *file, chd_header *header) memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES); header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen; header->hunkbytes = seclen * header->obsolete_hunksize; + header->unitbytes = header_guess_unitbytes(chd); + header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes; header->metaoffset = 0; } @@ -1859,6 +1885,8 @@ static chd_error header_read(core_file *file, chd_header *header) memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES); memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES); header->hunkbytes = get_bigendian_uint32(&rawheader[76]); + header->unitbytes = header_guess_unitbytes(chd); + header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes; memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES); memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES); } @@ -1870,6 +1898,8 @@ static chd_error header_read(core_file *file, chd_header *header) header->logicalbytes = get_bigendian_uint64(&rawheader[28]); header->metaoffset = get_bigendian_uint64(&rawheader[36]); header->hunkbytes = get_bigendian_uint32(&rawheader[44]); + header->unitbytes = header_guess_unitbytes(chd); + header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes; memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES); memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES); memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES); @@ -1879,17 +1909,17 @@ static chd_error header_read(core_file *file, chd_header *header) else if (header->version == 5) { /* TODO */ - header->compression[0] = get_bigendian_uint32(&rawheader[16]); - header->compression[1] = get_bigendian_uint32(&rawheader[20]); - header->compression[2] = get_bigendian_uint32(&rawheader[24]); - header->compression[3] = get_bigendian_uint32(&rawheader[28]); - header->logicalbytes = get_bigendian_uint64(&rawheader[32]); - header->mapoffset = get_bigendian_uint64(&rawheader[40]); - header->metaoffset = get_bigendian_uint64(&rawheader[48]); - header->hunkbytes = get_bigendian_uint32(&rawheader[56]); - header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes; - header->unitbytes = get_bigendian_uint32(&rawheader[60]); - header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes; + header->compression[0] = get_bigendian_uint32(&rawheader[16]); + header->compression[1] = get_bigendian_uint32(&rawheader[20]); + header->compression[2] = get_bigendian_uint32(&rawheader[24]); + header->compression[3] = get_bigendian_uint32(&rawheader[28]); + header->logicalbytes = get_bigendian_uint64(&rawheader[32]); + header->mapoffset = get_bigendian_uint64(&rawheader[40]); + header->metaoffset = get_bigendian_uint64(&rawheader[48]); + header->hunkbytes = get_bigendian_uint32(&rawheader[56]); + header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes; + header->unitbytes = get_bigendian_uint32(&rawheader[60]); + header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes; memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES); memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES); memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);