Beispiel #1
0
static int addrs_configure(backend_t *chain, hash_t *config){
	ssize_t           ret;
	DT_UINT32T          elements_per_level = 0;
	DT_UINT32T          read_per_calc      = READ_PER_CALC_DEFAULT;
	addrs_userdata   *data = (addrs_userdata *)chain->userdata;
	
	hash_data_copy(ret, TYPE_UINT32T, elements_per_level, config, HK(perlevel));
	hash_data_copy(ret, TYPE_UINT32T, read_per_calc,      config, HK(read_size));
	
	if(elements_per_level <= 1)
		return -EINVAL; // "chain blocks-address variable 'per-level' invalid");
	
	if(read_per_calc < 1)
		read_per_calc = READ_PER_CALC_DEFAULT;
	
	if( (data->tree = tree_alloc(chain, elements_per_level, read_per_calc)) == NULL)
		return error("chain blocks-address no memory"); 
	
	if(tree_recalc(data->tree) != 0){
		tree_free(data->tree);
		return error("chain blocks-address tree recalc failed");
	}
	
	return 0;
}
Beispiel #2
0
static ssize_t          mphf_configure_any(backend_t *backend, config_t *config, request_t *fork_req){ // {{{
	ssize_t          ret;
	uintmax_t        fork_only       = 0;
	char            *mphf_type_str   = NULL;
	mphf_userdata   *userdata        = (mphf_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_STRINGT,  mphf_type_str,    config, HK(type));
	hash_data_copy(ret, TYPE_UINTT,    fork_only,        config, HK(fork_only));
	hash_data_copy(ret, TYPE_HASHKEYT, userdata->input,  config, HK(input));
	hash_data_copy(ret, TYPE_HASHKEYT, userdata->output, config, HK(output));
       
	if(fork_only == 1 && fork_req == NULL)
		return 0;

	if( (userdata->mphf_proto = mphf_string_to_proto(mphf_type_str)) == NULL)
		return error("backend mphf parameter mphf_type invalid or not supplied");
	
	memset(&userdata->mphf, 0, sizeof(userdata->mphf));
	
	userdata->mphf.config     = config;
	userdata->broken          = 0;

	if(fork_req == NULL){
		if( (ret = userdata->mphf_proto->func_load(&userdata->mphf)) < 0)
			return ret;
	}else{
		if( (ret = userdata->mphf_proto->func_fork(&userdata->mphf, fork_req)) < 0)
			return ret;
	}
	return 0;
} // }}}
Beispiel #3
0
static int call_configure(backend_t *backend, config_t *config){ // {{{
	ssize_t                ret;
	call_userdata         *userdata          = (call_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_HASHKEYT, userdata->hk_backend,    config, HK(input));
	hash_data_copy(ret, TYPE_UINTT,    userdata->retry_request, config, HK(retry));
	return 0;
} // }}}
Beispiel #4
0
static int hashtable_configure(backend_t *backend, config_t *config){ // {{{
	ssize_t                ret;
	hashtable_userdata    *userdata        = (hashtable_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_HASHKEYT, userdata->input,          config, HK(input));
       	hash_data_copy(ret, TYPE_UINTT,    userdata->hashtable_size, config, HK(nelements));
	
	if(userdata->hashtable_size == 0)
		return error("invalid hashtable size");
	return 0;
} // }}}
Beispiel #5
0
static int lookup_configure(backend_t *backend, config_t *config){ // {{{
	ssize_t                ret;
	lookup_userdata       *userdata          = (lookup_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_HASHKEYT,  userdata->output,        config, HK(output));
	hash_data_copy(ret, TYPE_DATATYPET, userdata->output_type,   config, HK(output_type));
	hash_data_copy(ret, TYPE_UINTT,     userdata->fatal,         config, HK(fatal));
	hash_data_copy(ret, TYPE_UINTT,     userdata->force_query,   config, HK(force_query));
	hash_data_copy(ret, TYPE_BACKENDT,  userdata->backend_index, config, HK(index));
	if(ret != 0)
		return error("supplied index backend not valid, or not found");
	
	return 0;
} // }}}
Beispiel #6
0
static ssize_t addrs_set(backend_t *chain, request_t *request){
	ssize_t           ret;
	uint32_t          r_block_vid, r_block_off, r_block_size, insert = 1;
	addrs_userdata   *data = (addrs_userdata *)chain->userdata;
	
	hash_data_copy(ret, TYPE_UINT32T, r_block_size, request, HK(block_size)); if(ret != 0) return error("no block_size supplied");
	hash_data_copy(ret, TYPE_UINT32T, r_block_off,  request, HK(block_off));  if(ret != 0) insert = 0;
	hash_data_copy(ret, TYPE_UINT32T, r_block_vid,  request, HK(block_vid));
	if(ret != 0)
		r_block_vid = tree_blocks_count(data->tree);
	
	if(insert == 0){
		return tree_resize_block(data->tree, r_block_vid, r_block_size);
	}
	return tree_insert(data->tree, r_block_vid, r_block_off, r_block_size);
}
Beispiel #7
0
static int null_configure(backend_t *backend, config_t *config){ // {{{
	ssize_t                ret;
	null_userdata         *userdata          = (null_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_UINTT, userdata->testparam, config, HK(test));
	return 0;
} // }}}
Beispiel #8
0
static ssize_t lists_set(backend_t *backend, request_t *request){
	ssize_t           ret;
	off_t             from, to;
	
	if(hash_find(request, HK(insert)) != NULL){
		// on insert we move all items from 'key' to 'key'+1
		// recommended use of 'blocks' backend as under-lying backend to improve perfomance
		
		hash_data_copy(ret, TYPE_OFFT, from, request, HK(offset));
		if(ret != 0)
			return warning("no offset supplied");
		
		to = from + 1;
		
		hash_t  new_request[] = {
			{ HK(action),      DATA_UINT32T(ACTION_MOVE)             },
			{ HK(offset_from), DATA_PTR_OFFT(&from)                       },
			{ HK(offset_to),   DATA_PTR_OFFT(&to)                         },
			{ HK(size),        DATA_VOID                                  },
			hash_next(request)
		};
		
		if( (ret = backend_pass(backend, new_request)) < 0)
			return ret;
	}
	
	return ( (ret = backend_pass(backend, request)) < 0) ? ret : -EEXIST;
}
Beispiel #9
0
static int stdout_configure(backend_t *backend, hash_t *config){ // {{{
	ssize_t                ret;
	std_userdata          *userdata          = (std_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_HASHKEYT, userdata->key,      config, HK(input));
	return 0;
} // }}}
Beispiel #10
0
static ssize_t call_handler(backend_t *backend, request_t *request){ // {{{
	ssize_t                ret;
	backend_t             *call_to           = NULL;
	call_userdata         *userdata          = (call_userdata *)backend->userdata;
	
	hash_data_copy(ret, TYPE_BACKENDT, call_to, request, userdata->hk_backend);
	if(call_to)
		return ( (ret = backend_query(call_to, request)) < 0 ) ? ret : -EEXIST;
	
	ret = ( (ret = backend_pass(backend, request)) < 0 ) ? ret : -EEXIST;
	
	if(userdata->retry_request != 0){
		hash_data_copy(ret, TYPE_BACKENDT, call_to, request, userdata->hk_backend);
		if(call_to)
			return ( (ret = backend_query(call_to, request)) < 0 ) ? ret : -EEXIST;
	}
	return ret;
} // }}}
Beispiel #11
0
static ssize_t hashtable_handler(backend_t *backend, request_t *request){ // {{{
	ssize_t                ret;
	uint32_t               action;
	uintmax_t              d_input;
	hashtable_userdata    *userdata          = (hashtable_userdata *)backend->userdata;

	hash_data_copy(ret, TYPE_UINT32T, action,  request, HK(action));         if(ret != 0) return -ENOSYS;
	hash_data_copy(ret, TYPE_UINTT,   d_input, request, userdata->input);
	if(ret == 0){
		d_input = d_input % userdata->hashtable_size;
		
		request_t r_next[] = {
			{ userdata->input,  DATA_PTR_UINTT(&d_input) },
			hash_next(request)
		};
		return ( (ret = backend_pass(backend, r_next)) < 0 ) ? ret : -EEXIST;
	}
	return ( (ret = backend_pass(backend, request)) < 0 ) ? ret : -EEXIST;
} // }}}
Beispiel #12
0
static ssize_t null_create(backend_t *backend, request_t *request){
	ssize_t       ret;
	size_t        value;
	
	hash_data_copy(ret, TYPE_SIZET, value, request, HK(size));
	if(ret == 0 && value == 0x0000BEEF)
		return value;
	
	return ( (ret = backend_pass(backend, request)) < 0) ? ret : -EEXIST;
}
Beispiel #13
0
static ssize_t addrs_delete(backend_t *chain, request_t *request){
	ssize_t          ret;
	uint32_t         r_block_vid;
	addrs_userdata  *data = (addrs_userdata *)chain->userdata;
	
	hash_data_copy(ret, TYPE_UINT32T, r_block_vid, request, HK(block_vid));
	if(ret != 0)
		return -EINVAL;
	
	return tree_delete_block(data->tree, r_block_vid);
}
Beispiel #14
0
static ssize_t lists_delete(backend_t *backend, request_t *request){
	ssize_t           ret;
	off_t             from, to;
	size_t            size;
	
	hash_data_copy(ret, TYPE_SIZET, size,   request, HK(size));   if(ret != 0) return warning("no size supplied");
	hash_data_copy(ret, TYPE_OFFT,  from,   request, HK(offset)); if(ret != 0) return warning("no offset supplied");
	
	to = from;
	from += size;
	
	hash_t  new_request[] = {
		{ HK(action),      DATA_UINT32T(ACTION_MOVE)             },
		{ HK(offset_from), DATA_PTR_OFFT(&from)                       },
		{ HK(offset_to),   DATA_PTR_OFFT(&to)                         },
		{ HK(size),        DATA_VOID                                  },
		hash_next(request)
	};
	return ( (ret = backend_pass(backend, new_request)) < 0) ? ret : -EEXIST;
}
Beispiel #15
0
static ssize_t addrs_get(backend_t *chain, request_t *request){
	ssize_t           ret;
	data_t           *temp;
	off_t             def_real_offset;
	unsigned int      def_block_vid;
	unsigned int      def_block_size;
	off_t            *o_real_offset = &def_real_offset;
	unsigned int     *o_block_vid   = &def_block_vid;
	unsigned int     *o_block_size  = &def_block_size;
	block_info        block;
	off_t             r_virt_key;
	uint32_t          r_block_vid;
	hash_t           *r_virt_key, *r_block_vid;
	addrs_userdata   *data = (addrs_userdata *)chain->userdata;
	
	temp = hash_find_typed(request, TYPE_OFFT,  HK(real_offset));
	if(temp != NULL) o_real_offset = data_value_ptr(temp);
	temp = hash_find_typed(request, TYPE_UINT32T, HK(block_vid));
	if(temp != NULL) o_block_vid   = data_value_ptr(temp);
	temp = hash_find_typed(request, TYPE_UINT32T, HK(block_size));
	if(temp != NULL) o_block_size  = data_value_ptr(temp);
	
	if(hash_find(request, HK(blocks)) == NULL){
		hash_data_copy(ret, TYPE_OFFT, r_virt_key, request, HK(offset)); if(ret != 0) return warning("no offset supplied");
		
		if(tree_get(data->tree, r_virt_key, o_block_vid, o_real_offset) != 0)
			return -EFAULT;
	}else{
		hash_data_copy(ret, TYPE_UINT32T, r_block_vid, request, HK(block_vid)); if(ret != 0) return warning("no block_vid supplied");
		
		if(tree_get_block(data->tree, r_block_vid, &block) != 0)
			return -EFAULT;
		
		*o_real_offset = (off_t)(block.real_block_off);
		*o_block_size  = (unsigned int)(block.size);
	}
	return 0;
}
Beispiel #16
0
int mame_fchecksum(const char *gamename, const char *filename, unsigned int *length, char* hash)
{
	mame_file *file;

	/* first open the file; we pass the source hash because it contains
	   the expected checksum for the file (used to load by checksum) */
	file = generic_fopen(FILETYPE_ROM, gamename, filename, hash, FILEFLAG_OPENREAD | FILEFLAG_HASH | FILEFLAG_VERIFY_ONLY);

	/* if we didn't succeed return -1 */
	if (!file)
		return -1;

	/* close the file and save the length & checksum */
	hash_data_copy(hash, file->hash);
	*length = file->length;
	mame_fclose(file);
	return 0;
}
Beispiel #17
0
static ssize_t mphf_handler(backend_t *backend, request_t *request){ // {{{
	ssize_t               ret;
	uint32_t              action;
	uintmax_t             d_input;
	uintmax_t            *d_output;
	data_t               *data_output;
	mphf_userdata        *userdata           = (mphf_userdata *)backend->userdata;

	hash_data_copy(ret, TYPE_UINT32T, action, request, HK(action));
	if(ret != 0)
		return -ENOSYS;
	
	// rebuilds
	if(action == ACTION_REBUILD){
		if( (ret = userdata->mphf_proto->func_rebuild(&userdata->mphf)) < 0)
			return ret;
		
		userdata->broken = 0;
		return -EBADF;
	}
	if(userdata->broken != 0)
		return -EBADF;
	//
	
	hash_data_copy(ret, TYPE_UINTT, d_input, request, userdata->input);
	if(ret != 0)
		return -EINVAL;
	
	data_output = hash_data_find(request, userdata->output);
	if(data_output == NULL)
		return -EINVAL;
	
	d_output = data_output->ptr;
	
	switch(action){
		case ACTION_CREATE:
			if( (ret = userdata->mphf_proto->func_insert(
				&userdata->mphf, 
				d_input,
				*d_output
			)) < 0){
				if(ret == -EBADF)
					userdata->broken = 1;
				return ret;
			}
			break;
		case ACTION_WRITE:
			if( (ret = userdata->mphf_proto->func_update(
				&userdata->mphf, 
				d_input,
				*d_output
			)) < 0){
				if(ret == -EBADF)
					userdata->broken = 1;
				return ret;
			}
			break;
		case ACTION_READ:
			switch( (ret = userdata->mphf_proto->func_query(
				&userdata->mphf,
				d_input,
				d_output
			))){
				case MPHF_QUERY_NOTFOUND: return -ENOENT;
				case MPHF_QUERY_FOUND:    break;
				default:                  return ret;
			};
			break;
		case ACTION_DELETE:
			if( (ret = userdata->mphf_proto->func_delete(
				&userdata->mphf, 
				d_input
			)) < 0){
				if(ret == -EBADF)
					userdata->broken = 1;
				return ret;
			}
			
			break;
	}
	return 0;
} // }}}
Beispiel #18
0
static void audit_one_rom(core_options *options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, UINT32 validation, audit_record *record)
{
	const game_driver *drv;
	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);
	record->length = 0;
	record->explength = rom_file_size(rom);

	/* 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))
	{
		file_error filerr;
		mame_file *file;

		/* open the file if we can */
		astring fname(drv->name, PATH_SEPARATOR, ROM_GETNAME(rom));
	    if (has_crc)
			filerr = mame_fopen_crc_options(options, libretro_content_directory, fname, crc, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD, &file);
		else
			filerr = mame_fopen_options(options, libretro_content_directory, fname, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD, &file);

		/* 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 not found, check the region as a backup */
	if (record->length == 0 && regiontag != NULL)
	{
		file_error filerr;
		mame_file *file;

		/* open the file if we can */
		astring fname(regiontag, PATH_SEPARATOR, ROM_GETNAME(rom));
	    if (has_crc)
			filerr = mame_fopen_crc_options(options, libretro_content_directory, fname, crc, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD, &file);
		else
			filerr = mame_fopen_options(options, libretro_content_directory, fname, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD, &file);

		/* 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);
		}
	}

	/* if we failed to find the file, set the appropriate status */
	if (record->length == 0)
	{
		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 & GAME_IS_BIOS_ROOT) ? 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);
	}
}
Beispiel #19
0
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);
}
Beispiel #20
0
static ssize_t chm_imp_configure  (mphf_t *mphf, request_t *fork_req){ // {{{
	ssize_t                ret;
	backend_t             *t;
	backend_t             *be_g              = NULL;
	backend_t             *be_v              = NULL;
	backend_t             *be_e              = NULL;
	char                  *backend           = NULL;
	uintmax_t              nelements_min     = CAPACITY_MIN_DEFAULT;
	uintmax_t              nelements_step    = CAPACITY_STEP_DEFAULT;
	uintmax_t              nelements_mul     = CAPACITY_MUL_DEFAULT;
	uintmax_t              bi_value          = VALUE_BITS_DEFAULT;
	uintmax_t              readonly          = 0;
	chm_imp_t             *data              = (chm_imp_t *)&mphf->data;
	
	if( (data->status & FILLED) == 0){
		hash_data_copy(ret, TYPE_UINTT,  nelements_min,  mphf->config, HK(nelements_min));
		hash_data_copy(ret, TYPE_UINTT,  nelements_step, mphf->config, HK(nelements_step));
		hash_data_copy(ret, TYPE_UINTT,  nelements_mul,  mphf->config, HK(nelements_mul));
		hash_data_copy(ret, TYPE_UINTT,  bi_value,       mphf->config, HK(value_bits));     // number of bits per value to store
		hash_data_copy(ret, TYPE_UINTT,  readonly,       mphf->config, HK(readonly));       // run in read-only mode
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_g));
		if(ret == 0){
			be_g = t = backend_acquire(backend);
			if(fork_req){
				be_g = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_v));
		if(ret == 0){
			be_v = t = backend_acquire(backend);
			if(fork_req){
				be_v = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_e));
		if(ret == 0){
			be_e = t = backend_acquire(backend);
			if(fork_req){
				be_e = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		
		if(be_g == NULL)
			return error("backend chm_imp parameter backend_g invalid");
		
		if(be_v == NULL || be_e == NULL || readonly != 0){
			data->status &= ~WRITEABLE;
		}else{
			data->status |= WRITEABLE;
		}
		
		data->be_g           = be_g;
		data->be_v           = be_v;
		data->be_e           = be_e;
		data->nelements_min  = nelements_min;
		data->nelements_step = nelements_step;
		data->nelements_mul  = nelements_mul;
		data->bi_value       = bi_value;
		data->bt_value       = BITS_TO_BYTES(data->bi_value);
		
		data->status        |= FILLED;
	}
	return 0;
} // }}}
Beispiel #21
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;
}