diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/bus/a7800/a78_slot.cpp | 9 | ||||
-rw-r--r-- | src/devices/bus/a7800/a78_slot.h | 5 | ||||
-rw-r--r-- | src/devices/bus/nes/nes_slot.cpp | 14 | ||||
-rw-r--r-- | src/devices/bus/nes/nes_slot.h | 4 | ||||
-rw-r--r-- | src/emu/diimage.cpp | 118 | ||||
-rw-r--r-- | src/emu/diimage.h | 10 |
6 files changed, 62 insertions, 98 deletions
diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp index 78749155cbb..e33048ec40c 100644 --- a/src/devices/bus/a7800/a78_slot.cpp +++ b/src/devices/bus/a7800/a78_slot.cpp @@ -468,15 +468,6 @@ image_init_result a78_cart_slot_device::call_load() } -void a78_partialhash(util::hash_collection &dest, const unsigned char *data, - unsigned long length, const char *functions) -{ - if (length <= 128) - return; - dest.compute(&data[128], length - 128, functions); -} - - /*------------------------------------------------- call_unload -------------------------------------------------*/ diff --git a/src/devices/bus/a7800/a78_slot.h b/src/devices/bus/a7800/a78_slot.h index e498f416e54..7a5e6b26260 100644 --- a/src/devices/bus/a7800/a78_slot.h +++ b/src/devices/bus/a7800/a78_slot.h @@ -81,9 +81,6 @@ protected: }; -void a78_partialhash(util::hash_collection &dest, const unsigned char *data, unsigned long length, const char *functions); - - // ======================> a78_cart_slot_device class a78_cart_slot_device : public device_t, @@ -114,7 +111,7 @@ public: virtual bool is_reset_on_load() const override { return 1; } virtual const char *image_interface() const override { return "a7800_cart"; } virtual const char *file_extensions() const override { return "bin,a78"; } - virtual device_image_partialhash_func get_partial_hash() const override { return &a78_partialhash; } + virtual u32 unhashed_header_length() const override { return 128; } // slot interface overrides virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp index b8f99355faa..2676ad357a7 100644 --- a/src/devices/bus/nes/nes_slot.cpp +++ b/src/devices/bus/nes/nes_slot.cpp @@ -1015,17 +1015,3 @@ WRITE8_MEMBER(nes_cart_slot_device::write_ex) m_cart->set_open_bus(((offset + 0x4020) & 0xff00) >> 8); } } - - -//------------------------------------------------- -// partial hash function to be used by -// device_image_partialhash_func -//------------------------------------------------- - -void nes_partialhash(util::hash_collection &dest, const unsigned char *data, - unsigned long length, const char *functions) -{ - if (length <= 16) - return; - dest.compute(&data[16], length - 16, functions); -} diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index 82876ce15a5..088c402803c 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -331,8 +331,6 @@ protected: std::vector<uint16_t> m_prg_bank_map; }; -void nes_partialhash(util::hash_collection &dest, const unsigned char *data, unsigned long length, const char *functions); - // ======================> nes_cart_slot_device class nes_cart_slot_device : public device_t, @@ -364,7 +362,7 @@ public: virtual bool is_reset_on_load() const override { return 1; } virtual const char *image_interface() const override { return "nes_cart"; } virtual const char *file_extensions() const override { return "nes,unf,unif"; } - virtual device_image_partialhash_func get_partial_hash() const override { return &nes_partialhash; } + virtual u32 unhashed_header_length() const override { return 16; } // slot interface overrides virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index 28dad1f82ee..64b09a101f2 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -175,23 +175,6 @@ iodevice_t device_image_interface::device_typeid(const char *name) return (iodevice_t)-1; } -/*------------------------------------------------- - device_compute_hash - compute a hash, - using this device's partial hash if appropriate --------------------------------------------------*/ - -void device_image_interface::device_compute_hash(util::hash_collection &hashes, const void *data, size_t length, const char *types) const -{ - /* retrieve the partial hash func */ - device_image_partialhash_func partialhash = get_partial_hash(); - - /* compute the hash */ - if (partialhash) - partialhash(hashes, (const unsigned char*)data, length, types); - else - hashes.compute(reinterpret_cast<const u8 *>(data), length, types); -} - //------------------------------------------------- // set_image_filename - specifies the filename of // an image @@ -513,37 +496,46 @@ bool device_image_interface::load_software_region(const char *tag, optional_shar // to be loaded // **************************************************************************** -void device_image_interface::run_hash(util::core_file &file, void (*partialhash)(util::hash_collection &, const unsigned char *, unsigned long, const char *), - util::hash_collection &hashes, const char *types) +bool device_image_interface::run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types) { - u32 size; - std::vector<u8> buf; - + // reset the hash; we want to override existing data hashes.reset(); - size = (u32) file.size(); - buf.resize(size); - memset(&buf[0], 0, size); + // figure out the size, and "cap" the skip bytes + u64 size = file.size(); + skip_bytes = (u32) std::min((u64) skip_bytes, size); - // read the file - file.seek(0, SEEK_SET); - file.read(&buf[0], size); + // seek to the beginning + file.seek(skip_bytes, SEEK_SET); + u64 position = skip_bytes; - if (partialhash) - partialhash(hashes, &buf[0], size, types); - else - hashes.compute(&buf[0], size, types); + // keep on reading hashes + hashes.begin(types); + while (position < size) + { + uint8_t buffer[8192]; + + // read bytes + const u32 count = (u32) std::min(size - position, (u64) sizeof(buffer)); + const u32 actual_count = file.read(buffer, count); + if (actual_count == 0) + return false; + position += actual_count; + + // and compute the hashes + hashes.buffer(buffer, actual_count); + } + hashes.end(); // cleanup file.seek(0, SEEK_SET); + return true; } -void device_image_interface::image_checkhash() +bool device_image_interface::image_checkhash() { - device_image_partialhash_func partialhash; - // only calculate CRC if it hasn't been calculated, and the open_mode is read only u32 crcval; if (!m_hash.crc(crcval) && is_readonly() && !m_created) @@ -551,29 +543,26 @@ void device_image_interface::image_checkhash() // do not cause a linear read of 600 megs please // TODO: use SHA1 in the CHD header as the hash if (image_type() == IO_CDROM) - return; + return true; // Skip calculating the hash when we have an image mounted through a software list if (loaded_through_softlist()) - return; - - // retrieve the partial hash func - partialhash = get_partial_hash(); + return true; - run_hash(*m_file, partialhash, m_hash, util::hash_collection::HASH_TYPES_ALL); + // run the hash + if (!run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL)) + return false; } - return; + return true; } util::hash_collection device_image_interface::calculate_hash_on_file(util::core_file &file) const { - // retrieve the partial hash func - device_image_partialhash_func partialhash = get_partial_hash(); - - // and calculate the hash + // calculate the hash util::hash_collection hash; - run_hash(file, partialhash, hash, util::hash_collection::HASH_TYPES_ALL); + if (!run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL)) + hash.reset(); return hash; } @@ -1150,25 +1139,32 @@ image_init_result device_image_interface::finish_load() if (m_is_loading) { - image_checkhash(); + if (!image_checkhash()) + { + m_err = IMAGE_ERROR_INVALIDIMAGE; + err = image_init_result::FAIL; + } - if (m_created) + if (err == image_init_result::PASS) { - err = call_create(m_create_format, m_create_args); - if (err != image_init_result::PASS) + if (m_created) { - if (!m_err) - m_err = IMAGE_ERROR_UNSPECIFIED; + err = call_create(m_create_format, m_create_args); + if (err != image_init_result::PASS) + { + if (!m_err) + m_err = IMAGE_ERROR_UNSPECIFIED; + } } - } - else - { - // using device load - err = call_load(); - if (err != image_init_result::PASS) + else { - if (!m_err) - m_err = IMAGE_ERROR_UNSPECIFIED; + // using device load + err = call_load(); + if (err != image_init_result::PASS) + { + if (!m_err) + m_err = IMAGE_ERROR_UNSPECIFIED; + } } } } diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 1f716075451..19b7b18292b 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -97,8 +97,6 @@ enum class image_verify_result { PASS, FAIL }; // device image interface function types typedef delegate<image_init_result (device_image_interface &)> device_image_load_delegate; typedef delegate<void (device_image_interface &)> device_image_func_delegate; -// legacy -typedef void (*device_image_partialhash_func)(util::hash_collection &, const unsigned char *, unsigned long, const char *); //************************************************************************** // MACROS @@ -136,13 +134,11 @@ public: static const char *device_brieftypename(iodevice_t type); static iodevice_t device_typeid(const char *name); - virtual void device_compute_hash(util::hash_collection &hashes, const void *data, size_t length, const char *types) const; - virtual image_init_result call_load() { return image_init_result::PASS; } virtual image_init_result call_create(int format_type, util::option_resolution *format_options) { return image_init_result::PASS; } virtual void call_unload() { } virtual std::string call_display() { return std::string(); } - virtual device_image_partialhash_func get_partial_hash() const { return nullptr; } + virtual u32 unhashed_header_length() const { return 0; } virtual bool core_opens_image_file() const { return true; } virtual iodevice_t image_type() const = 0; virtual bool is_readable() const = 0; @@ -267,7 +263,7 @@ protected: void make_readonly() { m_readonly = true; } - void image_checkhash(); + bool image_checkhash(); const software_part *find_software_item(const std::string &identifier, bool restrict_to_interface, software_list_device **device = nullptr) const; std::string software_get_default_slot(const char *default_card_slot) const; @@ -305,7 +301,7 @@ private: bool load_software_part(const std::string &identifier); bool init_phase() const; - static void run_hash(util::core_file &file, void(*partialhash)(util::hash_collection &, const unsigned char *, unsigned long, const char *), util::hash_collection &hashes, const char *types); + static bool run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types); // loads an image or software items and resets - called internally when we // load an is_reset_on_load() item |