audit_record *media_auditor::audit_one_disk(const rom_entry *rom) { // allocate and append a new record audit_record &record = m_record_list.append(*global_alloc(audit_record(*rom, audit_record::MEDIA_DISK))); // open the disk emu_file *source_file; chd_file *source; chd_error err = open_disk_image(m_enumerator.options(), &m_enumerator.driver(), rom, &source_file, &source, NULL); // if we succeeded, get the hashes if (err == CHDERR_NONE) { static const UINT8 nullhash[20] = { 0 }; chd_header header = *chd_get_header(source); hash_collection hashes; // if there's an MD5 or SHA1 hash, add them to the output hash if (memcmp(nullhash, header.md5, sizeof(header.md5)) != 0) hashes.add_from_buffer(hash_collection::HASH_MD5, header.md5, sizeof(header.md5)); if (memcmp(nullhash, header.sha1, sizeof(header.sha1)) != 0) hashes.add_from_buffer(hash_collection::HASH_SHA1, header.sha1, sizeof(header.sha1)); // update the actual values record.set_actual(hashes); // close the file and release the source chd_close(source); global_free(source_file); } // compute the final status compute_status(record, rom, err == CHDERR_NONE); return &record; }
struct hard_disk_file *hard_disk_open(struct chd_file *chd) { int cylinders, heads, sectors, sectorbytes; struct hard_disk_file *file; char metadata[256]; UINT32 metatag; UINT32 count; /* punt if no CHD */ if (!chd) return NULL; /* read the hard disk metadata */ metatag = HARD_DISK_STANDARD_METADATA; count = chd_get_metadata(chd, &metatag, 0, metadata, sizeof(metadata)); if (count == 0) return NULL; /* parse the metadata */ if (sscanf(metadata, HARD_DISK_METADATA_FORMAT, &cylinders, &heads, §ors, §orbytes) != 4) return NULL; /* allocate memory for the hard disk file */ file = malloc(sizeof(struct hard_disk_file)); if (!file) return NULL; /* fill in the data */ file->chd = chd; file->info.cylinders = cylinders; file->info.heads = heads; file->info.sectors = sectors; file->info.sectorbytes = sectorbytes; file->hunksectors = chd_get_header(chd)->hunkbytes / file->info.sectorbytes; file->cachehunk = -1; /* allocate a cache */ file->cache = malloc(chd_get_header(chd)->hunkbytes); if (!file->cache) { free(file); return NULL; } return file; }
hard_disk_file *hard_disk_open(chd_file *chd) { int cylinders, heads, sectors, sectorbytes; hard_disk_file *file; char metadata[256]; chd_error err; /* punt if no CHD */ if (chd == NULL) return NULL; /* read the hard disk metadata */ err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) return NULL; /* parse the metadata */ if (sscanf(metadata, HARD_DISK_METADATA_FORMAT, &cylinders, &heads, §ors, §orbytes) != 4) return NULL; /* allocate memory for the hard disk file */ file = (hard_disk_file *)malloc(sizeof(hard_disk_file)); if (file == NULL) return NULL; /* fill in the data */ file->chd = chd; file->info.cylinders = cylinders; file->info.heads = heads; file->info.sectors = sectors; file->info.sectorbytes = sectorbytes; file->hunksectors = chd_get_header(chd)->hunkbytes / file->info.sectorbytes; file->cachehunk = -1; /* allocate a cache */ file->cache = (UINT8 *)malloc(chd_get_header(chd)->hunkbytes); if (file->cache == NULL) { free(file); return NULL; } return file; }
static void *open_chd(const char *filename, movie_info *info) { int fps, fpsfrac, width, height, interlaced, channels, rate; char metadata[256]; chd_error chderr; chd_file *chd; /* open the file */ chderr = chd_open(filename, CHD_OPEN_READ, NULL, &chd); if (chderr != CHDERR_NONE) { fprintf(stderr, "Error opening CHD file: %s\n", chd_error_string(chderr)); return NULL; } /* get the metadata */ chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (chderr != CHDERR_NONE) { fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr)); chd_close(chd); return NULL; } /* extract the info */ if (sscanf(metadata, AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7) { fprintf(stderr, "Improperly formatted metadata\n"); chd_close(chd); return NULL; } /* extract movie info */ info->framerate = (fps * 1000000 + fpsfrac) / 1000000.0; info->numframes = chd_get_header(chd)->totalhunks; info->width = width; info->height = height; info->samplerate = rate; info->channels = channels; /* convert to an interlaced frame */ chdinterlaced = interlaced; if (interlaced) { info->framerate /= 2; info->numframes = (info->numframes + 1) / 2; info->height *= 2; } return chd; }
cdrom_file *cdrom_open(chd_file *chd) { const chd_header *header = chd_get_header(chd); int i; cdrom_file *file; UINT32 physofs, chdofs; chd_error err; /* punt if no CHD */ if (!chd) return NULL; /* validate the CHD information */ if (header->hunkbytes % CD_FRAME_SIZE != 0) return NULL; /* allocate memory for the CD-ROM file */ file = (cdrom_file *)malloc(sizeof(cdrom_file)); if (file == NULL) return NULL; /* fill in the data */ file->chd = chd; file->hunksectors = header->hunkbytes / CD_FRAME_SIZE; file->cachehunk = -1; /* read the CD-ROM metadata */ err = cdrom_parse_metadata(chd, &file->cdtoc); if (err != CHDERR_NONE) { free(file); return NULL; } LOG(("CD has %d tracks\n", file->cdtoc.numtrks)); /* calculate the starting frame for each track, keeping in mind that CHDMAN pads tracks out with extra frames to fit hunk size boundries */ physofs = chdofs = 0; for (i = 0; i < file->cdtoc.numtrks; i++) { file->cdtoc.tracks[i].physframeofs = physofs; file->cdtoc.tracks[i].chdframeofs = chdofs; physofs += file->cdtoc.tracks[i].frames; chdofs += file->cdtoc.tracks[i].frames; chdofs += file->cdtoc.tracks[i].extraframes; LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1, file->cdtoc.tracks[i].trktype, file->cdtoc.tracks[i].subtype, file->cdtoc.tracks[i].datasize, file->cdtoc.tracks[i].subsize, file->cdtoc.tracks[i].frames, file->cdtoc.tracks[i].extraframes, file->cdtoc.tracks[i].physframeofs, file->cdtoc.tracks[i].chdframeofs)); } /* fill out dummy entries for the last track to help our search */ file->cdtoc.tracks[i].physframeofs = physofs; file->cdtoc.tracks[i].chdframeofs = chdofs; /* allocate a cache */ file->cache = (UINT8 *)malloc(chd_get_header(chd)->hunkbytes); if (file->cache == NULL) { free(file); return NULL; } return file; }
bool CHDDisc::TryOpen(wchar* file) { chd_error err=chd_open(file,CHD_OPEN_READ,0,&chd); if (err!=CHDERR_NONE) return false; const chd_header* head = chd_get_header(chd); hunkbytes = head->hunkbytes; hunk_mem = new u8[hunkbytes]; old_hunk=0xFFFFFFF; sph = hunkbytes/(2352+96); if (hunkbytes%(2352+96)!=0) return false; u32 tag; u8 flags; char temp[512]; u32 temp_len; u32 total_frames=150; u32 total_secs=0; u32 total_hunks=0; for(;;) { err=chd_get_metadata(chd,CDROM_TRACK_METADATA2_TAG,tracks.size(),temp,sizeof(temp),&temp_len,&tag,&flags); if (err!=CHDERR_NONE) break; //"TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d" char type[64],subtype[32],pgtype[32],pgsub[32]; int tkid,frames,pregap,postgap; sscanf(temp,CDROM_TRACK_METADATA2_FORMAT,&tkid,type,subtype,&frames,&pregap,pgtype,pgsub,&postgap); if (tkid!=(tracks.size()+1) || (strcmp(type,"MODE1_RAW")!=0 && strcmp(type,"AUDIO")!=0) || strcmp(subtype,"NONE")!=0 || pregap!=0 || postgap!=0) return false; printf("%s\n",temp); Track t; t.StartFAD=total_frames; total_frames+=frames; t.EndFAD=total_frames-1; t.ADDR=0; t.CTRL=strcmp(type,"AUDIO")==0?0:4; t.file = new CHDTrack(this,t.StartFAD,total_hunks); total_hunks+=frames/sph; if (frames%sph) total_hunks++; tracks.push_back(t); } if (total_frames!=549300 || tracks.size()<3) return false; FillGDSession(); return true; }
static void audit_one_disk(core_options *options, const rom_entry *rom, const game_driver *gamedrv, UINT32 validation, audit_record *record) { mame_file *source_file; chd_file *source; chd_error err; /* fill in the record basics */ record->type = AUDIT_FILE_DISK; record->name = ROM_GETNAME(rom); record->exphash = ROM_GETHASHDATA(rom); /* open the disk */ err = open_disk_image_options(options, gamedrv, rom, &source_file, &source); /* if we failed, report the error */ if (err != CHDERR_NONE) { /* out of memory */ if (err == CHDERR_OUT_OF_MEMORY) set_status(record, AUDIT_STATUS_ERROR, SUBSTATUS_ERROR); /* not found but it's not good anyway */ else if (hash_data_has_info(record->exphash, HASH_INFO_NO_DUMP)) set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND_NODUMP); /* not found but optional */ else if (DISK_ISOPTIONAL(rom)) set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND_OPTIONAL); /* not found at all */ else set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND); } /* if we succeeded, validate it */ else { static const UINT8 nullhash[HASH_BUF_SIZE] = { 0 }; chd_header header = *chd_get_header(source); /* if there's an MD5 or SHA1 hash, add them to the output hash */ if (memcmp(nullhash, header.md5, sizeof(header.md5)) != 0) hash_data_insert_binary_checksum(record->hash, HASH_MD5, header.md5); if (memcmp(nullhash, header.sha1, sizeof(header.sha1)) != 0) hash_data_insert_binary_checksum(record->hash, HASH_SHA1, header.sha1); /* found but needs a dump */ if (hash_data_has_info(record->exphash, HASH_INFO_NO_DUMP)) set_status(record, AUDIT_STATUS_GOOD, SUBSTATUS_FOUND_NODUMP); /* incorrect hash */ else if (!hash_data_is_equal(record->exphash, record->hash, 0)) set_status(record, AUDIT_STATUS_FOUND_INVALID, SUBSTATUS_FOUND_BAD_CHECKSUM); /* correct hash but needs a redump */ else if (hash_data_has_info(record->exphash, HASH_INFO_BAD_DUMP)) set_status(record, AUDIT_STATUS_GOOD, SUBSTATUS_GOOD_NEEDS_REDUMP); /* just plain good */ else set_status(record, AUDIT_STATUS_GOOD, SUBSTATUS_GOOD); chd_close(source); mame_fclose(source_file); } }
static int process_disk_entries(struct rom_load_data *romdata, const struct RomModule *romp) { /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { struct chd_file *source, *diff = NULL; struct chd_header header; char filename[1024], *c; char acthash[HASH_BUF_SIZE]; int err; /* make the filename of the source */ strcpy(filename, ROM_GETNAME(romp)); c = strrchr(filename, '.'); if (c) strcpy(c, ".chd"); else strcat(filename, ".chd"); /* first open the source drive */ debugload("Opening disk image: %s\n", filename); source = chd_open(filename, 0, NULL); if (!source) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NOT FOUND\n", filename); romdata->errors++; romp++; continue; } /* get the header and extract the MD5/SHA1 */ header = *chd_get_header(source); hash_data_clear(acthash); hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5); hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1); /* verify the MD5 */ if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s WRONG CHECKSUMS:\n", filename); dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash); romdata->warnings++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* make the filename of the diff */ strcpy(filename, ROM_GETNAME(romp)); c = strrchr(filename, '.'); if (c) strcpy(c, ".dif"); else strcat(filename, ".dif"); /* try to open the diff */ debugload("Opening differencing image: %s\n", filename); diff = chd_open(filename, 1, source); if (!diff) { /* didn't work; try creating it instead */ debugload("Creating differencing image: %s\n", filename); err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source); if (err != CHDERR_NONE) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T CREATE DIFF FILE\n", filename); romdata->errors++; romp++; continue; } /* open the newly-created diff file */ debugload("Opening differencing image: %s\n", filename); diff = chd_open(filename, 1, source); if (!diff) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T OPEN DIFF FILE\n", filename); romdata->errors++; romp++; continue; } } } /* we're okay, set the handle */ debugload("Assigning to handle %d\n", DISK_GETINDEX(romp)); disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff; romp++; } } return 1; }
/* Fills in an audit record for each rom in the romset. Sets 'audit' to point to the list of audit records. Returns total number of roms in the romset (same as number of audit records), 0 if romset missing. */ int audit_roms (int game, audit_record **audit) { const rom_entry *region, *rom, *chunk; const char *name; const game_driver *gamedrv; const game_driver *clone_of; int count = 0; audit_record *aud; int err; if (!audit_records) { audit_records = (audit_record *)malloc (AUD_MAX_ROMS * sizeof (audit_record)); // Make sure the memory is cleared - it's needed by the hashing // engine memset(audit_records, 0, AUD_MAX_ROMS * sizeof(audit_record)); } if (audit_records) *audit = aud = audit_records; else return 0; gamedrv = drivers[game]; clone_of = driver_get_clone(gamedrv); if (!gamedrv->rom) return -1; /* check for existence of romset */ if (!mame_faccess (gamedrv->name, FILETYPE_ROM)) { /* if the game is a clone, check for parent */ if (clone_of == NULL || (clone_of->flags & NOT_A_DRIVER) || !mame_faccess(clone_of->name,FILETYPE_ROM)) return 0; } for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { if (ROMREGION_ISROMDATA(region)) { const game_driver *drv; name = ROM_GETNAME(rom); strcpy (aud->rom, name); aud->explength = 0; aud->length = 0; aud->exphash = ROM_GETHASHDATA(rom); /* Copy into the variable we pass to the functions to support load-by-checksum */ hash_data_copy(aud->hash, aud->exphash); count++; /* obtain hash checksums and length of ROM file */ drv = gamedrv; do { err = mame_fchecksum(drv->name, name, &aud->length, aud->hash); drv = driver_get_clone(drv); } while (err && drv); /* spin through ROM_CONTINUEs, totaling length */ for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) aud->explength += ROM_GETLENGTH(chunk); if (err) { if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { /* not found but it's not good anyway */ aud->status = AUD_NOT_AVAILABLE; } else if (ROM_ISOPTIONAL(rom)) { /* optional ROM not found */ aud->status = AUD_OPTIONAL_ROM_NOT_FOUND; } else { /* not found */ aud->status = AUD_ROM_NOT_FOUND; drv = clone_of; /* If missing ROM is also present in a parent set, indicate that */ while (drv) { if (audit_is_rom_used (drv, aud->exphash)) { if (drv->flags & NOT_A_DRIVER) { aud->status = AUD_ROM_NOT_FOUND_BIOS; break; } else aud->status = AUD_ROM_NOT_FOUND_PARENT; } // Walk up the inheritance list. If this ROM is a clone of a set which // contains a BIOS that is missing, we can correctly mark it as // such. drv = driver_get_clone(drv); } } } /* all cases below assume the ROM was at least found */ else if (aud->explength != aud->length) aud->status = AUD_LENGTH_MISMATCH; else if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) aud->status = AUD_ROM_NEED_DUMP; /* new case - found but not known to be dumped */ else if (!hash_data_is_equal(aud->exphash, aud->hash, 0)) { /* non-matching hash */ aud->status = AUD_BAD_CHECKSUM; } else { /* matching hash */ if (hash_data_has_info(aud->exphash, HASH_INFO_BAD_DUMP)) aud->status = AUD_ROM_NEED_REDUMP; else aud->status = AUD_ROM_GOOD; } aud++; } else if (ROMREGION_ISDISKDATA(region)) { const UINT8 nullhash[HASH_BUF_SIZE] = { 0 }; void *source; chd_header header; name = ROM_GETNAME(rom); strcpy (aud->rom, name); aud->explength = 0; aud->length = 0; aud->exphash = ROM_GETHASHDATA(rom); hash_data_clear(aud->hash); count++; chd_gamedrv = gamedrv; chd_set_interface(&audit_chd_interface); source = chd_open( name, 0, NULL ); if( source == NULL ) { err = chd_get_last_error(); if( err == CHDERR_OUT_OF_MEMORY ) { aud->status = AUD_MEM_ERROR; } else if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { /* not found but it's not good anyway */ aud->status = AUD_DISK_NOT_AVAILABLE; } else { /* not found */ aud->status = AUD_DISK_NOT_FOUND; } } else { header = *chd_get_header(source); if (memcmp(nullhash, header.md5, sizeof(header.md5))) hash_data_insert_binary_checksum(aud->hash, HASH_MD5, header.md5); if (memcmp(nullhash, header.sha1, sizeof(header.sha1))) hash_data_insert_binary_checksum(aud->hash, HASH_SHA1, header.sha1); if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { aud->status = AUD_DISK_NEED_DUMP; } else if (!hash_data_is_equal(aud->exphash, aud->hash, 0)) { aud->status = AUD_DISK_BAD_MD5; } else { aud->status = AUD_DISK_GOOD; } chd_close( source ); } aud++; } } #ifdef MESS if (!count) return -1; else #endif return count; }
static void process_disk_entries(rom_load_data *romdata, const rom_entry *romp) { /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { chd_file *source, *diff = NULL; chd_header header; char filename[1024]; char acthash[HASH_BUF_SIZE]; chd_error err; /* make the filename of the source */ sprintf(filename, "%s.chd", ROM_GETNAME(romp)); /* first open the source drive */ debugload("Opening disk image: %s\n", filename); err = open_disk_image(Machine->gamedrv, romp, &source); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s NOT FOUND\n", filename); /* if this is NO_DUMP, keep going, though the system may not be able to handle it */ if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_NO_DUMP)) romdata->warnings++; else romdata->errors++; romp++; continue; } /* get the header and extract the MD5/SHA1 */ header = *chd_get_header(source); hash_data_clear(acthash); hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5); hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1); /* verify the MD5 */ if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s WRONG CHECKSUMS:\n", filename); dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash); romdata->warnings++; } else if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_BAD_DUMP)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s CHD NEEDS REDUMP\n", filename); romdata->warnings++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* make the filename of the diff */ sprintf(filename, "%s.dif", ROM_GETNAME(romp)); /* try to open the diff */ debugload("Opening differencing image: %s\n", filename); err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff); if (err != CHDERR_NONE) { /* didn't work; try creating it instead */ debugload("Creating differencing image: %s\n", filename); err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T CREATE DIFF FILE\n", filename); romdata->errors++; romp++; continue; } /* open the newly-created diff file */ debugload("Opening differencing image: %s\n", filename); err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T OPEN DIFF FILE\n", filename); romdata->errors++; romp++; continue; } } } /* we're okay, set the handle */ debugload("Assigning to handle %d\n", DISK_GETINDEX(romp)); disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff; romp++; } } }
static void identify_file(core_options *options, const char *name, romident_status *status) { file_error filerr; osd_file *file; UINT64 length; if (core_filename_ends_with(name, ".chd")) { chd_file *chd; chd_error err; astring basename; int found = 0; core_filename_extract_base(&basename, name, FALSE); mame_printf_info("%-20s", basename.cstr()); status->total++; err = chd_open(name, CHD_OPEN_READ, NULL, &chd); if (err != CHDERR_NONE) { mame_printf_info("NOT A CHD\n"); status->nonroms++; } else { chd_header header; header = *chd_get_header(chd); if (header.flags & CHDFLAGS_IS_WRITEABLE) { mame_printf_info("is a writable CHD\n"); } else { static const UINT8 nullhash[HASH_BUF_SIZE] = { 0 }; char hash[HASH_BUF_SIZE]; /* actual hash information */ hash_data_clear(hash); /* if there's an MD5 or SHA1 hash, add them to the output hash */ if (memcmp(nullhash, header.md5, sizeof(header.md5)) != 0) hash_data_insert_binary_checksum(hash, HASH_MD5, header.md5); if (memcmp(nullhash, header.sha1, sizeof(header.sha1)) != 0) hash_data_insert_binary_checksum(hash, HASH_SHA1, header.sha1); length = header.logicalbytes; match_roms(options, hash, length, &found); if (found == 0) { mame_printf_info("NO MATCH\n"); } /* if we did find it, count it as a match */ else status->matches++; } chd_close(chd); } } else { /* open for read and process if it opens and has a valid length */ filerr = osd_open(name, OPEN_FLAG_READ, &file, &length); if (filerr == FILERR_NONE && length > 0 && (UINT32)length == length) { UINT8 *data = global_alloc_array(UINT8, length); if (data != NULL) { UINT32 bytes; /* read file data into RAM and identify it */ filerr = osd_read(file, data, 0, length, &bytes); if (filerr == FILERR_NONE) identify_data(options, name, data, bytes, status); global_free(data); } osd_close(file); } } }