unlock: adopt UnlockCtx in the Unlocker impl
libfreemkv's Unlocker trait now hands matches()/unlock()/set_max_read_speed() an UnlockCtx instead of a bare DriveId. The firmware unlocker keys off ctx.drive_id (disc kind is irrelevant to it).
This commit is contained in:
+24
-9
@@ -27,7 +27,7 @@ mod platform;
|
|||||||
|
|
||||||
use error::Result;
|
use error::Result;
|
||||||
use libfreemkv::aacs::Vid;
|
use libfreemkv::aacs::Vid;
|
||||||
use libfreemkv::{DriveId, ScsiTransport, Unlocked, UnlockError, Unlocker};
|
use libfreemkv::{DriveId, ScsiTransport, UnlockCtx, UnlockError, Unlocked, Unlocker};
|
||||||
use scsi::DataDirection;
|
use scsi::DataDirection;
|
||||||
|
|
||||||
/// The LibreDrive unlocker.
|
/// The LibreDrive unlocker.
|
||||||
@@ -128,8 +128,9 @@ impl Unlocker for LibreDrive {
|
|||||||
"LibreDrive"
|
"LibreDrive"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches(&self, id: &DriveId) -> bool {
|
fn matches(&self, ctx: &UnlockCtx) -> bool {
|
||||||
profile::find_bundled(id).is_some()
|
// Firmware unlock keys off the drive identity; disc kind is irrelevant.
|
||||||
|
profile::find_bundled(ctx.drive_id).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Firmware-unlock the drive AND return the disc's OEM Volume ID in one step
|
/// Firmware-unlock the drive AND return the disc's OEM Volume ID in one step
|
||||||
@@ -146,8 +147,9 @@ impl Unlocker for LibreDrive {
|
|||||||
fn unlock(
|
fn unlock(
|
||||||
&self,
|
&self,
|
||||||
scsi: &mut dyn ScsiTransport,
|
scsi: &mut dyn ScsiTransport,
|
||||||
id: &DriveId,
|
ctx: &UnlockCtx,
|
||||||
) -> std::result::Result<Unlocked, UnlockError> {
|
) -> std::result::Result<Unlocked, UnlockError> {
|
||||||
|
let id = ctx.drive_id;
|
||||||
let Some(m) = profile::find_bundled(id) else {
|
let Some(m) = profile::find_bundled(id) else {
|
||||||
// matches() returned true but the profile vanished — this unlocker
|
// matches() returned true but the profile vanished — this unlocker
|
||||||
// cannot put the firmware into extended mode.
|
// cannot put the firmware into extended mode.
|
||||||
@@ -182,8 +184,8 @@ impl Unlocker for LibreDrive {
|
|||||||
/// `0xBB SET CD SPEED`-to-max command) over the raw transport. A profile
|
/// `0xBB SET CD SPEED`-to-max command) over the raw transport. A profile
|
||||||
/// without a `set_speed_max_cdb` (or no matching profile at all) is a
|
/// without a `set_speed_max_cdb` (or no matching profile at all) is a
|
||||||
/// no-op — the drive stays at its current speed.
|
/// no-op — the drive stays at its current speed.
|
||||||
fn set_max_read_speed(&self, scsi: &mut dyn ScsiTransport, id: &DriveId) -> Result<()> {
|
fn set_max_read_speed(&self, scsi: &mut dyn ScsiTransport, ctx: &UnlockCtx) -> Result<()> {
|
||||||
let Some(m) = profile::find_bundled(id) else {
|
let Some(m) = profile::find_bundled(ctx.drive_id) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let Some(cdb) = m.profile.set_speed_max_cdb else {
|
let Some(cdb) = m.profile.set_speed_max_cdb else {
|
||||||
@@ -203,8 +205,15 @@ impl Unlocker for LibreDrive {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use libfreemkv::DiscKind;
|
||||||
use scsi::{DataDirection, ScsiResult, ScsiTransport};
|
use scsi::{DataDirection, ScsiResult, ScsiTransport};
|
||||||
|
|
||||||
|
/// Drive-prep unlock context for a fake drive id (disc kind irrelevant to
|
||||||
|
/// the firmware unlocker — it keys off the drive identity).
|
||||||
|
fn ctx(id: &DriveId) -> UnlockCtx<'_> {
|
||||||
|
UnlockCtx::new(id, DiscKind::Unknown)
|
||||||
|
}
|
||||||
|
|
||||||
/// A fake transport that fills the response buffer from a fixed payload
|
/// A fake transport that fills the response buffer from a fixed payload
|
||||||
/// and reports a configurable transferred-byte count. Exercises the OEM
|
/// and reports a configurable transferred-byte count. Exercises the OEM
|
||||||
/// VID response-parse branches without a live drive.
|
/// VID response-parse branches without a live drive.
|
||||||
@@ -325,7 +334,10 @@ mod tests {
|
|||||||
bytes_transferred: 36,
|
bytes_transferred: 36,
|
||||||
};
|
};
|
||||||
let err = LibreDrive::new()
|
let err = LibreDrive::new()
|
||||||
.unlock(&mut t, &make_drive_id("FAKE-VND", "9.99", "XX12345", ""))
|
.unlock(
|
||||||
|
&mut t,
|
||||||
|
&ctx(&make_drive_id("FAKE-VND", "9.99", "XX12345", "")),
|
||||||
|
)
|
||||||
.expect_err("no profile → FirmwareNotUnlockable");
|
.expect_err("no profile → FirmwareNotUnlockable");
|
||||||
assert_eq!(err, UnlockError::FirmwareNotUnlockable);
|
assert_eq!(err, UnlockError::FirmwareNotUnlockable);
|
||||||
}
|
}
|
||||||
@@ -370,7 +382,7 @@ mod tests {
|
|||||||
calls: 0,
|
calls: 0,
|
||||||
};
|
};
|
||||||
LibreDrive::new()
|
LibreDrive::new()
|
||||||
.set_max_read_speed(&mut t, &known_vid_drive_id())
|
.set_max_read_speed(&mut t, &ctx(&known_vid_drive_id()))
|
||||||
.expect("set_max_read_speed ok");
|
.expect("set_max_read_speed ok");
|
||||||
assert_eq!(t.calls, 1, "exactly one CDB issued");
|
assert_eq!(t.calls, 1, "exactly one CDB issued");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -388,7 +400,10 @@ mod tests {
|
|||||||
calls: 0,
|
calls: 0,
|
||||||
};
|
};
|
||||||
LibreDrive::new()
|
LibreDrive::new()
|
||||||
.set_max_read_speed(&mut t, &make_drive_id("FAKE-VND", "9.99", "XX12345", ""))
|
.set_max_read_speed(
|
||||||
|
&mut t,
|
||||||
|
&ctx(&make_drive_id("FAKE-VND", "9.99", "XX12345", "")),
|
||||||
|
)
|
||||||
.expect("no-profile is a no-op Ok(())");
|
.expect("no-profile is a no-op Ok(())");
|
||||||
assert_eq!(t.calls, 0, "no profile → no CDB issued");
|
assert_eq!(t.calls, 0, "no profile → no CDB issued");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user