static void process_disk_entries(rom_load_data *romdata, const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag) { /* loop until we hit the end of this region */ for ( ; !ROMENTRY_ISREGIONEND(romp); romp++) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { open_chd *chd = global_alloc(open_chd(regiontag)); hash_collection hashes(ROM_GETHASHDATA(romp)); chd_error err; /* make the filename of the source */ astring filename(ROM_GETNAME(romp), ".chd"); /* first open the source drive */ LOG(("Opening disk image: %s\n", filename.cstr())); err = chd_error(open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, chd->orig_chd(), locationtag)); if (err != CHDERR_NONE) { if (err == CHDERR_FILE_NOT_FOUND) romdata->errorstring.catprintf("%s NOT FOUND\n", filename.cstr()); else romdata->errorstring.catprintf("%s CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err)); /* if this is NO_DUMP, keep going, though the system may not be able to handle it */ if (hashes.flag(hash_collection::FLAG_NO_DUMP)) romdata->knownbad++; else if (DISK_ISOPTIONAL(romp)) romdata->warnings++; else romdata->errors++; global_free(chd); continue; } /* get the header and extract the SHA1 */ hash_collection acthashes; acthashes.add_sha1(chd->orig_chd().sha1()); /* verify the hash */ if (hashes != acthashes) { romdata->errorstring.catprintf("%s WRONG CHECKSUMS:\n", filename.cstr()); dump_wrong_and_correct_checksums(romdata, hashes, acthashes); romdata->warnings++; } else if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) { romdata->errorstring.catprintf("%s CHD NEEDS REDUMP\n", filename.cstr()); romdata->knownbad++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* try to open or create the diff */ err = open_disk_diff(romdata->machine().options(), romp, chd->orig_chd(), chd->diff_chd()); if (err != CHDERR_NONE) { romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err)); romdata->errors++; global_free(chd); continue; } } /* we're okay, add to the list of disks */ LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp))); romdata->machine().romload_data->chd_list.append(*chd); } } }
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 void print_game_rom(FILE *out, const game_driver *game, const machine_config *config) { const game_driver *clone_of = driver_get_clone(game); int rom_type; machine_config *pconfig = (clone_of != NULL) ? machine_config_alloc(clone_of->machine_config) : NULL; /* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */ for (rom_type = 0; rom_type < 3; rom_type++) { const rom_source *source; const rom_entry *region; /* iterate over ROM sources: first the game, then any devices */ for (source = rom_first_source(game, config); source != NULL; source = rom_next_source(game, config, source)) for (region = rom_first_region(game, source); region != NULL; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); const rom_entry *rom; /* disk regions only work for disks */ if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; /* iterate through ROM entries */ for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { int is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const rom_entry *parent_rom = NULL; char bios_name[100]; /* BIOS ROMs only apply to bioses */ if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0)) continue; /* if we have a valid ROM and we are a clone, see if we can find the parent ROM */ if (!ROM_NOGOODDUMP(rom) && clone_of != NULL) { const rom_source *psource; const rom_entry *pregion, *prom; /* scan the clone_of ROM for a matching ROM entry */ for (psource = rom_first_source(clone_of, pconfig); psource != NULL; psource = rom_next_source(clone_of, pconfig, psource)) for (pregion = rom_first_region(clone_of, psource); pregion != NULL; pregion = rom_next_region(pregion)) for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0)) { parent_rom = prom; break; } } /* scan for a BIOS name */ bios_name[0] = 0; if (!is_disk && is_bios) { const rom_entry *brom; /* scan backwards through the ROM entries */ for (brom = rom - 1; brom != game->rom; brom--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); break; } } /* opening tag */ if (!is_disk) fprintf(out, "\t\t<rom"); else fprintf(out, "\t\t<disk"); /* add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) fprintf(out, " name=\"%s\"", xml_normalize_string(name)); if (parent_rom != NULL) fprintf(out, " merge=\"%s\"", xml_normalize_string(ROM_GETNAME(parent_rom))); if (bios_name[0] != 0) fprintf(out, " bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) fprintf(out, " size=\"%d\"", rom_file_size(rom)); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { char checksum[HASH_BUF_SIZE]; int hashtype; /* iterate over hash function types and print out their values */ for (hashtype = 0; hashtype < HASH_NUM_FUNCTIONS; hashtype++) if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), 1 << hashtype, checksum)) fprintf(out, " %s=\"%s\"", hash_function_name(1 << hashtype), checksum); } /* append a region name */ fprintf(out, " region=\"%s\"", ROMREGION_GETTAG(region)); /* add nodump/baddump flags */ if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) fprintf(out, " status=\"nodump\""); if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP)) fprintf(out, " status=\"baddump\""); /* for non-disk entries, print offset */ if (!is_disk) fprintf(out, " offset=\"%x\"", offset); /* for disk entries, add the disk index */ else fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); /* add optional flag */ if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom))) fprintf(out, " optional=\"yes\""); fprintf(out, "/>\n"); } } } if (pconfig != NULL) machine_config_free(pconfig); }
void info_xml_creator::output_rom() { // iterate over 3 different ROM "types": BIOS, ROMs, DISKs for (int rom_type = 0; rom_type < 3; rom_type++) { // iterate over ROM sources: first the game, then any devices for (const rom_source *source = rom_first_source(m_drivlist.config()); source != NULL; source = rom_next_source(*source)) for (const rom_entry *region = rom_first_region(*source); region != NULL; region = rom_next_region(region)) { bool is_disk = ROMREGION_ISDISKDATA(region); // disk regions only work for disks if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; // iterate through ROM entries for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { bool is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const char *merge_name = NULL; char bios_name[100]; // BIOS ROMs only apply to bioses if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0)) continue; // if we have a valid ROM and we are a clone, see if we can find the parent ROM hash_collection hashes(ROM_GETHASHDATA(rom)); if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) merge_name = get_merge_name(hashes); // scan for a BIOS name bios_name[0] = 0; if (!is_disk && is_bios) { // scan backwards through the ROM entries for (const rom_entry *brom = rom - 1; brom != m_drivlist.driver().rom; brom--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); break; } } // opening tag if (!is_disk) fprintf(m_output, "\t\t<rom"); else fprintf(m_output, "\t\t<disk"); // add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) fprintf(m_output, " name=\"%s\"", xml_normalize_string(name)); if (merge_name != NULL) fprintf(m_output, " merge=\"%s\"", xml_normalize_string(merge_name)); if (bios_name[0] != 0) fprintf(m_output, " bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) fprintf(m_output, " size=\"%d\"", rom_file_size(rom)); // dump checksum information only if there is a known dump if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) { // iterate over hash function types and print m_output their values astring tempstr; for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next()) fprintf(m_output, " %s=\"%s\"", hash->name(), hash->string(tempstr)); } // append a region name fprintf(m_output, " region=\"%s\"", ROMREGION_GETTAG(region)); // add nodump/baddump flags if (hashes.flag(hash_collection::FLAG_NO_DUMP)) fprintf(m_output, " status=\"nodump\""); if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) fprintf(m_output, " status=\"baddump\""); // for non-disk entries, print offset if (!is_disk) fprintf(m_output, " offset=\"%x\"", offset); // for disk entries, add the disk index else { fprintf(m_output, " index=\"%x\"", DISK_GETINDEX(rom)); fprintf(m_output, " writeable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes"); } // add optional flag if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom))) fprintf(m_output, " optional=\"yes\""); fprintf(m_output, "/>\n"); } } } }