static int image_checkhash(mess_image *image) { const game_driver *drv; const struct IODevice *dev; mame_file *file; char hash_string[HASH_BUF_SIZE]; int rc; /* this call should not be made when the image is not loaded */ assert(image->status & (IMAGE_STATUS_ISLOADING | IMAGE_STATUS_ISLOADED)); /* only calculate CRC if it hasn't been calculated, and the open_mode is read only */ if (!image->hash && !image->writeable && !image->created) { /* initialize key variables */ file = image_fp(image); dev = image_device(image); /* do not cause a linear read of 600 megs please */ /* TODO: use SHA/MD5 in the CHD header as the hash */ if (dev->type == IO_CDROM) return FALSE; if (!run_hash(file, dev->partialhash, hash_string, HASH_CRC | HASH_MD5 | HASH_SHA1)) return FALSE; image->hash = image_strdup(image, hash_string); if (!image->hash) return FALSE; /* now read the hash file */ drv = Machine->gamedrv; do { rc = read_hash_config(drv->name, image); drv = mess_next_compatible_driver(drv); } while(rc && drv); } return TRUE; }
static int image_load_internal(mess_image *image, const char *path, int is_create, int create_format, option_resolution *create_args) { image_error_t err; const char *software_path; char *software_path_list = NULL; const void *buffer; const game_driver *gamedrv; UINT32 open_plan[4]; int i; /* sanity checks */ assert_always(image, "image_load(): image is NULL"); assert_always(path, "image_load(): path is NULL"); /* we are now loading */ image->is_loading = 1; /* first unload the image */ image_unload(image); /* record the filename */ image->err = set_image_filename(image, path, NULL); if (image->err) goto done; /* tell the OSD layer that this is changing */ osd_image_load_status_changed(image, 0); /* do we need to reset the CPU? */ if ((timer_get_time() > 0) && image->dev->reset_on_load) mame_schedule_soft_reset(Machine); /* determine open plan */ determine_open_plan(image, is_create, open_plan); /* attempt to open the file in various ways */ for (i = 0; !image->file && open_plan[i]; i++) { software_path = software_path_list; do { gamedrv = Machine->gamedrv; while(!is_loaded(image) && gamedrv) { /* open the file */ image->err = load_image_by_path(image, software_path, gamedrv, open_plan[i], path); if (image->err && (image->err != IMAGE_ERROR_FILENOTFOUND)) goto done; /* move on to the next driver */ gamedrv = mess_next_compatible_driver(gamedrv); } /* move on to the next entry in the software path; if we can */ if (software_path) software_path += strlen(software_path) + 1; } while(!is_loaded(image) && software_path && *software_path); } /* did we fail to find the file? */ if (!is_loaded(image)) { image->err = IMAGE_ERROR_FILENOTFOUND; goto done; } /* if applicable, call device verify */ if (image->dev->imgverify && !image_has_been_created(image)) { /* access the memory */ buffer = image_ptr(image); if (!buffer) { image->err = IMAGE_ERROR_OUTOFMEMORY; goto done; } /* verify the file */ err = image->dev->imgverify(buffer, (size_t) image->length); if (err) { image->err = IMAGE_ERROR_INVALIDIMAGE; goto done; } } /* call device load or create */ if (image_has_been_created(image) && image->dev->create) { err = image->dev->create(image, create_format, create_args); if (err) { if (!image->err) image->err = IMAGE_ERROR_UNSPECIFIED; goto done; } } else if (image->dev->load) { /* using device load */ err = image->dev->load(image); if (err) { if (!image->err) image->err = IMAGE_ERROR_UNSPECIFIED; goto done; } } /* success! */ done: if (software_path_list) free(software_path_list); if (image->err) image_clear(image); image->is_loading = 1; return image->err ? INIT_FAIL : INIT_PASS; }
static void command_image_loadcreate(void) { mess_image *image; int device_type; int device_slot; const char *device_tag; int i, format_index = 0; const char *filename; const char *format; char buf[128]; const struct IODevice *dev; const char *file_extensions; char *filepath; int success; const game_driver *gamedrv; device_slot = current_command->u.image_args.device_slot; device_type = current_command->u.image_args.device_type; device_tag = current_command->u.image_args.device_tag; /* look up the image slot */ if (device_tag) image = image_from_devtag_and_index(device_tag, device_slot); else image = image_from_devtype_and_index(device_type, device_slot); if (!image) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Image slot '%s %i' does not exist", device_typename(device_type), device_slot); return; } dev = image_device(image); file_extensions = dev->file_extensions; /* is an image format specified? */ format = current_command->u.image_args.format; if (format) { if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format unless creating"); return; } if (!dev->createimage_options) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format for device"); return; } for (i = 0; dev->createimage_options[i].name; i++) { if (!strcmp(format, dev->createimage_options[i].name)) break; } if (!dev->createimage_options[i].name) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Unknown device '%s'", format); return; } format_index = i; file_extensions = dev->createimage_options[i].extensions; } /* figure out the filename */ filename = current_command->u.image_args.filename; if (!filename) { snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%s.%s", current_testcase.name, file_extensions); osd_get_temp_filename(buf, ARRAY_LENGTH(buf), buf); filename = buf; } success = FALSE; for (gamedrv = Machine->gamedrv; !success && gamedrv; gamedrv = mess_next_compatible_driver(gamedrv)) { /* assemble the full path */ filepath = assemble_software_path(gamedrv, filename); /* actually create or load the image */ switch(current_command->command_type) { case MESSTEST_COMMAND_IMAGE_CREATE: success = (image_create(image, filepath, format_index, NULL) == INIT_PASS); break; case MESSTEST_COMMAND_IMAGE_LOAD: success = (image_load(image, filepath) == INIT_PASS); break; default: fatalerror("Unexpected error"); break; } free(filepath); } if (!success) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to load/create image '%s': %s", filename, image_error(image)); return; } }
static mame_file *image_fopen_custom(mess_image *img, int filetype, int read_or_write) { const char *sysname; char *lpExt; const game_driver *gamedrv = Machine->gamedrv; assert(img); if (!img->name) return NULL; if (img->fp) { /* If already open, we won't open the file again until it is closed. */ return NULL; } do { sysname = gamedrv->name; logerror("image_fopen: trying %s for system %s\n", img->name, sysname); img->fp = mame_fopen(sysname, img->name, filetype, read_or_write); if (img->fp && (read_or_write == OSD_FOPEN_READ)) { lpExt = strrchr( img->name, '.' ); if (lpExt && (mame_stricmp( lpExt, ".ZIP" ) == 0)) { int pathindex; int pathcount = osd_get_path_count(filetype); zip_file *zipfile; zip_entry *zipentry; char *newname; char *name; char *zipname; const char *ext; const struct IODevice *dev; mame_fclose( img->fp ); img->fp = NULL; dev = image_device(img); assert(dev); newname = NULL; zipname = image_malloc( img, strlen( sysname ) + 1 + strlen( img->name ) + 1 ); if( osd_is_absolute_path( img->name ) ) { strcpy( zipname, img->name ); } else { strcpy( zipname, sysname ); strcat( zipname, osd_path_separator() ); strcat( zipname, img->name ); } for (pathindex = 0; pathindex < pathcount; pathindex++) { zipfile = openzip(filetype, pathindex, zipname); if (zipfile) { zipentry = readzip(zipfile); while( zipentry ) { /* mess doesn't support paths in zip files */ name = osd_basename( zipentry->name ); lpExt = strrchr(name, '.'); if (lpExt) { lpExt++; ext = dev->file_extensions; while(*ext) { if( mame_stricmp( lpExt, ext ) == 0 ) { if( newname ) { image_freeptr( img, newname ); } newname = image_malloc(img, strlen(img->name) + 1 + strlen(name) + 1); if (!newname) return NULL; strcpy(newname, img->name); strcat(newname, osd_path_separator()); strcat(newname, name); } ext += strlen(ext) + 1; } } zipentry = readzip(zipfile); } closezip(zipfile); } if( !newname ) { return NULL; } img->fp = mame_fopen(sysname, newname, filetype, read_or_write); if (img->fp) { image_freeptr(img, img->name); img->name = newname; break; } } image_freeptr( img, zipname ); } } gamedrv = mess_next_compatible_driver(gamedrv); } while(!img->fp && gamedrv); if (img->fp) { logerror("image_fopen: found image %s for system %s\n", img->name, sysname); img->length = mame_fsize(img->fp); img->hash = NULL; } return img->fp; }