Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package redumper for openSUSE:Factory checked in at 2026-07-20 09:59:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/redumper (Old) and /work/SRC/openSUSE:Factory/.redumper.new.24530 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "redumper" Mon Jul 20 09:59:15 2026 rev:8 rq:1366616 version:734 Changes: -------- --- /work/SRC/openSUSE:Factory/redumper/redumper.changes 2026-07-06 15:00:33.098513330 +0200 +++ /work/SRC/openSUSE:Factory/.redumper.new.24530/redumper.changes 2026-07-20 10:01:25.276332466 +0200 @@ -1,0 +2,11 @@ +Sun Jul 19 08:03:24 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 734 + * Update recommended OmniDrive version. + * Fix off by one in joliet UCS-2BE to UTF-8 conversion code. + * Remove xml tags from dvd key printing. + * Implement generic drive lead-in reading. + * Automatic sector order detection for generic drives. + * Support hp rebadges in flash_tsst. + +------------------------------------------------------------------- Old: ---- redumper-b729.tar.gz New: ---- redumper-b734.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ redumper.spec ++++++ --- /var/tmp/diff_new_pack.cQtpv1/_old 2026-07-20 10:01:25.892353198 +0200 +++ /var/tmp/diff_new_pack.cQtpv1/_new 2026-07-20 10:01:25.896353332 +0200 @@ -17,7 +17,7 @@ Name: redumper -Version: 729 +Version: 734 Release: 0 Summary: Low level CD dumper utility License: GPL-3.0-only ++++++ redumper-b729.tar.gz -> redumper-b734.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/CMakeLists.txt new/redumper-b734/CMakeLists.txt --- old/redumper-b729/CMakeLists.txt 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/CMakeLists.txt 2026-07-18 13:19:20.000000000 +0200 @@ -35,13 +35,21 @@ # C/C++ set(CMAKE_CXX_STANDARD 20) -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + option(REDUMPER_CLANG_USE_LIBCPP "Link to libc++ instead of system default" OFF) + + if(REDUMPER_CLANG_USE_LIBCPP) + add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>) + add_link_options(-stdlib=libc++) + endif() + + add_link_options(${REDUMPER_CLANG_LINK_OPTIONS}) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") add_compile_options(-Wall -Wextra -Werror) # remove after https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99426 is fixed add_compile_options(--param=ggc-min-expand=10000) -endif() -if(MSVC) +elseif(MSVC) # build MT configuration by default set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") @@ -110,6 +118,7 @@ "crc/crc.ixx" "crc/crc16_gsm.ixx" "crc/crc32.ixx" + "drive/detect.ixx" "drive/flash_mt1959.ixx" "drive/flash_plextor.ixx" "drive/flash_sd616.ixx" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/cd/cd_dump_extra.ixx new/redumper-b734/cd/cd_dump_extra.ixx --- old/redumper-b729/cd/cd_dump_extra.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/cd/cd_dump_extra.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -309,6 +309,93 @@ } +void generic_process_leadin(Context &ctx, const TOC &toc, std::fstream &fs_scram, std::fstream &fs_state, std::fstream &fs_subcode, Options &options) +{ + if(toc.sessions.empty() || toc.sessions.front().tracks.size() <= 1) + return; + + auto &t = toc.sessions.front().tracks.front(); + if(!(t.control & (uint8_t)ChannelQ::Control::DATA)) + return; + + int32_t track1_end = toc.sessions.front().tracks[1].lba_start; + auto write_offset = track_offset_by_sync(t.lba_start, track1_end, fs_state, fs_scram); + if(!write_offset) + return; + + int32_t combined_offset = *write_offset + ctx.drive_config.read_offset; + if(combined_offset >= 0 || combined_offset < -134 * (int32_t)CD_DATA_SIZE_SAMPLES) + return; + + // read from preceding sector up to and including start of first track + int32_t read_lba = sample_to_lba(*write_offset, 0) - 1; + uint32_t read_count = t.lba_start - read_lba + 1; + + // check if lead-in samples are needed + uint32_t sample_index = sample_offset_r2a(lba_to_sample(read_lba, -ctx.drive_config.read_offset)); + uint32_t samples_count = read_count * CD_DATA_SIZE_SAMPLES; + std::vector<State> existing_state(samples_count); + read_entry(fs_state, (uint8_t *)existing_state.data(), sizeof(State), sample_index, samples_count, 0, (uint8_t)State::ERROR_SKIP); + if(std::none_of(existing_state.begin(), existing_state.end(), [](State s) { return s == State::ERROR_SKIP || s == State::ERROR_C2; })) + return; + + auto layout = sector_order_layout(ctx.drive_config.sector_order); + std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE * read_count); + auto error_field = layout.c2_offset == CD_RAW_DATA_SIZE ? READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2; + auto sub_channel = layout.subcode_offset == CD_RAW_DATA_SIZE ? READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW; + + SPTD::Status status = cmd_read_cd(*ctx.sptd, sector_buffer.data(), CD_RAW_DATA_SIZE, read_lba, read_count, READ_CD_ExpectedSectorType::CD_DA, error_field, sub_channel); + if(status.status_code) + status = cmd_read_cd(*ctx.sptd, sector_buffer.data(), CD_RAW_DATA_SIZE, read_lba, read_count, READ_CD_ExpectedSectorType::ALL_TYPES, error_field, sub_channel); + + if(status.status_code) + { + if(options.verbose) + LOG("GENERIC: lead-in read failed (LBA: {:6}, sectors: {}, SCSI: {})", read_lba, read_count, SPTD::StatusMessage(status)); + return; + } + + LOG("GENERIC: storing lead-in (LBA: {:6}, sectors: {})", read_lba, read_count); + + std::vector<State> state_buffer(read_count * CD_DATA_SIZE_SAMPLES); + std::vector<uint8_t> data_buffer(read_count * CD_DATA_SIZE); + std::vector<uint8_t> subcode_buffer(read_count * CD_SUBCODE_SIZE); + + for(uint32_t i = 0; i < read_count; ++i) + { + auto raw = sector_buffer.data() + layout.size * i; + + std::span<State> sector_state(&state_buffer[i * CD_DATA_SIZE_SAMPLES], CD_DATA_SIZE_SAMPLES); + std::span<uint8_t> sector_data(&data_buffer[i * CD_DATA_SIZE], CD_DATA_SIZE); + std::span<uint8_t> sector_subcode(&subcode_buffer[i * CD_SUBCODE_SIZE], CD_SUBCODE_SIZE); + + if(layout.c2_offset != CD_RAW_DATA_SIZE) + { + auto sector_state_c2 = c2_to_state(raw + layout.c2_offset, State::SUCCESS); + std::copy(sector_state_c2.begin(), sector_state_c2.end(), sector_state.begin()); + + if(options.verbose) + { + uint32_t c2_bits = c2_bits_count(std::span<const uint8_t>(raw + layout.c2_offset, CD_C2_SIZE)); + if(c2_bits) + LOGC_R("[LBA: {:6}] C2 error (bits: {:4})", read_lba + (int32_t)i, c2_bits); + } + } + else + std::fill(sector_state.begin(), sector_state.end(), State::SUCCESS_C2_OFF); + + if(layout.data_offset != CD_RAW_DATA_SIZE) + std::copy(raw + layout.data_offset, raw + layout.data_offset + CD_DATA_SIZE, sector_data.begin()); + + if(layout.subcode_offset != CD_RAW_DATA_SIZE) + std::copy(raw + layout.subcode_offset, raw + layout.subcode_offset + CD_SUBCODE_SIZE, sector_subcode.begin()); + } + + store_data(fs_scram, fs_state, data_buffer, state_buffer, lba_to_sample(read_lba, -ctx.drive_config.read_offset)); + store_subcode(fs_subcode, subcode_buffer, read_lba); +} + + export int redumper_dump_extra(Context &ctx, Options &options) { int exit_code = 0; @@ -334,6 +421,11 @@ if(!options.mediatek_skip_leadout && !is_omnidrive_firmware(ctx.drive_config)) mediatek_process_leadout(ctx, toc, fs_scram, fs_state, fs_subcode, options); } + else if(ctx.drive_config.type == Type::GENERIC) + { + if(!options.generic_skip_leadin) + generic_process_leadin(ctx, toc, fs_scram, fs_state, fs_subcode, options); + } return exit_code; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/drive/detect.ixx new/redumper-b734/drive/detect.ixx --- old/redumper-b729/drive/detect.ixx 1970-01-01 01:00:00.000000000 +0100 +++ new/redumper-b734/drive/detect.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -0,0 +1,107 @@ +module; +#include <algorithm> +#include <cstdint> +#include <string> +#include <vector> + +export module drive.detect; + +import cd.cd; +import cd.common; +import cd.subcode; +import cd.toc; +import common; +import drive; +import options; +import scsi.cmd; +import scsi.mmc; +import scsi.sptd; +import utils.logger; +import utils.strings; + + +namespace gpsxre +{ + + +export bool detect_sector_order(SPTD &sptd, DriveConfig &drive_config, int32_t lba) +{ + std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE); + + for(auto const &order : SECTOR_ORDER_STRING) + { + auto test_layout = sector_order_layout(order.first); + + auto error_field = test_layout.c2_offset == CD_RAW_DATA_SIZE ? READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2; + auto sub_channel = test_layout.subcode_offset == CD_RAW_DATA_SIZE ? READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW; + + // try read as-audio first, then fallback to as-data + auto status = cmd_read_cd(sptd, sector_buffer.data(), CD_RAW_DATA_SIZE, lba, 1, READ_CD_ExpectedSectorType::CD_DA, error_field, sub_channel); + if(status.status_code) + status = cmd_read_cd(sptd, sector_buffer.data(), CD_RAW_DATA_SIZE, lba, 1, READ_CD_ExpectedSectorType::ALL_TYPES, error_field, sub_channel); + if(status.status_code) + continue; + + // validate by checking subcode Q CRC at the expected offset + if(test_layout.subcode_offset != CD_RAW_DATA_SIZE) + { + if(subcode_extract_q(sector_buffer.data() + test_layout.subcode_offset).isValid()) + { + // C2 should be zeroed assuming a clean first sector + if(test_layout.c2_offset != CD_RAW_DATA_SIZE) + { + auto c2_start = sector_buffer.data() + test_layout.c2_offset; + if(std::any_of(c2_start, c2_start + CD_C2_SIZE, [](uint8_t v) { return v != 0; })) + continue; + } + + drive_config.sector_order = order.first; + LOG("GENERIC: auto-detected sector order: {}", order.second); + return true; + } + } + else + { + // no subcode, validate DATA_C2 order + if(test_layout.c2_offset != CD_RAW_DATA_SIZE) + { + auto c2_start = sector_buffer.data() + test_layout.c2_offset; + if(std::all_of(c2_start, c2_start + CD_C2_SIZE, [](uint8_t v) { return v == 0; })) + { + drive_config.sector_order = order.first; + LOG("GENERIC: auto-detected sector order: {} (no subcode validation)", order.second); + return true; + } + } + } + } + + return false; +} + + +export int redumper_drive_detect(Context &ctx, Options &options) +{ + int exit_code = 0; + + if(ctx.disc_type != DiscType::CD) + return exit_code; + + if(ctx.drive_config.type == Type::GENERIC && ctx.drive_config.read_method == ReadMethod::BE && !options.drive_sector_order) + { + auto toc_buffer = toc_read(*ctx.sptd); + TOC toc(toc_buffer, false); + if(toc.sessions.empty() || toc.sessions.front().tracks.empty()) + { + LOG("warning: sector order detection failed (TOC has no tracks), using default"); + return exit_code; + } + int32_t lba = toc.sessions.front().tracks.front().lba_start; + if(!detect_sector_order(*ctx.sptd, ctx.drive_config, lba)) + LOG("warning: sector order detection failed, using default"); + } + + return exit_code; +} + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/drive/flash_tsst.ixx new/redumper-b734/drive/flash_tsst.ixx --- old/redumper-b729/drive/flash_tsst.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/drive/flash_tsst.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -21,6 +21,8 @@ namespace gpsxre { +const std::set<std::string> TSST_SUPPORTED_VENDORS = { "TSSTcorp", "hp" }; + const std::set<std::string> TSST_SUPPORTED_DRIVES = { "DVD-ROM SH-D163A", "DVD-ROM SH-D163B", "DVD-ROM SH-D162C", "DVD-ROM SH-D163C", "DVD-ROM SH-D162D", "DVD-ROM TS-H353A", "DVD-ROM TS-H353B", "DVD-ROM TS-H353C", "DVD-ROM TS-H352C", "DVD-ROM TS-H352D", "DVD-ROM SH-116AB", "DVD-ROM SH-118CB" }; @@ -50,7 +52,7 @@ { int exit_code = 0; - if(!options.force_flash && (ctx.drive_config.vendor_id != "TSSTcorp" || !TSST_SUPPORTED_DRIVES.contains(ctx.drive_config.product_id))) + if(!options.force_flash && (!TSST_SUPPORTED_VENDORS.contains(ctx.drive_config.vendor_id) || !TSST_SUPPORTED_DRIVES.contains(ctx.drive_config.product_id))) throw_line("flashing of this drive is unsupported"); // block size is how much data is sent in one command, potentially it can vary but current value is taken from the original flasher diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/drive.ixx new/redumper-b734/drive.ixx --- old/redumper-b729/drive.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/drive.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -112,7 +112,7 @@ }; -static const std::map<SectorOrder, std::string> SECTOR_ORDER_STRING = { +export const std::map<SectorOrder, std::string> SECTOR_ORDER_STRING = { { SectorOrder::DATA_C2_SUB, "DATA_C2_SUB" }, { SectorOrder::DATA_SUB_C2, "DATA_SUB_C2" }, { SectorOrder::DATA_SUB, "DATA_SUB" }, @@ -474,7 +474,7 @@ export uint32_t omnidrive_minimum_version() { - return 0x00010002; + return 0x00010004; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/dvd/dvd_dump.ixx new/redumper-b734/dvd/dvd_dump.ixx --- old/redumper-b729/dvd/dvd_dump.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/dvd/dvd_dump.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -808,7 +808,10 @@ std::vector<Range<int32_t>> protection; - bool omnidrive_firmware = is_omnidrive_firmware(ctx.drive_config) != std::nullopt; + auto omnidrive_version = is_omnidrive_firmware(ctx.drive_config); + if(omnidrive_version && *omnidrive_version == 0x00010003) + throw_line("unsupported OmniDrive version for DVD dumping, upgrade to {}", omnidrive_version_string(omnidrive_minimum_version())); + bool omnidrive_firmware = omnidrive_version != std::nullopt; bool kreon_firmware = is_kreon_firmware(ctx.drive_config); bool kreon_locked = false; @@ -1139,7 +1142,7 @@ uint32_t refine_retries = options.retries ? options.retries : 1; FilesystemContext fs_ctx; - ROMEntry rom_entry(image_prefix + dump_get_config(ctx.disc_type, false).image_extension); + ROMEntry rom_entry(options.image_name + dump_get_config(ctx.disc_type, false).image_extension); bool rom_update = dump; SignalINT signal; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/dvd/dvd_key.ixx new/redumper-b734/dvd/dvd_key.ixx --- old/redumper-b729/dvd/dvd_key.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/dvd/dvd_key.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -125,7 +125,7 @@ std::string protection("unknown"); if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::NONE) - protection = "<none>"; + protection = "NONE"; else if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::CSS_CPPM) protection = "CSS/CPPM"; else if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::CPRM) @@ -180,9 +180,9 @@ { std::string title_key; if(t.second.empty()) - title_key = "<error>"; + title_key = "(error)"; else if(is_zeroed(t.second.data(), t.second.size())) - title_key = "<none>"; + title_key = "N/A"; else title_key = std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", t.second[0], t.second[1], t.second[2], t.second[3], t.second[4]); @@ -234,9 +234,9 @@ { std::string title_key; if(t.second.empty()) - title_key = "<error>"; + title_key = "(error)"; else if(is_zeroed(t.second.data(), t.second.size())) - title_key = "<none>"; + title_key = "N/A"; else title_key = std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", t.second[0], t.second[1], t.second[2], t.second[3], t.second[4]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/filesystem/iso9660/iso9660_defs.ixx new/redumper-b734/filesystem/iso9660/iso9660_defs.ixx --- old/redumper-b729/filesystem/iso9660/iso9660_defs.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/filesystem/iso9660/iso9660_defs.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -382,7 +382,7 @@ utf16_identifier[i] = endian_swap(identifier[i]); std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert("", u""); - std::string utf8_identifier = convert.to_bytes(utf16_identifier, &utf16_identifier[N - 1]); + std::string utf8_identifier = convert.to_bytes(utf16_identifier, &utf16_identifier[N]); return trim(utf8_identifier).c_str(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/options.ixx new/redumper-b734/options.ixx --- old/redumper-b729/options.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/options.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -44,6 +44,7 @@ std::unique_ptr<int> drive_pregap_start; std::unique_ptr<std::string> drive_read_method; std::unique_ptr<std::string> drive_sector_order; + bool auto_detect; std::unique_ptr<double> speed; int retries; bool refine_subchannel; @@ -62,6 +63,7 @@ bool plextor_leadin_force_store; bool mediatek_skip_leadout; int mediatek_leadout_retries; + bool generic_skip_leadin; bool kreon_partial_ss; bool dvd_raw; bool bd_raw; @@ -106,6 +108,7 @@ , overwrite(false) , force_split(false) , leave_unchanged(false) + , auto_detect(false) , retries(retries_default) , refine_subchannel(false) , refine_sector_mode(false) @@ -119,6 +122,7 @@ , plextor_leadin_force_store(false) , mediatek_skip_leadout(false) , mediatek_leadout_retries(mediatek_leadout_retries_default) + , generic_skip_leadin(false) , kreon_partial_ss(false) , dvd_raw(false) , bd_raw(false) @@ -230,6 +234,8 @@ drive_sector_order = std::make_unique<std::string>(); s_value = drive_sector_order.get(); } + else if(key == "--auto-detect") + auto_detect = true; else if(key == "--speed") { speed = std::make_unique<double>(); @@ -278,6 +284,8 @@ mediatek_skip_leadout = true; else if(key == "--mediatek-leadout-retries") i_value = &mediatek_leadout_retries; + else if(key == "--generic-skip-leadin") + generic_skip_leadin = true; else if(key == "--kreon-partial-ss") kreon_partial_ss = true; else if(key == "--dvd-raw") @@ -422,17 +430,18 @@ LOG("\t--drive-pregap-start=VALUE \toverride drive pre-gap start LBA"); LOG("\t--drive-read-method=VALUE \toverride drive read method, possible values: BE, D8, BE_CDDA"); LOG("\t--drive-sector-order=VALUE \toverride drive sector order, possible values: DATA_C2_SUB, DATA_SUB_C2, DATA_SUB, DATA_C2"); + LOG("\t--auto-detect \tattempt to automatically detect drive sector order for generic drives"); LOG(""); LOG("\t(drive specific)"); LOG("\t--plextor-skip-leadin \tskip dumping lead-in using negative range"); LOG("\t--plextor-leadin-retries=VALUE \tmaximum number of lead-in retries per session (default: {})", plextor_leadin_retries_default); LOG("\t--plextor-leadin-force-store \tstore unverified lead-in"); + LOG("\t--mediatek-skip-leadout \tskip extracting lead-out from drive cache"); + LOG("\t--mediatek-leadout-retries \tnumber of preceding lead-out sector reads to fill up the cache (default: {})", mediatek_leadout_retries_default); + LOG("\t--generic-skip-leadin \tskip dumping lead-in for negative offset discs on generic drives"); LOG("\t--kreon-partial-ss \tget minimal security sector (fixes bad firmware)"); LOG("\t--dvd-raw \tdump raw DVD sectors (OmniDrive)"); LOG("\t--bd-raw \tdump raw BD sectors (OmniDrive)"); - - LOG("\t--mediatek-skip-leadout \tskip extracting lead-out from drive cache"); - LOG("\t--mediatek-leadout-retries \tnumber of preceding lead-out sector reads to fill up the cache (default: {})", mediatek_leadout_retries_default); LOG("\t--disable-cdtext \tdisable CD-TEXT reading"); LOG(""); LOG("\t(offset)"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redumper-b729/redumper.ixx new/redumper-b734/redumper.ixx --- old/redumper-b729/redumper.ixx 2026-07-05 18:46:51.000000000 +0200 +++ new/redumper-b734/redumper.ixx 2026-07-18 13:19:20.000000000 +0200 @@ -26,6 +26,7 @@ import common; import debug; import drive; +import drive.detect; import drive.flash.mt1959; import drive.flash.plextor; import drive.flash.tsst; @@ -145,6 +146,7 @@ { "fixmsf", { false, false, false, true, false, redumper_fix_msf } }, { "debug::flip", { false, false, false, true, false, redumper_flip } }, { "drive::test", { true, true, true, false, false, redumper_drive_test } }, + { "drive::detect", { true, true, true, false, false, redumper_drive_detect } }, }; @@ -260,6 +262,8 @@ std::list<std::string> cd_commands{ "dump", "dump::extra", "protection", "refine", "dvdkey", "split", "hash", "info" }; if(options.rings) cd_commands.insert(cd_commands.begin(), "rings"); + if(options.auto_detect) + cd_commands.insert(cd_commands.begin(), "drive::detect"); if(options.auto_eject) { if(auto it = std::find(cd_commands.begin(), cd_commands.end(), "split"); it != cd_commands.end()) @@ -274,7 +278,7 @@ { for(auto it = cd_commands.begin(); it != cit;) { - if(*it == "rings" && std::find(cit, cd_commands.end(), "dump") != cd_commands.end() || *it == "protection") + if(*it == "rings" && std::find(cit, cd_commands.end(), "dump") != cd_commands.end() || *it == "protection" || *it == "drive::detect") ++it; else it = cd_commands.erase(it);
