Пример #1
0
static int verify_length_and_hash(emu_file *file, const char *name, UINT32 explength, const util::hash_collection &hashes)
{
	int retVal = 0;
	if (file==nullptr) return 0;

	// verify length
	UINT32 actlength = file->size();
	if (explength != actlength)
	{
		osd_printf_error("%s WRONG LENGTH (expected: %d found: %d)\n", name, explength, actlength);
		retVal++;
	}

	// If there is no good dump known, write it
	util::hash_collection &acthashes = file->hashes(hashes.hash_types().c_str());
	if (hashes.flag(util::hash_collection::FLAG_NO_DUMP))
	{
		osd_printf_error("%s NO GOOD DUMP KNOWN\n", name);
	}
	// verify checksums
	else if (hashes != acthashes)
	{
		// otherwise, it's just bad
		osd_printf_error("%s WRONG CHECKSUMS:\n", name);
		dump_wrong_and_correct_checksums(hashes, acthashes);
		retVal++;
	}
	// If it matches, but it is actually a bad dump, write it
	else if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP))
	{
		osd_printf_error("%s NEEDS REDUMP\n",name);
	}
	return retVal;
}
Пример #2
0
void a78_partialhash(util::hash_collection &dest, const unsigned char *data,
						unsigned long length, const char *functions)
{
	if (length <= 128)
		return;
	dest.compute(&data[128], length - 128, functions);
}
Пример #3
0
void device_image_interface::device_compute_hash(util::hash_collection &hashes, const void *data, size_t length, const char *types) const
{
	/* retrieve the partial hash func */
	device_image_partialhash_func partialhash = get_partial_hash();

	/* compute the hash */
	if (partialhash)
		partialhash(hashes, (const unsigned char*)data, length, types);
	else
		hashes.compute(reinterpret_cast<const UINT8 *>(data), length, types);
}
Пример #4
0
static bool read_hash_config(const char *hash_path, const util::hash_collection &hashes, const char *sysname, std::string &result)
{
	/* open a file */
	emu_file file(hash_path, OPEN_FLAG_READ);
	if (file.open(sysname, ".hsi") != osd_file::error::NONE)
	{
		return false;
	}

	pugi::xml_document doc;

	pugi::xml_parse_result res = doc.load_file(file.fullpath());
	if (res)
	{
		// Do search by CRC32 and SHA1
		std::string query = "/hashfile/hash[";
		auto crc = hashes.internal_string().substr(1,8);
		auto sha1 = hashes.internal_string().substr(10, 40);
		query += "@crc32='" + crc + "' and @sha1='" + sha1 + "']/extrainfo";
		pugi::xpath_node_set tools = doc.select_nodes(query.c_str());
		for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
		{
			result = it->node().first_child().value();
			return true;
		}

		// Try search by CRC32 only
		query = "/hashfile/hash[";
		query += "@crc32='" + crc + "']/extrainfo";
		tools = doc.select_nodes(query.c_str());
		for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
		{
			result = it->node().first_child().value();
			return true;
		}

	}
	return false;
}
Пример #5
0
void device_image_interface::run_hash(void (*partialhash)(util::hash_collection &, const unsigned char *, unsigned long, const char *),
	util::hash_collection &hashes, const char *types)
{
	UINT32 size;
	dynamic_buffer buf;

	hashes.reset();
	size = (UINT32) length();

	buf.resize(size);
	memset(&buf[0], 0, size);

	// read the file
	fseek(0, SEEK_SET);
	fread(&buf[0], size);

	if (partialhash)
		partialhash(hashes, &buf[0], size, types);
	else
		hashes.compute(&buf[0], size, types);

	// cleanup
	fseek(0, SEEK_SET);
}
Пример #6
0
void media_identifier::file_info::match(
		device_t const &device,
		romload::file const &rom,
		util::hash_collection const &hashes)
{
	if (hashes == m_hashes)
	{
		m_matches.emplace_back(
				device.shortname(),
				device.name(),
				rom.get_name(),
				hashes.flag(util::hash_collection::FLAG_BAD_DUMP),
				device.owner());
	}
}
Пример #7
0
void rom_load_manager::verify_length_and_hash(const char *name, UINT32 explength, const util::hash_collection &hashes)
{
	/* we've already complained if there is no file */
	if (m_file == nullptr)
		return;

	/* verify length */
	UINT32 actlength = m_file->size();
	if (explength != actlength)
	{
		m_errorstring.append(string_format("%s WRONG LENGTH (expected: %08x found: %08x)\n", name, explength, actlength));
		m_warnings++;
	}

	/* If there is no good dump known, write it */
	util::hash_collection &acthashes = m_file->hashes(hashes.hash_types().c_str());
	if (hashes.flag(util::hash_collection::FLAG_NO_DUMP))
	{
		m_errorstring.append(string_format("%s NO GOOD DUMP KNOWN\n", name));
		m_knownbad++;
	}
	/* verify checksums */
	else if (hashes != acthashes)
	{
		/* otherwise, it's just bad */
		m_errorstring.append(string_format("%s WRONG CHECKSUMS:\n", name));
		dump_wrong_and_correct_checksums(hashes, acthashes);
		m_warnings++;
	}
	/* If it matches, but it is actually a bad dump, write it */
	else if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP))
	{
		m_errorstring.append(string_format("%s ROM NEEDS REDUMP\n", name));
		m_knownbad++;
	}
}
Пример #8
0
void media_identifier::file_info::match(
		std::string const &list,
		software_info const &software,
		rom_entry const &rom,
		util::hash_collection const &hashes)
{
	if (hashes == m_hashes)
	{
		m_matches.emplace_back(
				util::string_format("%s:%s", list, software.shortname()),
				std::string(software.longname()),
				ROM_GETNAME(&rom),
				hashes.flag(util::hash_collection::FLAG_BAD_DUMP),
				false);
	}
}
Пример #9
0
static void dump_wrong_and_correct_checksums(const util::hash_collection &hashes, const util::hash_collection &acthashes)
{
	osd_printf_error("    EXPECTED: %s\n", hashes.macro_string().c_str());
	osd_printf_error("       FOUND: %s\n", acthashes.macro_string().c_str());
}
Пример #10
0
void media_identifier::match_hashes(std::vector<file_info> &info)
{
	std::unordered_set<std::string> listnames;

	// iterate over drivers
	m_drivlist.reset();
	while (m_drivlist.next())
	{
		// iterate over regions and files within the region
		device_t &device = m_drivlist.config()->root_device();
		for (romload::region const &region : romload::entries(device.rom_region()).get_regions())
		{
			for (romload::file const &rom : region.get_files())
			{
				util::hash_collection const romhashes(rom.get_hashdata());
				if (!romhashes.flag(util::hash_collection::FLAG_NO_DUMP))
				{
					for (file_info &file : info)
						file.match(device, rom, romhashes);
				}
			}
		}

		// next iterate over softlists
		for (software_list_device &swlistdev : software_list_device_iterator(device))
		{
			if (listnames.insert(swlistdev.list_name()).second)
			{
				for (software_info const &swinfo : swlistdev.get_info())
				{
					for (software_part const &part : swinfo.parts())
					{
						for (rom_entry const *region = part.romdata().data(); region; region = rom_next_region(region))
						{
							for (rom_entry const *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
							{
								util::hash_collection romhashes(ROM_GETHASHDATA(rom));
								if (!romhashes.flag(util::hash_collection::FLAG_NO_DUMP))
								{
									for (file_info &file : info)
										file.match(swlistdev.list_name(), swinfo, *rom, romhashes);
								}
							}
						}
					}
				}
			}
		}
	}

	// iterator over devices
	machine_config config(GAME_NAME(___empty), m_drivlist.options());
	for (device_type type : registered_device_types)
	{
		// iterate over regions and files within the region
		device_t *const device = config.device_add(&config.root_device(), "_tmp", type, 0);
		for (romload::region const &region : romload::entries(device->rom_region()).get_regions())
		{
			for (romload::file const &rom : region.get_files())
			{
				util::hash_collection const romhashes(rom.get_hashdata());
				if (!romhashes.flag(util::hash_collection::FLAG_NO_DUMP))
				{
					for (file_info &file : info)
						file.match(*device, rom, romhashes);
				}
			}
		}
		config.device_remove(&config.root_device(), "_tmp");
	}
}
Пример #11
0
void rom_load_manager::dump_wrong_and_correct_checksums(const util::hash_collection &hashes, const util::hash_collection &acthashes)
{
	m_errorstring.append(string_format("    EXPECTED: %s\n", hashes.macro_string().c_str()));
	m_errorstring.append(string_format("       FOUND: %s\n", acthashes.macro_string().c_str()));
}