예제 #1
0
파일: audit.cs 프로젝트: kwanboy/mcs
        //-------------------------------------------------
        //  audit_one_disk - validate a single disk entry
        //-------------------------------------------------
        audit_record audit_one_disk(ListPointer <rom_entry> rom, string locationtag = null)  //const rom_entry *rom
        {
            // allocate and append a new record
            audit_record record = m_record_list.emplace_back(new audit_record(rom, audit_record.media_type.MEDIA_DISK)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), *rom, media_type::DISK);

            // open the disk
            chd_file  source = new chd_file();
            chd_error err    = (chd_error)romload_global.open_disk_image(m_enumerator.options(), m_enumerator.driver(), rom[0], source, locationtag);

            // if we succeeded, get the hashes
            if (err == chd_error.CHDERR_NONE)
            {
                util.hash_collection hashes = new util.hash_collection();

                // if there's a SHA1 hash, add them to the output hash
                if (source.sha1() != null)
                {
                    hashes.add_sha1(source.sha1());
                }

                // update the actual values
                record.set_actual(hashes);
            }

            // compute the final status
            compute_status(record, rom[0], err == chd_error.CHDERR_NONE);
            return(record);
        }
예제 #2
0
파일: audit.cs 프로젝트: kwanboy/mcs
        //-------------------------------------------------
        //  compute_status - compute a detailed status
        //  based on the information we have
        //-------------------------------------------------
        void compute_status(audit_record record, rom_entry rom, bool found)
        {
            // if not found, provide more details
            if (!found)
            {
                // no good dump
                if (record.expected_hashes().flag(util.hash_collection.FLAG_NO_DUMP))
                {
                    record.set_status(audit_record.audit_status.STATUS_NOT_FOUND, audit_record.audit_substatus.SUBSTATUS_NOT_FOUND_NODUMP);
                }

                // optional ROM
                else if (romload_global.ROM_ISOPTIONAL(rom))
                {
                    record.set_status(audit_record.audit_status.STATUS_NOT_FOUND, audit_record.audit_substatus.SUBSTATUS_NOT_FOUND_OPTIONAL);
                }

                // just plain old not found
                else
                {
                    record.set_status(audit_record.audit_status.STATUS_NOT_FOUND, audit_record.audit_substatus.SUBSTATUS_NOT_FOUND);
                }
            }

            // if found, provide more details
            else
            {
                // length mismatch
                if (record.expected_length() != record.actual_length())
                {
                    record.set_status(audit_record.audit_status.STATUS_FOUND_INVALID, audit_record.audit_substatus.SUBSTATUS_FOUND_WRONG_LENGTH);
                }

                // found but needs a dump
                else if (record.expected_hashes().flag(util.hash_collection.FLAG_NO_DUMP))
                {
                    record.set_status(audit_record.audit_status.STATUS_GOOD, audit_record.audit_substatus.SUBSTATUS_FOUND_NODUMP);
                }

                // incorrect hash
                else if (record.expected_hashes() != record.actual_hashes())
                {
                    record.set_status(audit_record.audit_status.STATUS_FOUND_INVALID, audit_record.audit_substatus.SUBSTATUS_FOUND_BAD_CHECKSUM);
                }

                // correct hash but needs a redump
                else if (record.expected_hashes().flag(util.hash_collection.FLAG_BAD_DUMP))
                {
                    record.set_status(audit_record.audit_status.STATUS_GOOD, audit_record.audit_substatus.SUBSTATUS_GOOD_NEEDS_REDUMP);
                }

                // just plain old good
                else
                {
                    record.set_status(audit_record.audit_status.STATUS_GOOD, audit_record.audit_substatus.SUBSTATUS_GOOD);
                }
            }
        }
예제 #3
0
파일: audit.cs 프로젝트: kwanboy/mcs
        //-------------------------------------------------
        //  audit_device - audit the device
        //-------------------------------------------------
        public summary audit_device(device_t device, string validation = AUDIT_VALIDATE_FULL)
        {
            // start fresh
            m_record_list.clear();

            // store validation for later
            m_validation = validation;
            m_searchpath = device.shortname();

            int found    = 0;
            int required = 0;

            // now iterate over regions and ROMs within
            for (ListPointer <rom_entry> region = romload_global.rom_first_region(device); region != null; region = romload_global.rom_next_region(region))
            {
                for (ListPointer <rom_entry> rom = romload_global.rom_first_file(region); rom != null; rom = romload_global.rom_next_file(rom))
                {
                    util.hash_collection hashes = new util.hash_collection(romload_global.ROM_GETHASHDATA(rom[0]));

                    // count the number of files with hashes
                    if (!hashes.flag(util.hash_collection.FLAG_NO_DUMP) && !romload_global.ROM_ISOPTIONAL(rom[0]))
                    {
                        required++;
                    }

                    // audit a file
                    audit_record record = null;
                    if (romload_global.ROMREGION_ISROMDATA(region[0]))
                    {
                        record = audit_one_rom(rom);
                    }
                    // audit a disk
                    else if (romload_global.ROMREGION_ISDISKDATA(region[0]))
                    {
                        record = audit_one_disk(rom);
                    }

                    // count the number of files that are found.
                    if (record != null && (record.status() == audit_record.audit_status.STATUS_GOOD || record.status() == audit_record.audit_status.STATUS_FOUND_INVALID))
                    {
                        found++;
                    }
                }
            }

            if (found == 0 && required > 0)
            {
                m_record_list.clear();
                return(summary.NOTFOUND);
            }

            // return a summary
            string unused = "";

            return(summarize(device.shortname(), ref unused));
        }
예제 #4
0
        //-------------------------------------------------
        //  audit_one_disk - validate a single disk entry
        //-------------------------------------------------
        audit_record audit_one_disk(Pointer <rom_entry> rom, object args)  //template <typename... T> audit_record &audit_one_disk(const rom_entry *rom, T &&... args);
        {
            // allocate and append a new record
            audit_record record = m_record_list.emplace_back(new audit_record(rom, media_type.DISK)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), *rom, media_type::DISK);

            // open the disk
            chd_file source = new chd_file();

            throw new emu_unimplemented();
#if false
#endif
        }
예제 #5
0
파일: audit.cs 프로젝트: kwanboy/mcs
        // internal helpers

        //-------------------------------------------------
        //  audit_one_rom - validate a single ROM entry
        //-------------------------------------------------
        audit_record audit_one_rom(ListPointer <rom_entry> rom)  //(const rom_entry *rom)
        {
            // allocate and append a new record
            audit_record record = m_record_list.emplace_back(new audit_record(rom, audit_record.media_type.MEDIA_ROM)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), *rom, media_type::ROM);

            // see if we have a CRC and extract it if so
            UInt32 crc;
            bool   has_crc = record.expected_hashes().crc(out crc);

            // find the file and checksum it, getting the file length along the way
            emu_file file = new emu_file(m_enumerator.options().media_path(), osdcore_global.OPEN_FLAG_READ | osdcore_global.OPEN_FLAG_NO_PRELOAD);

            file.set_restrict_to_mediapath(true);
            path_iterator path = new path_iterator(m_searchpath);
            string        curpath;

            while (path.next(out curpath, record.name()))
            {
                // open the file if we can
                osd_file.error filerr;
                if (has_crc)
                {
                    filerr = file.open(curpath, crc);
                }
                else
                {
                    filerr = file.open(curpath);
                }

                // if it worked, get the actual length and hashes, then stop
                if (filerr == osd_file.error.NONE)
                {
                    record.set_actual(file.hashes(m_validation), file.size());
                    break;
                }
            }

            file.close();

            // compute the final status
            compute_status(record, rom[0], record.actual_length() != 0);
            return(record);
        }
예제 #6
0
        //-------------------------------------------------
        //  audit_one_rom - validate a single ROM entry
        //-------------------------------------------------
        audit_record audit_one_rom(std.vector <string> searchpath, Pointer <rom_entry> rom)  //audit_record &audit_one_rom(const std::vector<std::string> &searchpath, const rom_entry *rom);
        {
            // allocate and append a new record
            audit_record record = m_record_list.emplace_back(new audit_record(rom, media_type.ROM)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), *rom, media_type::ROM);

            // see if we have a CRC and extract it if so
            uint32_t crc;
            bool     has_crc = record.expected_hashes().crc(out crc);

            // find the file and checksum it, getting the file length along the way
            emu_file file = new emu_file(m_enumerator.options().media_path(), searchpath, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD);

            file.set_restrict_to_mediapath(1);

            // open the file if we can
            std.error_condition filerr;
            if (has_crc)
            {
                filerr = file.open(record.name(), crc);
            }
            else
            {
                filerr = file.open(record.name());
            }

            // if it worked, get the actual length and hashes, then stop
            if (!filerr)
            {
                record.set_actual(file.hashes(m_validation), file.size());
            }

            file.close();

            // compute the final status
            compute_status(record, rom.op, record.actual_length() != 0);
            return(record);
        }
예제 #7
0
파일: audit.cs 프로젝트: kwanboy/mcs
        //-------------------------------------------------
        //  audit_samples - validate the samples for the
        //  currently-enumerated driver
        //-------------------------------------------------
        public summary audit_samples()
        {
            // start fresh
            m_record_list.clear();

            int required = 0;
            int found    = 0;

            // iterate over sample entries
            foreach (samples_device device in new samples_device_iterator(m_enumerator.config().root_device()))
            {
                // by default we just search using the driver name
                string searchpath = m_enumerator.driver().name;

                // add the alternate path if present
                samples_iterator samplesiter = new samples_iterator(device);
                if (samplesiter.altbasename() != null)
                {
                    searchpath += ";" + samplesiter.altbasename();
                }

                // iterate over samples in this entry
                for (string samplename = samplesiter.first(); samplename != null; samplename = samplesiter.next())
                {
                    required++;

                    // create a new record
                    audit_record record = m_record_list.emplace_back(new audit_record(samplename, audit_record.media_type.MEDIA_SAMPLE)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), samplename, media_type::SAMPLE);

                    // look for the files
                    emu_file      file = new emu_file(m_enumerator.options().sample_path(), osdcore_global.OPEN_FLAG_READ | osdcore_global.OPEN_FLAG_NO_PRELOAD);
                    path_iterator path = new path_iterator(searchpath);
                    string        curpath;
                    while (path.next(out curpath, samplename))
                    {
                        // attempt to access the file (.flac) or (.wav)
                        osd_file.error filerr = file.open(curpath, ".flac");
                        if (filerr != osd_file.error.NONE)
                        {
                            filerr = file.open(curpath, ".wav");
                        }

                        if (filerr == osd_file.error.NONE)
                        {
                            record.set_status(audit_record.audit_status.STATUS_GOOD, audit_record.audit_substatus.SUBSTATUS_GOOD);
                            found++;
                        }
                        else
                        {
                            record.set_status(audit_record.audit_status.STATUS_NOT_FOUND, audit_record.audit_substatus.SUBSTATUS_NOT_FOUND);
                        }
                    }

                    file.close();
                }
            }

            if (found == 0 && required > 0)
            {
                m_record_list.clear();
                return(summary.NOTFOUND);
            }

            // return a summary
            string unused = "";

            return(summarize(m_enumerator.driver().name, ref unused));
        }
예제 #8
0
파일: audit.cs 프로젝트: kwanboy/mcs
        // getters
        //const simple_list<audit_record> &records() const { return m_record_list; }


        // audit operations

        //-------------------------------------------------
        //  audit_media - audit the media described by the
        //  currently-enumerated driver
        //-------------------------------------------------
        public summary audit_media(string validation = AUDIT_VALIDATE_FULL)
        {
            // start fresh
            m_record_list.clear();

            // store validation for later
            m_validation = validation;

// temporary hack until romload is update: get the driver path and support it for
// all searches
            string driverpath = m_enumerator.config().root_device().searchpath();

            int found           = 0;
            int required        = 0;
            int shared_found    = 0;
            int shared_required = 0;

            // iterate over devices and regions
            foreach (device_t device in new device_iterator(m_enumerator.config().root_device()))
            {
                // determine the search path for this source and iterate through the regions
                m_searchpath = device.searchpath();

                // now iterate over regions and ROMs within
                for (ListPointer <rom_entry> region = romload_global.rom_first_region(device); region != null; region = romload_global.rom_next_region(region))
                {
// temporary hack: add the driver path & region name
                    string combinedpath = device.searchpath() + ";" + driverpath;
                    if (!string.IsNullOrEmpty(device.shortname()))
                    {
                        combinedpath += ";" + device.shortname();
                    }
                    m_searchpath = combinedpath;

                    for (ListPointer <rom_entry> rom = romload_global.rom_first_file(region); rom != null; rom = romload_global.rom_next_file(rom))
                    {
                        string name = romload_global.ROM_GETNAME(rom[0]);
                        util.hash_collection hashes        = new util.hash_collection(romload_global.ROM_GETHASHDATA(rom[0]));
                        device_t             shared_device = find_shared_device(device, name, hashes, romload_global.ROM_GETLENGTH(rom[0]));

                        // count the number of files with hashes
                        if (!hashes.flag(util.hash_collection.FLAG_NO_DUMP) && !romload_global.ROM_ISOPTIONAL(rom[0]))
                        {
                            required++;
                            if (shared_device != null)
                            {
                                shared_required++;
                            }
                        }

                        // audit a file
                        audit_record record = null;
                        if (romload_global.ROMREGION_ISROMDATA(region[0]))
                        {
                            record = audit_one_rom(rom);
                        }

                        // audit a disk
                        else if (romload_global.ROMREGION_ISDISKDATA(region[0]))
                        {
                            record = audit_one_disk(rom);
                        }

                        if (record != null)
                        {
                            // count the number of files that are found.
                            if (record.status() == audit_record.audit_status.STATUS_GOOD || (record.status() == audit_record.audit_status.STATUS_FOUND_INVALID && find_shared_device(device, name, record.actual_hashes(), record.actual_length()) == null))
                            {
                                found++;
                                if (shared_device != null)
                                {
                                    shared_found++;
                                }
                            }

                            record.set_shared_device(shared_device);
                        }
                    }
                }
            }

            // if we only find files that are in the parent & either the set has no unique files or the parent is not found, then assume we don't have the set at all
            if (found == shared_found && required > 0 && (required != shared_required || shared_found == 0))
            {
                m_record_list.clear();
                return(summary.NOTFOUND);
            }

            // return a summary
            string unused = "";

            return(summarize(m_enumerator.driver().name, ref unused));
        }
예제 #9
0
        // audit operations

        //-------------------------------------------------
        //  audit_media - audit the media described by the
        //  currently-enumerated driver
        //-------------------------------------------------
        public summary audit_media(string validation = AUDIT_VALIDATE_FULL)
        {
            // start fresh
            m_record_list.clear();

            // store validation for later
            m_validation = validation;

            // first walk the parent chain for required ROMs
            parent_rom_vector parentroms = new parent_rom_vector();

            for (var drvindex = driver_list.find(m_enumerator.driver().parent); 0 <= drvindex; drvindex = driver_list.find(driver_list.driver((size_t)drvindex).parent))  //for (auto drvindex = m_enumerator.find(m_enumerator.driver().parent); 0 <= drvindex; drvindex = m_enumerator.find(m_enumerator.driver(drvindex).parent))
            {
                game_driver parent = driver_list.driver((size_t)drvindex);
                LOG(null, "Checking parent {0} for ROM files\n", parent.type.shortname());
                std.vector <rom_entry> roms = rom_build_entries(parent.rom);
                for (Pointer <rom_entry> region = rom_first_region(new Pointer <rom_entry>(roms)); region != null; region = rom_next_region(region)) //for (rom_entry const *region = rom_first_region(&roms.front()); region; region = rom_next_region(region))
                {
                    for (Pointer <rom_entry> rom = rom_first_file(region); rom != null; rom = rom_next_file(rom))                                    //for (rom_entry const *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
                    {
                        LOG(null, "Adding parent ROM {0}\n", rom.op.name());
                        parentroms.emplace_back(new parent_rom(parent.type, rom));
                    }
                }
            }

            parentroms.remove_redundant_parents();

            // count ROMs required/found
            size_t found           = 0;
            size_t required        = 0;
            size_t shared_found    = 0;
            size_t shared_required = 0;
            size_t parent_found    = 0;

            // iterate over devices and regions
            std.vector <string> searchpath = new std.vector <string>();
            foreach (device_t device in new device_enumerator(m_enumerator.config().root_device()))
            {
                searchpath.clear();

                // now iterate over regions and ROMs within
                for (Pointer <rom_entry> region = rom_first_region(device); region != null; region = rom_next_region(region))
                {
                    for (Pointer <rom_entry> rom = rom_first_file(region); rom != null; rom = rom_next_file(rom))
                    {
                        if (searchpath.empty())
                        {
                            LOG(null, "Audit media for device {0}({1})\n", device.shortname(), device.tag());
                            searchpath = device.searchpath();
                        }

                        // look for a matching parent or device ROM
                        string name = rom.op.name();
                        util.hash_collection hashes = new util.hash_collection(rom.op.hashdata());
                        bool        dumped          = !hashes.flag(util.hash_collection.FLAG_NO_DUMP);
                        device_type shared_device   = parentroms.find_shared_device(device, name, hashes, rom_file_size(rom));
                        if (shared_device != null)
                        {
                            LOG(null, "File '{0}' {1}{2}dumped shared with {3}\n", name, ROM_ISOPTIONAL(rom.op) ? "optional " : "", dumped ? "" : "un", shared_device.shortname());
                        }
                        else
                        {
                            LOG(null, "File '{0}' {1}{2}dumped\n", name, ROM_ISOPTIONAL(rom.op) ? "optional " : "", dumped ? "" : "un");
                        }

                        // count the number of files with hashes
                        if (dumped && !ROM_ISOPTIONAL(rom.op))
                        {
                            required++;
                            if (shared_device != null)
                            {
                                shared_required++;
                            }
                        }

                        // audit a file
                        audit_record record = null;
                        if (ROMREGION_ISROMDATA(region.op))
                        {
                            record = audit_one_rom(searchpath, rom);
                        }

                        // audit a disk
                        else if (ROMREGION_ISDISKDATA(region.op))
                        {
                            record = audit_one_disk(rom, device);
                        }

                        if (record != null)
                        {
                            // see if the actual content found belongs to a parent
                            var matchesshared = parentroms.actual_matches_shared(device, record);
                            if (matchesshared.first != null)
                            {
                                LOG(null, "Actual ROM file shared with {0}parent {1}\n", matchesshared.second ? "immediate " : "", matchesshared.first.shortname());
                            }

                            // count the number of files that are found.
                            if ((record.status() == audit_status.GOOD) || ((record.status() == audit_status.FOUND_INVALID) && (matchesshared.first == null)))
                            {
                                found++;
                                if (shared_device != null)
                                {
                                    shared_found++;
                                }
                                if (matchesshared.second)
                                {
                                    parent_found++;
                                }
                            }

                            record.set_shared_device(shared_device);
                        }
                    }
                }
            }

            if (!searchpath.empty())
            {
                LOG(null, "Total required={0} (shared={1}) found={2} (shared={3} parent={4})\n", required, shared_required, found, shared_found, parent_found);
            }

            // if we only find files that are in the parent & either the set has no unique files or the parent is not found, then assume we don't have the set at all
            if ((found == shared_found) && required != 0 && ((required != shared_required) || parent_found == 0))
            {
                m_record_list.clear();
                return(summary.NOTFOUND);
            }

            // return a summary
            return(summarize(m_enumerator.driver().name));
        }