Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
static DEVICE_IMAGE_LOAD(cdrom)
{
	dev_cdrom_t	*cdrom = get_safe_token(&image.device());
	chd_error	err = (chd_error)0;
	chd_file	*chd = NULL;
	astring tempstring;

	if (image.software_entry() == NULL)
	{
		err = chd_open_file( image.image_core_file(), CHD_OPEN_READ, NULL, &chd );	/* CDs are never writeable */
		if ( err )
			goto error;
	} else {
		chd  = get_disk_handle(image.device().machine, image.device().subtag(tempstring,"cdrom"));
	}

	/* open the CHD file */
	cdrom->cdrom_handle = cdrom_open( chd );
	if ( ! cdrom->cdrom_handle )
		goto error;

	return IMAGE_INIT_PASS;

error:
	if ( chd )
		chd_close( chd );
	if ( err )
		image.seterror( IMAGE_ERROR_UNSPECIFIED, chd_get_error_string( err ) );
	return IMAGE_INIT_FAIL;
}
Exemple #4
0
static int internal_load_mess_cd(mess_image *image, const char *metadata)
{
	chd_error err = 0;
	struct mess_cd *cd;
	chd_file *chd;
	int id = image_index_in_device(image);

	cd = get_drive(image);

	/* open the CHD file */
	err = chdcd_open_ref(image, CHD_OPEN_READ, NULL, &chd);	/* CDs are never writable */
	if (err)
		goto error;

	/* open the CD-ROM file */
	cd->cdrom_handle = cdrom_open(chd);
	if (!cd->cdrom_handle)
		goto error;

	drive_handles[id] = cd->cdrom_handle;
	return INIT_PASS;

error:
	if (chd)
		chd_close(chd);
	if (err)
		image_seterror(image, IMAGE_ERROR_UNSPECIFIED, chd_get_error_string(err));
	return INIT_FAIL;
}
Exemple #5
0
static int internal_load_mess_hd(mess_image *image, const char *metadata)
{
	int err = 0;
	struct mess_hd *hd;
	chd_file *chd;
	int is_writeable;
	int id = image_index_in_device(image);

	hd = get_drive(image);

	/* open the CHD file */
	do
	{
		is_writeable = image_is_writable(image);
		chd = chd_open_ref(image, is_writeable, NULL);

		if (!chd)
		{
			err = chd_get_last_error();

			/* special case; if we get CHDERR_FILE_NOT_WRITEABLE, make the
			 * image read only and repeat */
			if (err == CHDERR_FILE_NOT_WRITEABLE)
				image_make_readonly(image);
		}
	}
	while(!chd && is_writeable && (err == CHDERR_FILE_NOT_WRITEABLE));
	if (!chd)
		goto error;

	/* if we created the image and hence, have metadata to set, set the metadata */
	if (metadata)
	{
		err = chd_set_metadata(chd, HARD_DISK_STANDARD_METADATA, 0, metadata, strlen(metadata) + 1);
		if (err != CHDERR_NONE)
			goto error;
	}

	/* open the hard disk file */
	hd->hard_disk_handle = hard_disk_open(chd);
	if (!hd->hard_disk_handle)
		goto error;

	drive_handles[id] = hd->hard_disk_handle;

	return INIT_PASS;

error:
	if (chd)
		chd_close(chd);

	err = chd_get_last_error();
	if (err)
		image_seterror(image, IMAGE_ERROR_UNSPECIFIED, chd_get_error_string(err));
	return INIT_FAIL;
}
Exemple #6
0
int harddisk_image_device::internal_load_hd(const char *metadata)
{
	chd_error		err = (chd_error)0;
	int				is_writeable;

	/* open the CHD file */
	do
	{
		is_writeable = !is_readonly();
		m_chd = NULL;
		err = chd_open_file(image_core_file(), is_writeable ? CHD_OPEN_READWRITE : CHD_OPEN_READ, NULL, &m_chd);

		/* special case; if we get CHDERR_FILE_NOT_WRITEABLE, make the
         * image read only and repeat */
		if (err == CHDERR_FILE_NOT_WRITEABLE)
			make_readonly();
	}
	while(!m_chd && is_writeable && (err == CHDERR_FILE_NOT_WRITEABLE));
	if (!m_chd)
		goto done;

	/* if we created the image and hence, have metadata to set, set the metadata */
	if (metadata)
	{
		err = chd_set_metadata(m_chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
		if (err != CHDERR_NONE)
			goto done;
	}

	/* open the hard disk file */
	m_hard_disk_handle = hard_disk_open(m_chd);
	if (!m_hard_disk_handle)
		goto done;

done:
	if (err)
	{
		/* if we had an error, close out the CHD */
		if (m_chd != NULL)
		{
			chd_close(m_chd);
			m_chd = NULL;
		}

		seterror(IMAGE_ERROR_UNSPECIFIED, chd_get_error_string(err));
	}
	return err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS;
}
Exemple #7
0
void harddisk_image_device::call_unload()
{
	/* Check if there is an image_unload callback defined */
	if ( m_device_image_unload )
	{
		m_device_image_unload(*this);
	}

	if (m_hard_disk_handle != NULL)
	{
		hard_disk_close(m_hard_disk_handle);
		m_hard_disk_handle = NULL;
	}

	if (m_chd != NULL)
	{
		chd_close(m_chd);
		m_chd = NULL;
	}
}
Exemple #8
0
/*
	imghd_close()

	Close MAME HD image
*/
void imghd_close(struct mess_hard_disk_file *disk)
{
	chd_interface interface_save;

	chd_save_interface(&interface_save);
	chd_set_interface(&imgtool_chd_interface);

	if (disk->hard_disk)
	{
		hard_disk_close(disk->hard_disk);
		disk->hard_disk = NULL;
	}
	if (disk->chd)
	{
		chd_close(disk->chd);
		disk->chd = NULL;
	}

	chd_set_interface(&interface_save);
}
Exemple #9
0
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);
	}
}
/* 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;
}
Exemple #11
0
/*
	imghd_create()

	Create a MAME HD image
*/
imgtoolerr_t imghd_create(imgtool_stream *stream, UINT32 hunksize, UINT32 cylinders, UINT32 heads, UINT32 sectors, UINT32 seclen)
{
	imgtoolerr_t err = IMGTOOLERR_SUCCESS;
	char encoded_image_ref[encoded_image_ref_max_len];
	chd_interface interface_save;
	UINT8 *cache = NULL;
	chd_file *chd = NULL;
	int rc;
	UINT64 logicalbytes;
	int hunknum, totalhunks;
	char metadata[256];

	/* jump through the hoops as required by the CHD system */
	encode_image_ref(stream, encoded_image_ref);
	chd_save_interface(&interface_save);
	chd_set_interface(&imgtool_chd_interface);

	/* sanity check args */
	if (hunksize >= 2048)
	{
		err = IMGTOOLERR_PARAMCORRUPT;
		goto done;
	}
	if (hunksize <= 0)
		hunksize = 1024;	/* default value */

	/* bail if we are read only */
	if (stream_isreadonly(stream))
	{
		err = IMGTOOLERR_READONLY;
		goto done;
	}

	/* calculations */
	logicalbytes = (UINT64)cylinders * heads * sectors * seclen;

	/* create the new hard drive */
	rc = chd_create(encoded_image_ref, logicalbytes, hunksize, CHDCOMPRESSION_NONE, NULL);
	if (rc != CHDERR_NONE)
	{
		err = map_chd_error(rc);
		goto done;
	}

	/* open the new hard drive */
	rc = chd_open(encoded_image_ref, CHD_OPEN_READWRITE, NULL, &chd);
	if (rc != CHDERR_NONE)
	{
		err = map_chd_error(rc);
		goto done;
	}

	/* write the metadata */
	sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, seclen);
	err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1);
	if (rc != CHDERR_NONE)
	{
		err = map_chd_error(rc);
		goto done;
	}

	/* alloc and zero buffer */
	cache = malloc(hunksize);
	if (!cache)
	{
		err = IMGTOOLERR_OUTOFMEMORY;
		goto done;
	}
	memset(cache, '\0', hunksize);

	/* zero out every hunk */
	totalhunks = (logicalbytes + hunksize - 1) / hunksize;
	for (hunknum = 0; hunknum < totalhunks; hunknum++)
	{
		rc = chd_write(chd, hunknum, cache);
		if (rc)
		{
			err = IMGTOOLERR_WRITEERROR;
			goto done;
		}
	}

	
done:
	if (cache)
		free(cache);
	if (chd)
		chd_close(chd);
	chd_set_interface(&interface_save);
	return err;
}
Exemple #12
0
static void close_chd(void *file)
{
	chd_close((chd_file *)file);
}
Exemple #13
0
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);
		}
	}
}