Audit fixes (14 critical, 22 warnings): - UDF: bounds checks on all ICB/FID parsing from disc data - SCSI Linux: saturating_sub on residual, CDB length guard, buffer size guard - SCSI macOS: SCSITaskStatus u32 (was u8 — stack corruption) - AACS: EC mod_inv returns infinity instead of panic, key reduced mod n - AACS: do_handshake tries all host certs (was returning on first failure) - H.264: bounds check on SPS < 4 bytes - ContentReader: error on missing unit key (was zero-fill) - KEYDB: flat redirect loop (was recursive), 100MB response limit, Windows HOME fallback - ISO writer: AVDP extent order, partition length, allocation cap - Network: removed TCP_NODELAY on bulk stream - MKV: guard on u64::MAX seek - disc.rs: saturating_sub on extent offset, simplified dead region code - cargo fmt (610 violations), cargo clippy --fix (55 auto-fixes) DVD support (new files): - src/ifo.rs — IFO parser (VIDEO_TS.IFO, VTS_XX_0.IFO, PGC chains, cells, streams) — 13 tests - src/mux/ps.rs — MPEG-2 Program Stream demuxer (pack headers, PES, private stream 1) — 12 tests - src/mux/codec/mpeg2.rs — MPEG-2 video parser (sequence headers, I-frame detection) — 15 tests - src/css/crack.rs — split-attack algorithm (LFSR cipher needs verification — test ignored) 226 tests total (was 186), 1 ignored (CSS crack needs cipher verification).
61 lines
1.5 KiB
Rust
61 lines
1.5 KiB
Rust
//! MT1959 variant A firmware upload.
|
||
//!
|
||
//! WRITE_BUFFER (0x3B) → verify READ_BUFFER (0x45) → unlock × 2
|
||
|
||
use super::Mt1959;
|
||
use crate::error::Result;
|
||
use crate::scsi::{DataDirection, ScsiTransport};
|
||
|
||
const SCSI_WRITE_BUFFER: u8 = 0x3B;
|
||
const VERIFY_BUFFER_ID: u8 = 0x45;
|
||
|
||
pub(super) fn load_firmware(mt: &mut Mt1959, scsi: &mut dyn ScsiTransport) -> Result<()> {
|
||
let firmware = &mt.profile.firmware;
|
||
if firmware.is_empty() {
|
||
return Err(crate::error::Error::UnlockFailed);
|
||
}
|
||
|
||
// Upload firmware via WRITE_BUFFER
|
||
let len = firmware.len();
|
||
let cdb = [
|
||
SCSI_WRITE_BUFFER,
|
||
0x06,
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
(len >> 16) as u8,
|
||
(len >> 8) as u8,
|
||
len as u8,
|
||
0x00,
|
||
];
|
||
let mut data = firmware.clone();
|
||
scsi.execute(&cdb, DataDirection::ToDevice, &mut data, 30_000)?;
|
||
|
||
// Verify firmware loaded (non-fatal — different buffer_id 0x45)
|
||
let verify_cdb = [
|
||
super::SCSI_READ_BUFFER,
|
||
super::MODE_A,
|
||
VERIFY_BUFFER_ID,
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
super::VALIDATE_RESPONSE_SIZE,
|
||
0x00,
|
||
];
|
||
let mut verify_resp = [0u8; super::VALIDATE_RESPONSE_SIZE as usize];
|
||
let _ = scsi.execute(
|
||
&verify_cdb,
|
||
DataDirection::FromDevice,
|
||
&mut verify_resp,
|
||
5_000,
|
||
);
|
||
|
||
// Double unlock after firmware upload
|
||
mt.do_unlock(scsi)?;
|
||
mt.do_unlock(scsi)?;
|
||
Ok(())
|
||
}
|