mirror of
https://github.com/holub/mame
synced 2025-06-04 20:06:28 +03:00
270 lines
12 KiB
C++
270 lines
12 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Nathan Woods
|
|
/***************************************************************************
|
|
|
|
imgtool.h
|
|
|
|
Main headers for Imgtool core
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef IMGTOOL_H
|
|
#define IMGTOOL_H
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <functional>
|
|
|
|
#include "corestr.h"
|
|
#include "formats/flopimg.h"
|
|
#include "opresolv.h"
|
|
#include "library.h"
|
|
#include "filter.h"
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
#define EOLN_CR "\x0d"
|
|
#define EOLN_LF "\x0a"
|
|
#define EOLN_CRLF "\x0d\x0a"
|
|
|
|
#define FILENAME_BOOTBLOCK ((const char *) 1)
|
|
|
|
enum
|
|
{
|
|
OSD_FOPEN_READ,
|
|
OSD_FOPEN_WRITE,
|
|
OSD_FOPEN_RW,
|
|
OSD_FOPEN_RW_CREATE
|
|
};
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
* Image calls
|
|
*
|
|
* These are the calls that front ends should use for manipulating images. You
|
|
* should never call the module functions directly because they may not be
|
|
* implemented (i.e. - the function pointers are NULL). The img_* functions are
|
|
* aware of these issues and will make the appropriate checks as well as
|
|
* marking up return codes with the source. In addition, some of the img_*
|
|
* calls are high level calls that simply image manipulation
|
|
*
|
|
* Calls that return 'int' that are not explicitly noted otherwise return
|
|
* imgtool error codes
|
|
* ---------------------------------------------------------------------------
|
|
*/
|
|
|
|
struct imgtool_module_features
|
|
{
|
|
unsigned int supports_create : 1;
|
|
unsigned int supports_open : 1;
|
|
unsigned int supports_readsector : 1;
|
|
unsigned int supports_writesector : 1;
|
|
unsigned int is_read_only : 1;
|
|
};
|
|
|
|
struct imgtool_partition_features
|
|
{
|
|
unsigned int supports_reading : 1;
|
|
unsigned int supports_writing : 1;
|
|
unsigned int supports_deletefile : 1;
|
|
unsigned int supports_directories : 1;
|
|
unsigned int supports_freespace : 1;
|
|
unsigned int supports_createdir : 1;
|
|
unsigned int supports_deletedir : 1;
|
|
unsigned int supports_creation_time : 1;
|
|
unsigned int supports_lastmodified_time : 1;
|
|
unsigned int supports_forks : 1;
|
|
unsigned int supports_geticoninfo : 1;
|
|
unsigned int is_read_only : 1;
|
|
};
|
|
|
|
/* ----- initialization and basics ----- */
|
|
void imgtool_init(bool omit_untested, void (*warning)(const char *message));
|
|
void imgtool_exit(void);
|
|
const imgtool_module *imgtool_find_module(const std::string &modulename);
|
|
const imgtool::library::modulelist &imgtool_get_modules();
|
|
imgtool_module_features imgtool_get_module_features(const imgtool_module *module);
|
|
void imgtool_warn(const char *format, ...) ATTR_PRINTF(1,2);
|
|
|
|
// ----- image management -----
|
|
namespace imgtool
|
|
{
|
|
class image
|
|
{
|
|
public:
|
|
typedef std::unique_ptr<image> ptr;
|
|
|
|
image(const imgtool_module &module, object_pool *pool, void *extra_bytes);
|
|
~image();
|
|
|
|
static imgtoolerr_t identify_file(const char *filename, imgtool_module **modules, size_t count);
|
|
static imgtoolerr_t open(const imgtool_module *module, const std::string &filename, int read_or_write, ptr &outimg);
|
|
static imgtoolerr_t open(const std::string &modulename, const std::string &filename, int read_or_write, ptr &outimg);
|
|
static imgtoolerr_t create(const imgtool_module *module, const std::string &filename, util::option_resolution *opts, ptr &image);
|
|
static imgtoolerr_t create(const std::string &modulename, const std::string &filename, util::option_resolution *opts, ptr &image);
|
|
static imgtoolerr_t create(const imgtool_module *module, const std::string &filename, util::option_resolution *opts);
|
|
static imgtoolerr_t create(const std::string &modulename, const std::string &filename, util::option_resolution *opts);
|
|
|
|
std::string info();
|
|
imgtoolerr_t get_geometry(uint32_t *tracks, uint32_t *heads, uint32_t *sectors);
|
|
imgtoolerr_t read_sector(uint32_t track, uint32_t head, uint32_t sector, std::vector<uint8_t> &buffer);
|
|
imgtoolerr_t write_sector(uint32_t track, uint32_t head, uint32_t sector, const void *buffer, size_t len);
|
|
imgtoolerr_t get_block_size(uint32_t &length);
|
|
imgtoolerr_t read_block(uint64_t block, void *buffer);
|
|
imgtoolerr_t write_block(uint64_t block, const void *buffer);
|
|
imgtoolerr_t clear_block(uint64_t block, uint8_t data);
|
|
imgtoolerr_t list_partitions(std::vector<imgtool::partition_info> &partitions);
|
|
void *malloc(size_t size);
|
|
const imgtool_module &module() { return m_module; }
|
|
void *extra_bytes() { return m_extra_bytes; }
|
|
|
|
private:
|
|
const imgtool_module &m_module;
|
|
object_pool *m_pool;
|
|
void *m_extra_bytes;
|
|
|
|
// because of an idiosyncrasy of how imgtool::image::internal_open() works, we are only "okay to close"
|
|
// by invoking the module's close function once internal_open() succeeds. the long term solution is
|
|
// better C++ adoption (e.g. - std::unique_ptr<>, std:move() etc)
|
|
bool m_okay_to_close;
|
|
|
|
static imgtoolerr_t internal_open(const imgtool_module *module, const std::string &filename,
|
|
int read_or_write, util::option_resolution *createopts, imgtool::image::ptr &outimg);
|
|
};
|
|
}
|
|
|
|
namespace imgtool
|
|
{
|
|
// ----- partition management -----
|
|
class partition
|
|
{
|
|
friend class directory;
|
|
public:
|
|
typedef std::unique_ptr<partition> ptr;
|
|
|
|
// ctor/dtor
|
|
partition(imgtool::image &image, const imgtool_class &imgclass, int partition_index, uint64_t base_block, uint64_t block_count);
|
|
~partition();
|
|
|
|
static imgtoolerr_t open(imgtool::image &image, int partition_index, ptr &partition);
|
|
imgtool::image &image() { return m_image; }
|
|
|
|
// ----- partition operations -----
|
|
imgtoolerr_t get_directory_entry(const char *path, int index, imgtool_dirent &ent);
|
|
imgtoolerr_t get_file_size(const char *filename, uint64_t &filesize);
|
|
imgtoolerr_t get_free_space(uint64_t &sz);
|
|
imgtoolerr_t read_file(const char *filename, const char *fork, imgtool::stream &destf, filter_getinfoproc filter);
|
|
imgtoolerr_t write_file(const char *filename, const char *fork, imgtool::stream &sourcef, util::option_resolution *resolution, filter_getinfoproc filter);
|
|
imgtoolerr_t get_file(const char *filename, const char *fork, const char *dest, filter_getinfoproc filter);
|
|
imgtoolerr_t put_file(const char *newfname, const char *fork, const char *source, util::option_resolution *opts, filter_getinfoproc filter);
|
|
imgtoolerr_t delete_file(const char *fname);
|
|
imgtoolerr_t list_file_forks(const char *path, std::vector<imgtool::fork_entry> &forks);
|
|
imgtoolerr_t create_directory(const char *path);
|
|
imgtoolerr_t delete_directory(const char *path);
|
|
imgtoolerr_t list_file_attributes(const char *path, uint32_t *attrs, size_t len);
|
|
imgtoolerr_t get_file_attributes(const char *path, const uint32_t *attrs, imgtool_attribute *values);
|
|
imgtoolerr_t put_file_attributes(const char *path, const uint32_t *attrs, const imgtool_attribute *values);
|
|
imgtoolerr_t get_file_attribute(const char *path, uint32_t attr, imgtool_attribute &value);
|
|
imgtoolerr_t put_file_attribute(const char *path, uint32_t attr, const imgtool_attribute &value);
|
|
void get_attribute_name(uint32_t attribute, const imgtool_attribute *attr_value, char *buffer, size_t buffer_len);
|
|
imgtoolerr_t get_icon_info(const char *path, imgtool_iconinfo *iconinfo);
|
|
imgtoolerr_t suggest_file_filters(const char *path, imgtool::stream *stream, imgtool_transfer_suggestion *suggestions, size_t suggestions_length);
|
|
imgtoolerr_t get_block_size(uint32_t &length);
|
|
imgtoolerr_t read_block(uint64_t block, void *buffer);
|
|
imgtoolerr_t write_block(uint64_t block, const void *buffer);
|
|
imgtoolerr_t get_chain(const char *path, imgtool_chainent *chain, size_t chain_size);
|
|
imgtoolerr_t get_chain_string(const char *path, char *buffer, size_t buffer_len);
|
|
imgtool_partition_features get_features() const;
|
|
void * get_info_ptr(uint32_t state);
|
|
const char * get_info_string(uint32_t state);
|
|
uint64_t get_info_int(uint32_t state);
|
|
void * extra_bytes();
|
|
|
|
// ----- path management -----
|
|
const char * get_root_path();
|
|
const char * path_concatenate(const char *path1, const char *path2);
|
|
const char * get_base_name(const char *path);
|
|
|
|
private:
|
|
imgtool::image &m_image;
|
|
//int m_partition_index;
|
|
uint64_t m_base_block;
|
|
uint64_t m_block_count;
|
|
|
|
imgtool_class m_imgclass;
|
|
size_t m_directory_extra_bytes;
|
|
|
|
char m_path_separator;
|
|
char m_alternate_path_separator;
|
|
|
|
unsigned int m_prefer_ucase : 1;
|
|
unsigned int m_supports_creation_time : 1;
|
|
unsigned int m_supports_lastmodified_time : 1;
|
|
unsigned int m_supports_bootblock : 1; /* this module supports loading/storing the boot block */
|
|
|
|
std::function<imgtoolerr_t(imgtool::directory &enumeration, const char *path)> m_begin_enum;
|
|
std::function<imgtoolerr_t(imgtool::directory &enumeration, imgtool_dirent &ent)> m_next_enum;
|
|
std::function<void(imgtool::directory &enumeration)> m_close_enum;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, uint64_t *size)> m_free_space;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *filename, const char *fork, imgtool::stream &destf)> m_read_file;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *filename, const char *fork, imgtool::stream &sourcef, util::option_resolution *opts)> m_write_file;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *filename)> m_delete_file;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, std::vector<imgtool::fork_entry> &forks)> m_list_forks;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path)> m_create_dir;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path)> m_delete_dir;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, uint32_t *attrs, size_t len)> m_list_attrs;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, const uint32_t *attrs, imgtool_attribute *values)> m_get_attrs;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, const uint32_t *attrs, const imgtool_attribute *values)> m_set_attrs;
|
|
std::function<imgtoolerr_t(uint32_t attribute, const imgtool_attribute *attr, char *buffer, size_t buffer_len)> m_attr_name;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, imgtool_iconinfo *iconinfo)> m_get_iconinfo;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)> m_suggest_transfer;
|
|
std::function<imgtoolerr_t(imgtool::partition &partition, const char *path, imgtool_chainent *chain, size_t chain_size)> m_get_chain;
|
|
|
|
const util::option_guide *m_writefile_optguide;
|
|
std::string m_writefile_optspec;
|
|
|
|
std::unique_ptr<uint8_t[]> m_extra_bytes;
|
|
|
|
// methods
|
|
imgtoolerr_t cannonicalize_path(uint32_t flags, const char *path, std::string &result);
|
|
imgtoolerr_t cannonicalize_fork(const char **fork);
|
|
imgtoolerr_t map_block_to_image_block(uint64_t partition_block, uint64_t &image_block) const;
|
|
};
|
|
|
|
// ----- directory management -----
|
|
class directory
|
|
{
|
|
public:
|
|
typedef std::unique_ptr<directory> ptr;
|
|
|
|
// ctor/dtor
|
|
directory(imgtool::partition &partition);
|
|
~directory();
|
|
|
|
// methods
|
|
static imgtoolerr_t open(imgtool::partition &partition, const std::string &path, ptr &outenum);
|
|
imgtoolerr_t get_next(imgtool_dirent &ent);
|
|
|
|
// accessors
|
|
imgtool::partition &partition() { return m_partition; }
|
|
imgtool::image &image() { return partition().image(); }
|
|
const imgtool_module &module() { return partition().image().module(); }
|
|
void *extra_bytes() { assert(m_extra_bytes); return m_extra_bytes.get(); }
|
|
|
|
private:
|
|
imgtool::partition &m_partition;
|
|
std::unique_ptr<uint8_t[]> m_extra_bytes;
|
|
bool m_okay_to_close; // similar wart as what is on imgtool::image
|
|
};
|
|
};
|
|
|
|
/* ----- special ----- */
|
|
bool imgtool_validitychecks(void);
|
|
void unknown_partition_get_info(const imgtool_class *imgclass, uint32_t state, union imgtoolinfo *info);
|
|
|
|
char *strncpyz(char *dest, const char *source, size_t len);
|
|
void rtrim(char *buf);
|
|
std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length);
|
|
|
|
#endif /* IMGTOOL_H */
|