コード例 #1
0
ファイル: audit.c プロジェクト: thige/mameui
//-------------------------------------------------
//  audit_software
//-------------------------------------------------
media_auditor::summary media_auditor::audit_software(const char *list_name, software_info *swinfo, const char *validation)
{
	// start fresh
	m_record_list.reset();

	// store validation for later
	m_validation = validation;

	std::string combinedpath(swinfo->shortname());
	combinedpath.append(";");
	combinedpath.append(list_name);
	combinedpath.append(PATH_SEPARATOR);
	combinedpath.append(swinfo->shortname());
	std::string locationtag(list_name);
	locationtag.append("%");
	locationtag.append(swinfo->shortname());
	locationtag.append("%");
	if (swinfo->parentname() != NULL)
	{
		locationtag.append(swinfo->parentname());
		combinedpath.append(";").append(swinfo->parentname()).append(";").append(list_name).append(PATH_SEPARATOR).append(swinfo->parentname());
	}
	m_searchpath = combinedpath.c_str();

	int found = 0;
	int required = 0;

	// now iterate over software parts
	for ( software_part *part = swinfo->first_part(); part != NULL; part = part->next() )
	{
		// now iterate over regions
		for ( const rom_entry *region = part->romdata(); region; region = rom_next_region( region ) )
		{
			// now iterate over rom definitions
			for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
			{
				hash_collection hashes(ROM_GETHASHDATA(rom));

				// count the number of files with hashes
				if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && !ROM_ISOPTIONAL(rom))
				{
					required++;
				}

				// audit a file
				audit_record *record = NULL;
				if (ROMREGION_ISROMDATA(region))
				{
					record = audit_one_rom(rom);
				}
				// audit a disk
				else if (ROMREGION_ISDISKDATA(region))
				{
					record = audit_one_disk(rom, locationtag.c_str());
				}

				// count the number of files that are found.
				if (record != NULL && (record->status() == audit_record::STATUS_GOOD || record->status() == audit_record::STATUS_FOUND_INVALID))
				{
					found++;
				}
			}
		}
	}

	if (found == 0 && required > 0)
	{
		m_record_list.reset();
		return NOTFOUND;
	}

	// return a summary
	return summarize(list_name);
}
コード例 #2
0
ファイル: info.c プロジェクト: rogerjowett/ClientServerMAME
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");
				}
			}
	}
}
コード例 #3
0
ファイル: audit.c プロジェクト: shangma/mame0112
static int audit_one_rom(const rom_entry *rom, const game_driver *gamedrv, UINT32 validation, audit_record *record)
{
	const game_driver *drv;
	const rom_entry *chunk;
	UINT32 crc = 0;
	UINT8 crcs[4];
	int has_crc;

	/* fill in the record basics */
	record->type = AUDIT_FILE_ROM;
	record->name = ROM_GETNAME(rom);
	record->exphash = ROM_GETHASHDATA(rom);

	/* compute the expected length by summing the chunks */
	for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk))
		record->explength += ROM_GETLENGTH(chunk);

	/* see if we have a CRC and extract it if so */
	has_crc = hash_data_extract_binary_checksum(record->exphash, HASH_CRC, crcs);
	if (has_crc)
		crc = (crcs[0] << 24) | (crcs[1] << 16) | (crcs[2] << 8) | crcs[3];

	/* find the file and checksum it, getting the file length along the way */
	for (drv = gamedrv; drv != NULL; drv = driver_get_clone(drv))
	{
		mame_file_error filerr;
		mame_file *file;
		char *fname;

		/* open the file if we can */
		fname = assemble_3_strings(drv->name, PATH_SEPARATOR, ROM_GETNAME(rom));
	    if (has_crc)
			filerr = mame_fopen_crc(SEARCHPATH_ROM, fname, crc, OPEN_FLAG_READ, &file);
		else
			filerr = mame_fopen(SEARCHPATH_ROM, fname, OPEN_FLAG_READ, &file);
		free(fname);

		/* if we got it, extract the hash and length */
		if (filerr == FILERR_NONE)
		{
			hash_data_copy(record->hash, mame_fhash(file, validation));
			record->length = (UINT32)mame_fsize(file);
			mame_fclose(file);
			break;
		}
	}

	/* if we failed to find the file, set the appropriate status */
	if (drv == NULL)
	{
		const game_driver *parent;

		/* no good dump */
		if (hash_data_has_info(record->exphash, HASH_INFO_NO_DUMP))
			set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND_NODUMP);

		/* optional ROM */
		else if (ROM_ISOPTIONAL(rom))
			set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND_OPTIONAL);

		/* not found and used by parent */
		else if (rom_used_by_parent(gamedrv, rom, &parent))
			set_status(record, AUDIT_STATUS_NOT_FOUND, (parent->flags & NOT_A_DRIVER) ? SUBSTATUS_NOT_FOUND_BIOS : SUBSTATUS_NOT_FOUND_PARENT);

		/* just plain old not found */
		else
			set_status(record, AUDIT_STATUS_NOT_FOUND, SUBSTATUS_NOT_FOUND);
	}

	/* if we did find the file, do additional verification */
	else
	{
		/* length mismatch */
		if (record->explength != record->length)
			set_status(record, AUDIT_STATUS_FOUND_INVALID, SUBSTATUS_FOUND_WRONG_LENGTH);

		/* found but needs a dump */
		else 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 old good */
		else
			set_status(record, AUDIT_STATUS_GOOD, SUBSTATUS_GOOD);
	}

	/* return TRUE if we found anything at all */
	return (drv != NULL);
}
コード例 #4
0
/* 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;
}
コード例 #5
0
ファイル: audit.cpp プロジェクト: kaspal/mame
media_auditor::summary media_auditor::audit_media(const char *validation)
{
	// start fresh
	m_record_list.reset();

	// store validation for later
	m_validation = validation;

// temporary hack until romload is update: get the driver path and support it for
// all searches
const char *driverpath = m_enumerator.config().root_device().searchpath();

	int found = 0;
	int required = 0;
	int shared_found = 0;
	int shared_required = 0;

	// iterate over devices and regions
	device_iterator deviter(m_enumerator.config().root_device());
	for (device_t *device = deviter.first(); device != nullptr; device = deviter.next())
	{
		// determine the search path for this source and iterate through the regions
		m_searchpath = device->searchpath();

		// now iterate over regions and ROMs within
		for (const rom_entry *region = rom_first_region(*device); region != nullptr; region = rom_next_region(region))
		{
// temporary hack: add the driver path & region name
std::string combinedpath = std::string(device->searchpath()).append(";").append(driverpath);
if (device->shortname())
	combinedpath.append(";").append(device->shortname());
m_searchpath = combinedpath.c_str();

			for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
			{
				const char *name = ROM_GETNAME(rom);
				hash_collection hashes(ROM_GETHASHDATA(rom));
				device_t *shared_device = find_shared_device(*device, name, hashes, ROM_GETLENGTH(rom));

				// count the number of files with hashes
				if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && !ROM_ISOPTIONAL(rom))
				{
					required++;
					if (shared_device != nullptr)
						shared_required++;
				}

				// audit a file
				audit_record *record = nullptr;
				if (ROMREGION_ISROMDATA(region))
					record = audit_one_rom(rom);

				// audit a disk
				else if (ROMREGION_ISDISKDATA(region))
					record = audit_one_disk(rom);

				if (record != nullptr)
				{
					// count the number of files that are found.
					if (record->status() == audit_record::STATUS_GOOD || (record->status() == audit_record::STATUS_FOUND_INVALID && find_shared_device(*device, name, record->actual_hashes(), record->actual_length()) == nullptr))
					{
						found++;
						if (shared_device != nullptr)
							shared_found++;
					}

					record->set_shared_device(shared_device);
				}
			}
		}
	}

	// if we only find files that are in the parent & either the set has no unique files or the parent is not found, then assume we don't have the set at all
	if (found == shared_found && required > 0 && (required != shared_required || shared_found == 0))
	{
		m_record_list.reset();
		return NOTFOUND;
	}

	// return a summary
	return summarize(m_enumerator.driver().name);
}