diff options
Diffstat (limited to 'src/mess/tools/imgtool/imgtool.c')
-rw-r--r-- | src/mess/tools/imgtool/imgtool.c | 2814 |
1 files changed, 0 insertions, 2814 deletions
diff --git a/src/mess/tools/imgtool/imgtool.c b/src/mess/tools/imgtool/imgtool.c deleted file mode 100644 index df44a9bbff2..00000000000 --- a/src/mess/tools/imgtool/imgtool.c +++ /dev/null @@ -1,2814 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods -/*************************************************************************** - - imgtool.c - - Core code for Imgtool - -***************************************************************************/ - -#include <string.h> -#include <ctype.h> - -#include "imgtool.h" -#include "formats/imageutl.h" -#include "library.h" -#include "modules.h" -#include "pool.h" - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -struct imgtool_image -{ - const imgtool_module *module; - object_pool *pool; -}; - -struct imgtool_partition -{ - imgtool_image *image; - object_pool *pool; - int partition_index; - UINT64 base_block; - UINT64 block_count; - - imgtool_class imgclass; - size_t partition_extra_bytes; - size_t directory_extra_bytes; - - char path_separator; - char alternate_path_separator; - - unsigned int prefer_ucase : 1; - unsigned int supports_creation_time : 1; - unsigned int supports_lastmodified_time : 1; - unsigned int supports_bootblock : 1; /* this module supports loading/storing the boot block */ - - imgtoolerr_t (*begin_enum) (imgtool_directory *enumeration, const char *path); - imgtoolerr_t (*next_enum) (imgtool_directory *enumeration, imgtool_dirent *ent); - void (*close_enum) (imgtool_directory *enumeration); - imgtoolerr_t (*free_space) (imgtool_partition *partition, UINT64 *size); - imgtoolerr_t (*read_file) (imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf); - imgtoolerr_t (*write_file) (imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts); - imgtoolerr_t (*delete_file) (imgtool_partition *partition, const char *filename); - imgtoolerr_t (*list_forks) (imgtool_partition *partition, const char *path, imgtool_forkent *ents, size_t len); - imgtoolerr_t (*create_dir) (imgtool_partition *partition, const char *path); - imgtoolerr_t (*delete_dir) (imgtool_partition *partition, const char *path); - imgtoolerr_t (*list_attrs) (imgtool_partition *partition, const char *path, UINT32 *attrs, size_t len); - imgtoolerr_t (*get_attrs) (imgtool_partition *partition, const char *path, const UINT32 *attrs, imgtool_attribute *values); - imgtoolerr_t (*set_attrs) (imgtool_partition *partition, const char *path, const UINT32 *attrs, const imgtool_attribute *values); - imgtoolerr_t (*attr_name) (UINT32 attribute, const imgtool_attribute *attr, char *buffer, size_t buffer_len); - imgtoolerr_t (*get_iconinfo) (imgtool_partition *partition, const char *path, imgtool_iconinfo *iconinfo); - imgtoolerr_t (*suggest_transfer)(imgtool_partition *partition, const char *path, imgtool_transfer_suggestion *suggestions, size_t suggestions_length); - imgtoolerr_t (*get_chain) (imgtool_partition *partition, const char *path, imgtool_chainent *chain, size_t chain_size); - - const option_guide *writefile_optguide; - const char *writefile_optspec; -}; - -struct imgtool_directory -{ - imgtool_partition *partition; -}; - - - -/*************************************************************************** - GLOBALS -***************************************************************************/ - -static imgtool_library *global_imgtool_library; - -static int global_omit_untested; -static void (*global_warn)(const char *message); - - -void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...) -{ - va_list arg; - va_start(arg, format); - vprintf(format, arg); - va_end(arg); -} - -/*************************************************************************** - - Imgtool initialization and basics - -***************************************************************************/ -void rtrim(char *buf) -{ - size_t buflen; - char *s; - - buflen = strlen(buf); - if (buflen) - { - for (s = &buf[buflen-1]; s >= buf && (*s >= '\0') && isspace(*s); s--) - *s = '\0'; - } -} - -char *strncpyz(char *dest, const char *source, size_t len) -{ - char *s; - if (len) { - s = strncpy(dest, source, len - 1); - dest[len-1] = '\0'; - } - else { - s = dest; - } - return s; -} - -char *strncatz(char *dest, const char *source, size_t len) -{ - size_t l; - l = strlen(dest); - dest += l; - if (len > l) - len -= l; - else - len = 0; - return strncpyz(dest, source, len); -} - -/*------------------------------------------------- - markerrorsource - marks where an error source --------------------------------------------------*/ - -static imgtoolerr_t markerrorsource(imgtoolerr_t err) -{ - switch(err) - { - case IMGTOOLERR_OUTOFMEMORY: - case IMGTOOLERR_UNEXPECTED: - case IMGTOOLERR_BUFFERTOOSMALL: - /* Do nothing */ - break; - - case IMGTOOLERR_FILENOTFOUND: - case IMGTOOLERR_BADFILENAME: - err = (imgtoolerr_t)(err | IMGTOOLERR_SRC_FILEONIMAGE); - break; - - default: - err = (imgtoolerr_t)(err | IMGTOOLERR_SRC_IMAGEFILE); - break; - } - return err; -} - -char *imgtool_basename(char *filename) -{ - char *c; - - // NULL begets NULL - if (!filename) - return NULL; - - // start at the end and return when we hit a slash or colon - for (c = filename + strlen(filename) - 1; c >= filename; c--) - if (*c == '\\' || *c == '/' || *c == ':') - return c + 1; - - // otherwise, return the whole thing - return filename; -} - -/*------------------------------------------------- - internal_error - debug function for raising - internal errors --------------------------------------------------*/ - -static void internal_error(const imgtool_module *module, const char *message) -{ -#ifdef MAME_DEBUG - printf("%s: %s\n", module->name, message); -#endif -} - - -/*------------------------------------------------- - normalize_filename - convert a filename to the - native format used by the module --------------------------------------------------*/ - -static char *normalize_filename(imgtool_partition *partition, const char *src) -{ - imgtool_charset charset; - - /* get charset from module */ - charset = (imgtool_charset) (int) imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_CHARSET); - - /* and dupe it */ - return native_from_utf8(charset, src); -} - - - -/*------------------------------------------------- - imgtool_init - initializes the imgtool core --------------------------------------------------*/ - -void imgtool_init(int omit_untested, void (*warn)(const char *message)) -{ - imgtoolerr_t err; - err = imgtool_create_cannonical_library(omit_untested, &global_imgtool_library); - assert(err == IMGTOOLERR_SUCCESS); - if (err == IMGTOOLERR_SUCCESS) - { - imgtool_library_sort(global_imgtool_library, ITLS_DESCRIPTION); - } - global_omit_untested = omit_untested; - global_warn = warn; -} - - - -/*------------------------------------------------- - imgtool_exit - closes out the imgtool core --------------------------------------------------*/ - -void imgtool_exit(void) -{ - if (global_imgtool_library) - { - imgtool_library_close(global_imgtool_library); - global_imgtool_library = NULL; - } - global_warn = NULL; -} - - - -/*------------------------------------------------- - imgtool_find_module - looks up a module --------------------------------------------------*/ - -const imgtool_module *imgtool_find_module(const char *modulename) -{ - return imgtool_library_findmodule(global_imgtool_library, modulename); -} - - - -/*------------------------------------------------- - imgtool_get_module_features - retrieves a - structure identifying this module's features - associated with an image --------------------------------------------------*/ - -imgtool_module_features imgtool_get_module_features(const imgtool_module *module) -{ - imgtool_module_features features; - memset(&features, 0, sizeof(features)); - - if (module->create) - features.supports_create = 1; - if (module->open) - features.supports_open = 1; - if (module->read_sector) - features.supports_readsector = 1; - if (module->write_sector) - features.supports_writesector = 1; - return features; -} - - - -/*------------------------------------------------- - imgtool_warn - issues a warning --------------------------------------------------*/ - -void imgtool_warn(const char *format, ...) -{ - va_list va; - char buffer[2000]; - - if (global_warn) - { - va_start(va, format); - vsprintf(buffer, format, va); - va_end(va); - global_warn(buffer); - } -} - - - -/*------------------------------------------------- - evaluate_module - evaluates a single file to - determine what module can best handle a file --------------------------------------------------*/ - -static imgtoolerr_t evaluate_module(const char *fname, - const imgtool_module *module, float *result) -{ - imgtoolerr_t err; - imgtool_image *image = NULL; - imgtool_partition *partition = NULL; - imgtool_directory *imageenum = NULL; - imgtool_dirent ent; - float current_result; - - *result = 0.0; - - err = imgtool_image_open(module, fname, OSD_FOPEN_READ, &image); - if (err) - goto done; - - if (image) - { - current_result = module->open_is_strict ? 0.9 : 0.5; - - err = imgtool_partition_open(image, 0, &partition); - if (err) - goto done; - - err = imgtool_directory_open(partition, NULL, &imageenum); - if (err) - goto done; - - memset(&ent, 0, sizeof(ent)); - do - { - err = imgtool_directory_get_next(imageenum, &ent); - if (err) - goto done; - - if (ent.corrupt) - current_result = (current_result * 99 + 1.00f) / 100; - else - current_result = (current_result + 1.00f) / 2; - } - while(!ent.eof); - - *result = current_result; - } - -done: - if (ERRORCODE(err) == IMGTOOLERR_CORRUPTIMAGE) - err = IMGTOOLERR_SUCCESS; - if (imageenum) - imgtool_directory_close(imageenum); - if (partition) - imgtool_partition_close(partition); - if (image) - imgtool_image_close(image); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_image - retrieves the image - associated with this partition --------------------------------------------------*/ - -imgtool_image *imgtool_partition_image(imgtool_partition *partition) -{ - return partition->image; -} - - - -/*------------------------------------------------- - imgtool_identify_file - attempts to determine the module - for any given image --------------------------------------------------*/ - -imgtoolerr_t imgtool_identify_file(const char *fname, imgtool_module **modules, size_t count) -{ - imgtoolerr_t err = IMGTOOLERR_SUCCESS; - imgtool_library *library = global_imgtool_library; - imgtool_module *module = NULL; - imgtool_module *insert_module; - imgtool_module *temp_module; - size_t i = 0; - const char *extension; - float val, temp_val, *values = NULL; - - if (count <= 0) - { - err = IMGTOOLERR_UNEXPECTED; - goto done; - } - - for (i = 0; i < count; i++) - modules[i] = NULL; - if (count > 1) - count--; /* null terminate */ - - values = (float *) malloc(count * sizeof(*values)); - if (!values) - { - err = IMGTOOLERR_OUTOFMEMORY; - goto done; - } - for (i = 0; i < count; i++) - values[i] = 0.0; - - /* figure out the file extension, if any */ - extension = strrchr(fname, '.'); - if (extension) - extension++; - - /* iterate through all modules */ - while((module = imgtool_library_iterate(library, module)) != NULL) - { - if (!extension || image_find_extension(module->extensions, extension)) - { - err = evaluate_module(fname, module, &val); - if (err) - goto done; - - insert_module = module; - for (i = 0; (val > 0.0f) && (i < count); i++) - { - if (val > values[i]) - { - temp_val = values[i]; - temp_module = modules[i]; - values[i] = val; - modules[i] = insert_module; - val = temp_val; - insert_module = temp_module; - } - } - } - } - - if (!modules[0]) - err = (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE); - -done: - if (values) - free(values); - return err; -} - - - -/*------------------------------------------------- - imgtool_image_get_sector_size - gets the size - of a particular sector on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_get_sector_size(imgtool_image *image, UINT32 track, UINT32 head, - UINT32 sector, UINT32 *length) -{ - /* implemented? */ - if (!image->module->get_sector_size) - return (imgtoolerr_t )(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->get_sector_size(image, track, head, sector, length); -} - - - -/*------------------------------------------------- - imgtool_image_get_geometry - gets the geometry - of an image; note that this may disagree with - particular sectors; this is a common copy - protection scheme --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_get_geometry(imgtool_image *image, UINT32 *tracks, UINT32 *heads, UINT32 *sectors) -{ - UINT32 dummy; - - /* some sanitization, to make the callbacks easier to implement */ - if (!tracks) - tracks = &dummy; - if (!heads) - heads = &dummy; - if (!sectors) - sectors = &dummy; - *tracks = 0; - *heads = 0; - *sectors = 0; - - /* implemented? */ - if (!image->module->get_geometry) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->get_geometry(image, tracks, heads, sectors); -} - - - -/*------------------------------------------------- - imgtool_image_read_sector - reads a sector on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_read_sector(imgtool_image *image, UINT32 track, UINT32 head, - UINT32 sector, void *buffer, size_t len) -{ - /* implemented? */ - if (!image->module->read_sector) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->read_sector(image, track, head, sector, buffer, len); -} - - - -/*------------------------------------------------- - imgtool_image_write_sector - writes a sector on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_write_sector(imgtool_image *image, UINT32 track, UINT32 head, - UINT32 sector, const void *buffer, size_t len) -{ - /* implemented? */ - if (!image->module->write_sector) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->write_sector(image, track, head, sector, buffer, len); -} - - - -/*------------------------------------------------- - imgtool_image_get_block_size - gets the size of - a standard block on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_get_block_size(imgtool_image *image, UINT32 *length) -{ - /* implemented? */ - if (image->module->block_size == 0) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - *length = image->module->block_size; - return IMGTOOLERR_SUCCESS; -} - - - -/*------------------------------------------------- - imgtool_image_read_block - reads a standard - block on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_read_block(imgtool_image *image, UINT64 block, void *buffer) -{ - /* implemented? */ - if (!image->module->read_block) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->read_block(image, buffer, block); -} - - - -/*------------------------------------------------- - imgtool_image_write_block - writes a standard - block on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_write_block(imgtool_image *image, UINT64 block, const void *buffer) -{ - /* implemented? */ - if (!image->module->write_block) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - return image->module->write_block(image, buffer, block); -} - - - -/*------------------------------------------------- - imgtool_image_clear_block - clears a standard - block on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_clear_block(imgtool_image *image, UINT64 block, UINT8 data) -{ - imgtoolerr_t err; - UINT8 *block_data = NULL; - UINT32 length; - - err = imgtool_image_get_block_size(image, &length); - if (err) - goto done; - - block_data = (UINT8*)malloc(length); - if (!block_data) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - memset(block_data, data, length); - - err = imgtool_image_write_block(image, block, block_data); - if (err) - goto done; - -done: - if (block_data) - free(block_data); - return err; -} - - - -/*------------------------------------------------- - imgtool_image_list_partitions - lists the - partitions on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_list_partitions(imgtool_image *image, imgtool_partition_info *partitions, size_t len) -{ - /* implemented? */ - if (!image->module->list_partitions) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - memset(partitions, '\0', sizeof(*partitions) * len); - return image->module->list_partitions(image, partitions, len); -} - - - -/*------------------------------------------------- - imgtool_image_malloc - allocates memory associated with an - image --------------------------------------------------*/ - -void *imgtool_image_malloc(imgtool_image *image, size_t size) -{ - return pool_malloc_lib(image->pool, size); -} - - - -/*------------------------------------------------- - imgtool_image_module - returns the module associated with - this image --------------------------------------------------*/ - -const imgtool_module *imgtool_image_module(imgtool_image *img) -{ - return img->module; -} - - - -/*------------------------------------------------- - imgtool_image_extra_bytes - returns extra bytes on an image --------------------------------------------------*/ - -void *imgtool_image_extra_bytes(imgtool_image *image) -{ - void *ptr = NULL; - if (image->module->image_extra_bytes > 0) - ptr = ((UINT8 *) image) + sizeof(*image); - assert(ptr); - return ptr; -} - - - -/*------------------------------------------------- - imgtool_image_rand - returns a random number --------------------------------------------------*/ - -UINT64 imgtool_image_rand(imgtool_image *image) -{ - /* we can't use mame_rand() here */ -#ifdef rand -#undef rand -#endif - return ((UINT64) rand()) << 32 - | ((UINT64) rand()) << 0; -} - - - -/*************************************************************************** - - Imgtool partition management - -***************************************************************************/ - -static char *pool_strdup_allow_null(object_pool *pool, char *s) -{ - return s ? pool_strdup_lib(pool, s) : NULL; -} - - - -imgtoolerr_t imgtool_partition_open(imgtool_image *image, int partition_index, imgtool_partition **partition) -{ - imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS; - imgtool_partition *p = NULL; - imgtool_class imgclass; - imgtool_partition_info partition_info[32]; - UINT64 base_block, block_count; - size_t partition_extra_bytes; - object_pool *pool; - imgtoolerr_t (*open_partition)(imgtool_partition *partition, UINT64 first_block, UINT64 block_count); - - if (image->module->list_partitions) - { - /* this image supports partitions */ - if ((partition_index < 0) || (partition_index >= ARRAY_LENGTH(partition_info))) - return IMGTOOLERR_INVALIDPARTITION; - - /* retrieve the info on the partitions */ - memset(partition_info, '\0', sizeof(partition_info)); - err = image->module->list_partitions(image, partition_info, ARRAY_LENGTH(partition_info)); - if (err) - return err; - - /* is this a valid partition */ - if (!partition_info[partition_index].get_info) - return IMGTOOLERR_INVALIDPARTITION; - - /* use this partition */ - memset(&imgclass, 0, sizeof(imgclass)); - imgclass.get_info = partition_info[partition_index].get_info; - base_block = partition_info[partition_index].base_block; - block_count = partition_info[partition_index].block_count; - } - else - { - /* this image does not support partitions */ - if (partition_index != 0) - return IMGTOOLERR_INVALIDPARTITION; - - /* identify the image class */ - imgclass = imgtool_image_module(image)->imgclass; - base_block = 0; - block_count = ~0; - } - - /* does this partition type have extra bytes? */ - partition_extra_bytes = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_PARTITION_EXTRA_BYTES); - - /* allocate the new memory pool */ - pool = pool_alloc_lib(NULL); - if (!pool) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - - /* allocate the new partition object */ - p = (imgtool_partition *) pool_malloc_lib(pool, sizeof(*p) + partition_extra_bytes); - if (!p) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - memset(p, 0, sizeof(*p) + partition_extra_bytes); - p->pool = pool; - - /* fill out the structure */ - p->image = image; - p->partition_index = partition_index; - p->base_block = base_block; - p->block_count = block_count; - p->imgclass = imgclass; - p->partition_extra_bytes = partition_extra_bytes; - p->directory_extra_bytes = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES); - p->path_separator = (char) imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_PATH_SEPARATOR); - p->alternate_path_separator = (char) imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_ALTERNATE_PATH_SEPARATOR); - p->prefer_ucase = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_PREFER_UCASE) ? 1 : 0; - p->supports_creation_time = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_SUPPORTS_CREATION_TIME) ? 1 : 0; - p->supports_lastmodified_time = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_SUPPORTS_LASTMODIFIED_TIME) ? 1 : 0; - p->supports_bootblock = imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_SUPPORTS_BOOTBLOCK) ? 1 : 0; - p->begin_enum = (imgtoolerr_t (*)(imgtool_directory *, const char *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_BEGIN_ENUM); - p->next_enum = (imgtoolerr_t (*)(imgtool_directory *, imgtool_dirent *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_NEXT_ENUM); - p->free_space = (imgtoolerr_t (*)(imgtool_partition *, UINT64 *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_FREE_SPACE); - p->read_file = (imgtoolerr_t (*)(imgtool_partition *, const char *, const char *, imgtool_stream *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_READ_FILE); - p->write_file = (imgtoolerr_t (*)(imgtool_partition *, const char *, const char *, imgtool_stream *, option_resolution *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_WRITE_FILE); - p->delete_file = (imgtoolerr_t (*)(imgtool_partition *, const char *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_DELETE_FILE); - p->list_forks = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_forkent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_LIST_FORKS); - p->create_dir = (imgtoolerr_t (*)(imgtool_partition *, const char *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_CREATE_DIR); - p->delete_dir = (imgtoolerr_t (*)(imgtool_partition *, const char *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_DELETE_DIR); - p->list_attrs = (imgtoolerr_t (*)(imgtool_partition *, const char *, UINT32 *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_LIST_ATTRS); - p->get_attrs = (imgtoolerr_t (*)(imgtool_partition *, const char *, const UINT32 *, imgtool_attribute *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_ATTRS); - p->set_attrs = (imgtoolerr_t (*)(imgtool_partition *, const char *, const UINT32 *, const imgtool_attribute *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SET_ATTRS); - p->attr_name = (imgtoolerr_t (*)(UINT32, const imgtool_attribute *, char *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_ATTR_NAME); - p->get_iconinfo = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_iconinfo *)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_ICON_INFO); - p->suggest_transfer = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_transfer_suggestion *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_SUGGEST_TRANSFER); - p->get_chain = (imgtoolerr_t (*)(imgtool_partition *, const char *, imgtool_chainent *, size_t)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_GET_CHAIN); - p->writefile_optguide = (const option_guide *) imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE); - p->writefile_optspec = pool_strdup_allow_null(p->pool, (char*)imgtool_get_info_ptr(&imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC)); - - /* mask out if writing is untested */ - if (global_omit_untested && imgtool_get_info_int(&imgclass, IMGTOOLINFO_INT_WRITING_UNTESTED)) - { - p->write_file = NULL; - p->delete_file = NULL; - p->create_dir = NULL; - p->delete_dir = NULL; - p->writefile_optguide = NULL; - p->writefile_optspec = NULL; - } - - /* call the partition open function, if present */ - open_partition = (imgtoolerr_t (*)(imgtool_partition *, UINT64, UINT64)) imgtool_get_info_fct(&imgclass, IMGTOOLINFO_PTR_OPEN_PARTITION); - if (open_partition) - { - /* we have an open partition function */ - err = (*open_partition)(p, base_block, block_count); - if (err) - goto done; - } - -done: - *partition = err ? NULL : p; - return err; -} - - - -void imgtool_partition_close(imgtool_partition *partition) -{ - pool_free_lib(partition->pool); -} - - - -/*************************************************************************** - - Imgtool partition operations - -***************************************************************************/ - -/*------------------------------------------------- - imgtool_partition_get_attribute_name - retrieves the human readable - name for an attribute --------------------------------------------------*/ - -void imgtool_partition_get_attribute_name(imgtool_partition *partition, UINT32 attribute, const imgtool_attribute *attr_value, - char *buffer, size_t buffer_len) -{ - imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_UNIMPLEMENTED; - - buffer[0] = '\0'; - - if (attr_value) - { - if (partition->attr_name) - err = partition->attr_name(attribute, attr_value, buffer, buffer_len); - - if (err == (imgtoolerr_t)IMGTOOLERR_UNIMPLEMENTED) - { - switch(attribute & 0xF0000) - { - case IMGTOOLATTR_INT_FIRST: - snprintf(buffer, buffer_len, "%d", (int) attr_value->i); - break; - } - } - } - else - { - switch(attribute) - { - case IMGTOOLATTR_INT_MAC_TYPE: - snprintf(buffer, buffer_len, "File type"); - break; - case IMGTOOLATTR_INT_MAC_CREATOR: - snprintf(buffer, buffer_len, "File creator"); - break; - case IMGTOOLATTR_INT_MAC_FINDERFLAGS: - snprintf(buffer, buffer_len, "Finder flags"); - break; - case IMGTOOLATTR_INT_MAC_COORDX: - snprintf(buffer, buffer_len, "X coordinate"); - break; - case IMGTOOLATTR_INT_MAC_COORDY: - snprintf(buffer, buffer_len, "Y coordinate"); - break; - case IMGTOOLATTR_INT_MAC_FINDERFOLDER: - snprintf(buffer, buffer_len, "Finder folder"); - break; - case IMGTOOLATTR_INT_MAC_ICONID: - snprintf(buffer, buffer_len, "Icon ID"); - break; - case IMGTOOLATTR_INT_MAC_SCRIPTCODE: - snprintf(buffer, buffer_len, "Script code"); - break; - case IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS: - snprintf(buffer, buffer_len, "Extended flags"); - break; - case IMGTOOLATTR_INT_MAC_COMMENTID: - snprintf(buffer, buffer_len, "Comment ID"); - break; - case IMGTOOLATTR_INT_MAC_PUTAWAYDIRECTORY: - snprintf(buffer, buffer_len, "Putaway directory"); - break; - case IMGTOOLATTR_TIME_CREATED: - snprintf(buffer, buffer_len, "Creation time"); - break; - case IMGTOOLATTR_TIME_LASTMODIFIED: - snprintf(buffer, buffer_len, "Last modified time"); - break; - } - } -} - - - -/*------------------------------------------------- - imgtool_validitychecks - checks the validity - of the imgtool modules --------------------------------------------------*/ - -int imgtool_validitychecks(void) -{ - int error = 0; - int val; - imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS; - const imgtool_module *module = NULL; - const option_guide *guide_entry; - imgtool_module_features features; - int created_library = FALSE; - - if (!global_imgtool_library) - { - imgtool_init(FALSE, NULL); - created_library = TRUE; - } - - while((module = imgtool_library_iterate(global_imgtool_library, module)) != NULL) - { - features = imgtool_get_module_features(module); - - if (!module->name) - { - printf("imgtool module %s has null 'name'\n", module->name); - error = 1; - } - if (!module->description) - { - printf("imgtool module %s has null 'description'\n", module->name); - error = 1; - } - if (!module->extensions) - { - printf("imgtool module %s has null 'extensions'\n", module->extensions); - error = 1; - } - -#if 0 - /* sanity checks on modules that do not support directories */ - if (!module->path_separator) - { - if (module->alternate_path_separator) - { - printf("imgtool module %s specified alternate_path_separator but not path_separator\n", module->name); - error = 1; - } - if (module->initial_path_separator) - { - printf("imgtool module %s specified initial_path_separator without directory support\n", module->name); - error = 1; - } - if (module->create_dir) - { - printf("imgtool module %s implements create_dir without directory support\n", module->name); - error = 1; - } - if (module->delete_dir) - { - printf("imgtool module %s implements delete_dir without directory support\n", module->name); - error = 1; - } - } -#endif - - /* sanity checks on sector operations */ - if (module->read_sector && !module->get_sector_size) - { - printf("imgtool module %s implements read_sector without supporting get_sector_size\n", module->name); - error = 1; - } - if (module->write_sector && !module->get_sector_size) - { - printf("imgtool module %s implements write_sector without supporting get_sector_size\n", module->name); - error = 1; - } - - /* sanity checks on creation options */ - if (module->createimage_optguide || module->createimage_optspec) - { - if (!module->create) - { - printf("imgtool module %s has creation options without supporting create\n", module->name); - error = 1; - } - if ((!module->createimage_optguide && module->createimage_optspec) - || (module->createimage_optguide && !module->createimage_optspec)) - { - printf("imgtool module %s does has partially incomplete creation options\n", module->name); - error = 1; - } - - if (module->createimage_optguide && module->createimage_optspec) - { - guide_entry = module->createimage_optguide; - while(guide_entry->option_type != OPTIONTYPE_END) - { - if (option_resolution_contains(module->createimage_optspec, guide_entry->parameter)) - { - switch(guide_entry->option_type) - { - case OPTIONTYPE_INT: - case OPTIONTYPE_ENUM_BEGIN: - err = (imgtoolerr_t)option_resolution_getdefault(module->createimage_optspec, - guide_entry->parameter, &val); - if (err) - goto done; - break; - - default: - break; - } - if (!guide_entry->identifier) - { - printf("imgtool module %s creation option %d has null identifier\n", - module->name, (int) (guide_entry - module->createimage_optguide)); - error = 1; - } - if (!guide_entry->display_name) - { - printf("imgtool module %s creation option %d has null display_name\n", - module->name, (int) (guide_entry - module->createimage_optguide)); - error = 1; - } - } - guide_entry++; - } - } - } - } - -done: - if (created_library) - imgtool_exit(); - if (err) - { - printf("imgtool: %s\n", imgtool_error(err)); - error = 1; - } - return error; -} - - - -/*------------------------------------------------- - imgtool_temp_str - provides a temporary string - buffer used for string passing --------------------------------------------------*/ - -char *imgtool_temp_str(void) -{ - static int index; - static char temp_string_pool[32][256]; - return temp_string_pool[index++ % ARRAY_LENGTH(temp_string_pool)]; -} - - - -/*************************************************************************** - - Image handling functions - -***************************************************************************/ - -static imgtoolerr_t internal_open(const imgtool_module *module, const char *fname, - int read_or_write, option_resolution *createopts, imgtool_image **outimg) -{ - imgtoolerr_t err; - imgtool_stream *f = NULL; - imgtool_image *image = NULL; - object_pool *pool = NULL; - size_t size; - - if (outimg) - *outimg = NULL; - - /* is the requested functionality implemented? */ - if ((read_or_write == OSD_FOPEN_RW_CREATE) ? !module->create : !module->open) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - /* create a memory pool */ - pool = pool_alloc_lib(NULL); - if (!pool) - { - err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY); - goto done; - } - - /* open the stream */ - f = stream_open(fname, read_or_write); - if (!f) - { - err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE); - goto done; - } - - /* setup the image structure */ - size = sizeof(imgtool_image) + module->image_extra_bytes; - image = (imgtool_image *) pool_malloc_lib(pool, size); - if (!image) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - memset(image, '\0', size); - image->pool = pool; - image->module = module; - - /* actually call create or open */ - if (read_or_write == OSD_FOPEN_RW_CREATE) - err = module->create(image, f, createopts); - else - err = module->open(image, f); - if (err) - { - err = markerrorsource(err); - goto done; - } - -done: - if (err) - { - if (f) - stream_close(f); - if (pool) - pool_free_lib(pool); - image = NULL; - } - - if (outimg) - *outimg = image; - else if (image) - imgtool_image_close(image); - return err; -} - - - -/*------------------------------------------------- - imgtool_image_open - open an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_open(const imgtool_module *module, const char *fname, int read_or_write, imgtool_image **outimg) -{ - read_or_write = read_or_write ? OSD_FOPEN_RW : OSD_FOPEN_READ; - return internal_open(module, fname, read_or_write, NULL, outimg); -} - - - -/*------------------------------------------------- - imgtool_image_open_byname - open an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_open_byname(const char *modulename, const char *fname, int read_or_write, imgtool_image **outimg) -{ - const imgtool_module *module; - - module = imgtool_find_module(modulename); - if (!module) - return (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE); - - return imgtool_image_open(module, fname, read_or_write, outimg); -} - - - -/*------------------------------------------------- - imgtool_image_close - close an image --------------------------------------------------*/ - -void imgtool_image_close(imgtool_image *image) -{ - if (image->module->close) - image->module->close(image); - pool_free_lib(image->pool); -} - - - -/*------------------------------------------------- - imgtool_image_create - creates an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_create(const imgtool_module *module, const char *fname, - option_resolution *opts, imgtool_image **image) -{ - imgtoolerr_t err; - option_resolution *alloc_resolution = NULL; - - /* allocate dummy options if necessary */ - if (!opts && module->createimage_optguide) - { - alloc_resolution = option_resolution_create(module->createimage_optguide, module->createimage_optspec); - if (!alloc_resolution) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - opts = alloc_resolution; - } - if (opts) - option_resolution_finish(opts); - - err = internal_open(module, fname, OSD_FOPEN_RW_CREATE, opts, image); - if (err) - goto done; - -done: - if (alloc_resolution) - option_resolution_close(alloc_resolution); - return err; -} - - - -/*------------------------------------------------- - imgtool_image_create_byname - creates an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_create_byname(const char *modulename, const char *fname, - option_resolution *opts, imgtool_image **image) -{ - const imgtool_module *module; - - module = imgtool_find_module(modulename); - if (!module) - return (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE); - - return imgtool_image_create(module, fname, opts, image); -} - - - -/*------------------------------------------------- - imgtool_image_info - returns format specific information - about an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_image_info(imgtool_image *image, char *string, size_t len) -{ - if (len > 0) - { - string[0] = '\0'; - if (image->module->info) - image->module->info(image, string, len); - } - return IMGTOOLERR_SUCCESS; -} - - - -#define PATH_MUSTBEDIR 0x00000001 -#define PATH_LEAVENULLALONE 0x00000002 -#define PATH_CANBEBOOTBLOCK 0x00000004 - -/*------------------------------------------------- - cannonicalize_path - normalizes a path string - into a NUL delimited list --------------------------------------------------*/ - -static imgtoolerr_t cannonicalize_path(imgtool_partition *partition, UINT32 flags, - const char **path, char **alloc_path) -{ - imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS; - char *new_path = NULL; - char path_separator, alt_path_separator; - const char *s; - int in_path_separator, i, j; - - path_separator = partition->path_separator; - alt_path_separator = partition->alternate_path_separator; - - /* is this path NULL? if so, is that ignored? */ - if (!*path && (flags & PATH_LEAVENULLALONE)) - goto done; - - /* is this the special filename for bootblocks? */ - if (*path == FILENAME_BOOTBLOCK) - { - if (!(flags & PATH_CANBEBOOTBLOCK)) - err = (imgtoolerr_t)IMGTOOLERR_UNEXPECTED; - else if (!partition->supports_bootblock) - err = (imgtoolerr_t)IMGTOOLERR_FILENOTFOUND; - goto done; - } - - if (path_separator == '\0') - { - if (flags & PATH_MUSTBEDIR) - { - /* do we specify a path when paths are not supported? */ - if (*path && **path) - { - err = (imgtoolerr_t)(IMGTOOLERR_CANNOTUSEPATH | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - *path = NULL; /* normalize empty path */ - } - } - else - { - s = *path ? *path : ""; - - /* allocate space for a new cannonical path */ - new_path = (char*)malloc(strlen(s) + 4); - if (!new_path) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - - /* copy the path */ - in_path_separator = TRUE; - i = j = 0; - do - { - if ((s[i] != '\0') && (s[i] != path_separator) && (s[i] != alt_path_separator)) - { - new_path[j++] = s[i]; - in_path_separator = FALSE; - } - else if (!in_path_separator) - { - new_path[j++] = '\0'; - in_path_separator = TRUE; - } - } - while(s[i++] != '\0'); - new_path[j++] = '\0'; - new_path[j++] = '\0'; - *path = new_path; - } - -done: - *alloc_path = new_path; - return err; -} - - - -static imgtoolerr_t cannonicalize_fork(imgtool_partition *partition, const char **fork) -{ - /* does this module support forks? */ - if (partition->list_forks) - { - /* this module supports forks; make sure that fork is non-NULL */ - if (!*fork) - *fork = ""; - } - else - { - /* this module does not support forks; make sure that fork is NULL */ - if (*fork) - return IMGTOOLERR_NOFORKS; - } - return IMGTOOLERR_SUCCESS; -} - - - -/*------------------------------------------------- - imgtool_partition_get_directory_entry - retrieves - the nth directory entry within a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_directory_entry(imgtool_partition *partition, const char *path, int index, imgtool_dirent *ent) -{ - imgtoolerr_t err; - imgtool_directory *imgenum = NULL; - - if (index < 0) - { - err = (imgtoolerr_t)IMGTOOLERR_PARAMTOOSMALL; - goto done; - } - - err = imgtool_directory_open(partition, path, &imgenum); - if (err) - goto done; - - do - { - err = imgtool_directory_get_next(imgenum, ent); - if (err) - goto done; - - if (ent->eof) - { - err = (imgtoolerr_t)IMGTOOLERR_FILENOTFOUND; - goto done; - } - } - while(index--); - -done: - if (err) - memset(ent->filename, 0, sizeof(ent->filename)); - if (imgenum) - imgtool_directory_close(imgenum); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_file_size - returns free - space on a partition, in bytes --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_file_size(imgtool_partition *partition, const char *fname, UINT64 *filesize) -{ - imgtoolerr_t err; - imgtool_directory *imgenum; - imgtool_dirent ent; - const char *path; - - path = NULL; /* TODO: Need to parse off the path */ - - *filesize = -1; - memset(&ent, 0, sizeof(ent)); - - err = imgtool_directory_open(partition, path, &imgenum); - if (err) - goto done; - - do - { - err = imgtool_directory_get_next(imgenum, &ent); - if (err) - goto done; - - if (!core_stricmp(fname, ent.filename)) - { - *filesize = ent.filesize; - goto done; - } - } - while(ent.filename[0]); - - err = (imgtoolerr_t)IMGTOOLERR_FILENOTFOUND; - -done: - if (imgenum) - imgtool_directory_close(imgenum); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_list_file_attributes - identifies - all attributes on a file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_list_file_attributes(imgtool_partition *partition, const char *path, UINT32 *attrs, size_t len) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_fname = NULL; - - memset(attrs, 0, sizeof(*attrs) * len); - - if (!partition->list_attrs) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_fname = normalize_filename(partition, path); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_fname; - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_LEAVENULLALONE, &path, &alloc_path); - if (err) - goto done; - - err = partition->list_attrs(partition, path, attrs, len); - if (err) - goto done; - -done: - if (alloc_path != NULL) - free(alloc_path); - if (new_fname != NULL) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_file_attributes - retrieves - attributes on a file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_file_attributes(imgtool_partition *partition, const char *path, const UINT32 *attrs, imgtool_attribute *values) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_fname = NULL; - - if (!partition->get_attrs) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_fname = normalize_filename(partition, path); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_fname; - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_LEAVENULLALONE, &path, &alloc_path); - if (err) - goto done; - - err = partition->get_attrs(partition, path, attrs, values); - if (err) - goto done; - -done: - if (alloc_path != NULL) - free(alloc_path); - if (new_fname != NULL) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_put_file_attributes - sets - attributes on a file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_put_file_attributes(imgtool_partition *partition, const char *path, const UINT32 *attrs, const imgtool_attribute *values) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - - if (!partition->set_attrs) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_LEAVENULLALONE, &path, &alloc_path); - if (err) - goto done; - - err = partition->set_attrs(partition, path, attrs, values); - if (err) - goto done; - -done: - if (alloc_path) - free(alloc_path); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_file_attributes - retrieves - an attribute on a single file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_file_attribute(imgtool_partition *partition, const char *path, UINT32 attr, imgtool_attribute *value) -{ - UINT32 attrs[2]; - attrs[0] = attr; - attrs[1] = 0; - return imgtool_partition_get_file_attributes(partition, path, attrs, value); -} - - - -/*------------------------------------------------- - imgtool_partition_put_file_attribute - sets - attributes on a single file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_put_file_attribute(imgtool_partition *partition, const char *path, UINT32 attr, imgtool_attribute value) -{ - UINT32 attrs[2]; - attrs[0] = attr; - attrs[1] = 0; - return imgtool_partition_put_file_attributes(partition, path, attrs, &value); -} - - - -/*------------------------------------------------- - imgtool_partition_get_icon_info - retrieves the - icon for a file stored on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_icon_info(imgtool_partition *partition, const char *path, imgtool_iconinfo *iconinfo) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_fname = NULL; - - if (!partition->get_iconinfo) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_fname = normalize_filename(partition, path); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_fname; - - /* cannonicalize path */ - err = cannonicalize_path(partition, 0, &path, &alloc_path); - if (err) - goto done; - - memset(iconinfo, 0, sizeof(*iconinfo)); - err = partition->get_iconinfo(partition, path, iconinfo); - if (err) - goto done; - -done: - if (alloc_path) - free(alloc_path); - if (new_fname) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_suggest_file_filters - suggests - a list of filters appropriate for a file on a - partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_suggest_file_filters(imgtool_partition *partition, const char *path, - imgtool_stream *stream, imgtool_transfer_suggestion *suggestions, size_t suggestions_length) -{ - imgtoolerr_t err; - int i, j; - char *alloc_path = NULL; - imgtoolerr_t (*check_stream)(imgtool_stream *stream, imgtool_suggestion_viability_t *viability); - size_t position; - - /* clear out buffer */ - memset(suggestions, 0, sizeof(*suggestions) * suggestions_length); - - if (!partition->suggest_transfer) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_LEAVENULLALONE, &path, &alloc_path); - if (err) - goto done; - - /* invoke the module's suggest call */ - err = partition->suggest_transfer(partition, path, suggestions, suggestions_length); - if (err) - goto done; - - /* Loop on resulting suggestions, and do the following: - * 1. Call check_stream if present, and remove disqualified streams - * 2. Fill in missing descriptions - */ - i = j = 0; - while(suggestions[i].viability) - { - if (stream && suggestions[i].filter) - { - check_stream = (imgtoolerr_t (*)(imgtool_stream *, imgtool_suggestion_viability_t *)) filter_get_info_fct(suggestions[i].filter, FILTINFO_PTR_CHECKSTREAM); - if (check_stream) - { - position = stream_tell(stream); - err = check_stream(stream, &suggestions[i].viability); - stream_seek(stream, position, SEEK_SET); - if (err) - goto done; - } - } - - /* the check_stream proc can remove the option by clearing out the viability */ - if (suggestions[i].viability) - { - /* we may have to move this suggestion, if one was removed */ - if (i != j) - memcpy(&suggestions[j], &suggestions[i], sizeof(*suggestions)); - - /* if the description is missing, fill it in */ - if (!suggestions[j].description) - { - if (suggestions[j].filter) - suggestions[j].description = filter_get_info_string(suggestions[i].filter, FILTINFO_STR_HUMANNAME); - else - suggestions[j].description = "Raw"; - } - - j++; - } - i++; - } - suggestions[j].viability = (imgtool_suggestion_viability_t)0; - -done: - if (alloc_path) - free(alloc_path); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_chain - retrieves the block - chain for a file or directory on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_chain(imgtool_partition *partition, const char *path, imgtool_chainent *chain, size_t chain_size) -{ - size_t i; - - assert(chain_size > 0); - - if (!partition->get_chain) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - /* initialize the chain array, so the module's get_chain function can be lazy */ - for (i = 0; i < chain_size; i++) - { - chain[i].level = 0; - chain[i].block = ~0; - } - - return partition->get_chain(partition, path, chain, chain_size - 1); -} - - - -/*------------------------------------------------- - imgtool_partition_get_chain_string - retrieves - the block chain for a file or directory on a - partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_chain_string(imgtool_partition *partition, const char *path, char *buffer, size_t buffer_len) -{ - imgtoolerr_t err; - imgtool_chainent chain[512]; - UINT64 last_block; - UINT8 cur_level = 0; - int len, i; - int comma_needed = FALSE; - - /* determine the last block identifier */ - chain[0].block = ~0; - last_block = chain[0].block; - - err = imgtool_partition_get_chain(partition, path, chain, ARRAY_LENGTH(chain)); - if (err) - return err; - - len = snprintf(buffer, buffer_len, "["); - buffer += len; - buffer_len -= len; - - for (i = 0; chain[i].block != last_block; i++) - { - while(cur_level < chain[i].level) - { - len = snprintf(buffer, buffer_len, " ["); - buffer += len; - buffer_len -= len; - cur_level++; - comma_needed = FALSE; - } - while(cur_level > chain[i].level) - { - len = snprintf(buffer, buffer_len, "]"); - buffer += len; - buffer_len -= len; - cur_level--; - } - - if (comma_needed) - { - len = snprintf(buffer, buffer_len, ", "); - buffer += len; - buffer_len -= len; - } - - len = snprintf(buffer, buffer_len, "%u", (unsigned) chain[i].block); - buffer += len; - buffer_len -= len; - comma_needed = TRUE; - } - - do - { - len = snprintf(buffer, buffer_len, "]"); - buffer += len; - buffer_len -= len; - } - while(cur_level-- > 0); - - return IMGTOOLERR_SUCCESS; -} - - - -/*------------------------------------------------- - imgtool_partition_get_free_space - returns the - amount of free space on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_free_space(imgtool_partition *partition, UINT64 *sz) -{ - imgtoolerr_t err; - UINT64 size; - - if (!partition->free_space) - return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - - err = partition->free_space(partition, &size); - if (err) - return (imgtoolerr_t)(err | IMGTOOLERR_SRC_IMAGEFILE); - - if (sz) - *sz = size; - return IMGTOOLERR_SUCCESS; -} - - - -/*------------------------------------------------- - imgtool_partition_read_file - starts reading - from a file on a partition with a stream --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_read_file(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf, filter_getinfoproc filter) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - union filterinfo u; - - if (!partition->read_file) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - if (filter) - { - /* use a filter */ - filter(FILTINFO_PTR_READFILE, &u); - if (!u.read_file) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - err = u.read_file(partition, filename, fork, destf); - if (err) - { - err = markerrorsource(err); - goto done; - } - } - else - { - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_CANBEBOOTBLOCK, &filename, &alloc_path); - if (err) - goto done; - - err = cannonicalize_fork(partition, &fork); - if (err) - goto done; - - /* invoke the actual module */ - err = partition->read_file(partition, filename, fork, destf); - if (err) - { - err = markerrorsource(err); - goto done; - } - } - -done: - if (alloc_path) - free(alloc_path); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_write_file - starts writing - to a new file on an image with a stream --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_write_file(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts, filter_getinfoproc filter) -{ - imgtoolerr_t err; - char *buf = NULL; - char *s; - option_resolution *alloc_resolution = NULL; - char *alloc_path = NULL; - UINT64 free_space; - UINT64 file_size; - union filterinfo u; - - if (!partition->write_file) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - if (filter) - { - /* use a filter */ - filter(FILTINFO_PTR_WRITEFILE, &u); - if (!u.write_file) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - err = u.write_file(partition, filename, fork, sourcef, opts); - if (err) - { - err = markerrorsource(err); - goto done; - } - } - else - { - /* does this partition prefer upper case file names? */ - if (partition->prefer_ucase) - { - buf = (char*)malloc(strlen(filename) + 1); - if (!buf) - { - err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY); - goto done; - } - strcpy(buf, filename); - for (s = buf; *s; s++) - *s = toupper(*s); - filename = buf; - } - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_CANBEBOOTBLOCK, &filename, &alloc_path); - if (err) - goto done; - - err = cannonicalize_fork(partition, &fork); - if (err) - goto done; - - /* allocate dummy options if necessary */ - if (!opts && partition->writefile_optguide) - { - alloc_resolution = option_resolution_create(partition->writefile_optguide, partition->writefile_optspec); - if (!alloc_resolution) - { - err = IMGTOOLERR_OUTOFMEMORY; - goto done; - } - opts = alloc_resolution; - } - if (opts) - option_resolution_finish(opts); - - /* if free_space is implemented; do a quick check to see if space is available */ - if (partition->free_space) - { - err = partition->free_space(partition, &free_space); - if (err) - { - err = markerrorsource(err); - goto done; - } - - file_size = stream_size(sourcef); - - if (file_size > free_space) - { - err = markerrorsource(IMGTOOLERR_NOSPACE); - goto done; - } - } - - /* actually invoke the write file handler */ - err = partition->write_file(partition, filename, fork, sourcef, opts); - if (err) - { - err = markerrorsource(err); - goto done; - } - } - -done: - if (buf) - free(buf); - if (alloc_path) - free(alloc_path); - if (alloc_resolution) - option_resolution_close(alloc_resolution); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_file - read a file from - an image, storing it into a native file --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_file(imgtool_partition *partition, const char *filename, const char *fork, - const char *dest, filter_getinfoproc filter) -{ - imgtoolerr_t err; - imgtool_stream *f; - char *new_fname = NULL; - char *alloc_dest = NULL; - const char *filter_extension = NULL; - - if (!dest) - { - /* determine the filter extension, if appropriate */ - if (filter != NULL) - filter_extension = filter_get_info_string(filter, FILTINFO_STR_EXTENSION); - - if (filter_extension != NULL) - { - alloc_dest = (char*)malloc(strlen(filename) + 1 + strlen(filter_extension) + 1); - if (!alloc_dest) - return IMGTOOLERR_OUTOFMEMORY; - - sprintf(alloc_dest, "%s.%s", filename, filter_extension); - dest = alloc_dest; - } - else - { - if (filename == FILENAME_BOOTBLOCK) - dest = "boot.bin"; - else - dest = filename; - } - } - - f = stream_open(dest, OSD_FOPEN_WRITE); - if (!f) - { - err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE); - goto done; - } - - new_fname = normalize_filename(partition, filename); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - err = imgtool_partition_read_file(partition, new_fname, fork, f, filter); - if (err) - goto done; - -done: - if (f != NULL) - stream_close(f); - if (alloc_dest != NULL) - free(alloc_dest); - if (new_fname != NULL) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_put_file - read a native file - and store it on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_put_file(imgtool_partition *partition, const char *newfname, const char *fork, - const char *source, option_resolution *opts, filter_getinfoproc filter) -{ - imgtoolerr_t err; - imgtool_stream *f = NULL; - imgtool_charset charset; - char *alloc_newfname = NULL; - - if (!newfname) - newfname = (const char *) imgtool_basename((char *) source); - - charset = (imgtool_charset) (int) imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_CHARSET); - if (charset != IMGTOOL_CHARSET_UTF8) - { - /* convert to native format */ - alloc_newfname = native_from_utf8(charset, newfname); - if (alloc_newfname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_NATIVEFILE); - goto done; - } - - newfname = alloc_newfname; - } - - f = stream_open(source, OSD_FOPEN_READ); - if (f) - err = imgtool_partition_write_file(partition, newfname, fork, f, opts, filter); - else - err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE); - -done: - /* clean up */ - if (f != NULL) - stream_close(f); - if (alloc_newfname != NULL) - osd_free(alloc_newfname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_delete_file - delete a file - on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_delete_file(imgtool_partition *partition, const char *fname) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_fname = NULL; - - if (!partition->delete_file) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_fname = normalize_filename(partition, fname); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - fname = new_fname; - - /* cannonicalize path */ - err = cannonicalize_path(partition, 0, &fname, &alloc_path); - if (err) - goto done; - - err = partition->delete_file(partition, fname); - if (err) - { - err = markerrorsource(err); - goto done; - } - -done: - if (alloc_path) - free(alloc_path); - if (new_fname) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_list_file_forks - lists all - forks on an image --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_list_file_forks(imgtool_partition *partition, const char *path, imgtool_forkent *ents, size_t len) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_fname = NULL; - - if (!partition->list_forks) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_fname = normalize_filename(partition, path); - if (new_fname == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_fname; - - /* cannonicalize path */ - err = cannonicalize_path(partition, 0, &path, &alloc_path); - if (err) - goto done; - - err = partition->list_forks(partition, path, ents, len); - if (err) - goto done; - -done: - if (alloc_path) - free(alloc_path); - if (new_fname) - osd_free(new_fname); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_create_directory - creates a - directory on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_create_directory(imgtool_partition *partition, const char *path) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_path = NULL; - - /* implemented? */ - if (!partition->create_dir) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_path = normalize_filename(partition, path); - if (new_path == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_path; - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_MUSTBEDIR, &path, &alloc_path); - if (err) - goto done; - - err = partition->create_dir(partition, path); - if (err) - goto done; - -done: - if (alloc_path) - free(alloc_path); - if (new_path) - osd_free(new_path); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_delete_directory - deletes a - directory on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_delete_directory(imgtool_partition *partition, const char *path) -{ - imgtoolerr_t err; - char *alloc_path = NULL; - char *new_path = NULL; - - /* implemented? */ - if (!partition->delete_dir) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_path = normalize_filename(partition, path); - if (new_path == NULL) - { - err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - path = new_path; - - /* cannonicalize path */ - err = cannonicalize_path(partition, PATH_MUSTBEDIR, &path, &alloc_path); - if (err) - goto done; - - err = partition->delete_dir(partition, path); - if (err) - goto done; - -done: - if (alloc_path) - free(alloc_path); - if (new_path) - osd_free(new_path); - return err; -} - - - -/*------------------------------------------------- - imgtool_partition_get_block_size - gets the - size of a standard block on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_get_block_size(imgtool_partition *partition, UINT32 *length) -{ - return imgtool_image_get_block_size(partition->image, length); -} - - - -/*------------------------------------------------- - imgtool_partition_read_block - reads a standard - block on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_read_block(imgtool_partition *partition, UINT64 block, void *buffer) -{ - if (block >= partition->block_count) - return IMGTOOLERR_SEEKERROR; - return imgtool_image_read_block(partition->image, block + partition->base_block, buffer); -} - - - -/*------------------------------------------------- - imgtool_partition_write_block - writes a - standard block on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_partition_write_block(imgtool_partition *partition, UINT64 block, const void *buffer) -{ - if (block >= partition->block_count) - return IMGTOOLERR_SEEKERROR; - return imgtool_image_write_block(partition->image, block + partition->base_block, buffer); -} - - - -/*------------------------------------------------- - imgtool_partition_get_features - retrieves a - structure identifying this partition's features - associated with an image --------------------------------------------------*/ - -imgtool_partition_features imgtool_partition_get_features(imgtool_partition *partition) -{ - imgtool_partition_features features; - memset(&features, 0, sizeof(features)); - - if (partition->read_file) - features.supports_reading = 1; - if (partition->write_file) - features.supports_writing = 1; - if (partition->delete_file) - features.supports_deletefile = 1; - if (partition->path_separator) - features.supports_directories = 1; - if (partition->free_space) - features.supports_freespace = 1; - if (partition->create_dir) - features.supports_createdir = 1; - if (partition->delete_dir) - features.supports_deletedir = 1; - if (partition->supports_creation_time) - features.supports_creation_time = 1; - if (partition->supports_lastmodified_time) - features.supports_lastmodified_time = 1; - if (!features.supports_writing && !features.supports_createdir && !features.supports_deletefile && !features.supports_deletedir) - features.is_read_only = 1; - return features; -} - - - -/*------------------------------------------------- - imgtool_partition_get_info_ptr - retrieves a - pointer associated with a partition's format --------------------------------------------------*/ - -void *imgtool_partition_get_info_ptr(imgtool_partition *partition, UINT32 state) -{ - return imgtool_get_info_ptr(&partition->imgclass, state); -} - - - -/*------------------------------------------------- - imgtool_partition_get_info_string - retrieves a - string associated with a partition's format --------------------------------------------------*/ - -const char *imgtool_partition_get_info_string(imgtool_partition *partition, UINT32 state) -{ - return imgtool_get_info_string(&partition->imgclass, state); -} - - - -/*------------------------------------------------- - imgtool_partition_get_info_int - retrieves a - pointer associated with a partition's format --------------------------------------------------*/ - -UINT64 imgtool_partition_get_info_int(imgtool_partition *partition, UINT32 state) -{ - return imgtool_get_info_int(&partition->imgclass, state); -} - - - -/*------------------------------------------------- - imgtool_partition_extra_bytes - returns extra - bytes on a partition --------------------------------------------------*/ - -void *imgtool_partition_extra_bytes(imgtool_partition *partition) -{ - void *ptr = NULL; - if (partition->partition_extra_bytes > 0) - ptr = ((UINT8 *) partition) + sizeof(*partition); - assert(ptr); - return ptr; -} - - - -/*------------------------------------------------- - imgtool_partition_rand - returns random number --------------------------------------------------*/ - -UINT64 imgtool_partition_rand(imgtool_partition *partition) -{ - return imgtool_image_rand(partition->image); -} - - - -/*************************************************************************** - - Path handling functions - -***************************************************************************/ - -/*------------------------------------------------- - imgtool_partition_get_root_path - retrieves - the path root of this partition --------------------------------------------------*/ - -const char *imgtool_partition_get_root_path(imgtool_partition *partition) -{ - int initial_path_separator; - char path_separator; - char *buf; - int pos = 0; - - initial_path_separator = imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_INITIAL_PATH_SEPARATOR) ? 1 : 0; - path_separator = (char) imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_PATH_SEPARATOR); - buf = imgtool_temp_str(); - - if (initial_path_separator) - buf[pos++] = path_separator; - buf[pos] = '\0'; - return buf; -} - - - -/*------------------------------------------------- - imgtool_partition_path_concatenate - retrieves - a pointer associated with a partition's format --------------------------------------------------*/ - -const char *imgtool_partition_path_concatenate(imgtool_partition *partition, const char *path1, const char *path2) -{ - char path_separator; - size_t len; - char *buffer; - size_t buffer_len; - - path_separator = (char) imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_PATH_SEPARATOR); - len = strlen(path1); - - /* prepare buffer */ - buffer = imgtool_temp_str(); - buffer_len = 256; - - if (!strcmp(path2, ".")) - { - /* keep the same directory */ - snprintf(buffer, buffer_len, "%s", path1); - } - else if (!strcmp(path2, "..")) - { - /* up one directory */ - while((len > 0) && (path1[len - 1] == path_separator)) - len--; - while((len > 0) && (path1[len - 1] != path_separator)) - len--; - while((len > 1) && (path1[len - 1] == path_separator)) - len--; - snprintf(buffer, buffer_len, "%s", path1); - buffer[len] = '\0'; - } - else - { - /* append a path */ - if ((*path1 != 0) && (path1[strlen(path1) - 1] != path_separator)) - snprintf(buffer, buffer_len, "%s%c%s", path1, path_separator, path2); - else - snprintf(buffer, buffer_len, "%s%s", path1, path2); - } - return buffer; -} - - - -/*------------------------------------------------- - imgtool_partition_get_base_name - retrieves - a base name for a partition specific path --------------------------------------------------*/ - -const char *imgtool_partition_get_base_name(imgtool_partition *partition, const char *path) -{ - char path_separator; - const char *new_path = path; - int i; - - path_separator = (char) imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_PATH_SEPARATOR); - - for (i = 0; path[i]; i++) - { - if (path[i] == path_separator) - new_path = &path[i + 1]; - } - return new_path; -} - - - -/*************************************************************************** - - Directory handling functions - -***************************************************************************/ - -/*------------------------------------------------- - imgtool_directory_open - begins - enumerating files on a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_directory_open(imgtool_partition *partition, const char *path, imgtool_directory **outenum) -{ - imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS; - imgtool_directory *enumeration = NULL; - char *alloc_path = NULL; - char *new_path = NULL; - size_t size; - - /* sanity checks */ - assert(partition); - assert(outenum); - - *outenum = NULL; - - if (!partition->next_enum) - { - err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY); - goto done; - } - - new_path = normalize_filename(partition, path); - path = new_path; - - err = cannonicalize_path(partition, PATH_MUSTBEDIR, &path, &alloc_path); - if (err) - goto done; - - size = sizeof(imgtool_directory) + partition->directory_extra_bytes; - enumeration = (imgtool_directory *) malloc(size); - if (!enumeration) - { - err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY; - goto done; - } - memset(enumeration, '\0', size); - enumeration->partition = partition; - - if (partition->begin_enum) - { - err = partition->begin_enum(enumeration, path); - if (err) - { - err = markerrorsource(err); - goto done; - } - } - -done: - if (alloc_path != NULL) - free(alloc_path); - if (new_path != NULL) - osd_free(new_path); - if (err && (enumeration != NULL)) - { - free(enumeration); - enumeration = NULL; - } - *outenum = enumeration; - return err; -} - - - -/*------------------------------------------------- - imgtool_directory_close - closes a directory --------------------------------------------------*/ - -void imgtool_directory_close(imgtool_directory *directory) -{ - imgtool_partition *partition; - partition = imgtool_directory_partition(directory); - if (partition->close_enum) - partition->close_enum(directory); - free(directory); -} - - - -/*------------------------------------------------- - imgtool_directory_get_next - continues - enumerating files within a partition --------------------------------------------------*/ - -imgtoolerr_t imgtool_directory_get_next(imgtool_directory *directory, imgtool_dirent *ent) -{ - imgtoolerr_t err; - imgtool_partition *partition; - int charset; - - partition = imgtool_directory_partition(directory); - - /* This makes it so that drivers don't have to take care of clearing - * the attributes if they don't apply - */ - memset(ent, 0, sizeof(*ent)); - - err = partition->next_enum(directory, ent); - if (err) - return markerrorsource(err); - - charset = imgtool_partition_get_info_int(partition, IMGTOOLINFO_INT_CHARSET); - - if (charset) - { - char *new_fname = utf8_from_native((imgtool_charset)charset, ent->filename); - - if (!new_fname) - return IMGTOOLERR_BADFILENAME; - - strcpy(ent->filename, new_fname); - osd_free(new_fname); - } - - /* don't trust the module! */ - if (!partition->supports_creation_time && (ent->creation_time != 0)) - { - internal_error(NULL, "next_enum() specified creation_time, which is marked as unsupported by this module"); - return IMGTOOLERR_UNEXPECTED; - } - if (!partition->supports_lastmodified_time && (ent->lastmodified_time != 0)) - { - internal_error(NULL, "next_enum() specified lastmodified_time, which is marked as unsupported by this module"); - return IMGTOOLERR_UNEXPECTED; - } - if (!partition->path_separator && ent->directory) - { - internal_error(NULL, "next_enum() returned a directory, which is marked as unsupported by this module"); - return IMGTOOLERR_UNEXPECTED; - } - return IMGTOOLERR_SUCCESS; -} - - - -/*------------------------------------------------- - imgtool_directory_module - returns the module associated - with this directory --------------------------------------------------*/ - -const imgtool_module *imgtool_directory_module(imgtool_directory *directory) -{ - return directory->partition->image->module; -} - - - -/*------------------------------------------------- - imgtool_directory_extrabytes - returns extra - bytes on a directory --------------------------------------------------*/ - -void *imgtool_directory_extrabytes(imgtool_directory *directory) -{ - assert(directory->partition->directory_extra_bytes > 0); - return ((UINT8 *) directory) + sizeof(*directory); -} - - - -/*------------------------------------------------- - imgtool_directory_partition - returns the - partition associated with this directory --------------------------------------------------*/ - -imgtool_partition *imgtool_directory_partition(imgtool_directory *directory) -{ - return directory->partition; -} - - - -/*------------------------------------------------- - imgtool_directory_image - returns the image - associated with this directory --------------------------------------------------*/ - -imgtool_image *imgtool_directory_image(imgtool_directory *directory) -{ - return directory->partition->image; -} - - - -/*------------------------------------------------- - unknown_partition_get_info - represents an - unknown partition --------------------------------------------------*/ - -void unknown_partition_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinfo *info) -{ - switch(state) - { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case IMGTOOLINFO_STR_NAME: strcpy(info->s = imgtool_temp_str(), "unknown"); break; - case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "Unknown partition type"); break; - } -} |