unlock: add Unlocker::name() + report-only applies_to() for the matrix
Each unlocker now carries its own stable name() (the single source; apps never hardcode it) and a report-only applies_to() — phase-independent 'would this apply to this drive+disc', distinct from the dispatch-gated matches(). LibreDrive overrides applies_to to report on drive identity regardless of disc kind (its matches() is gated to the Unknown-kind init phase). Enables a registry-driven unlocker matrix.
This commit is contained in:
@@ -44,6 +44,10 @@ impl Default for AacsCert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Unlocker for AacsCert {
|
impl Unlocker for AacsCert {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"AACS"
|
||||||
|
}
|
||||||
|
|
||||||
fn matches(&self, ctx: &UnlockCtx) -> bool {
|
fn matches(&self, ctx: &UnlockCtx) -> bool {
|
||||||
ctx.kind == DiscKind::Aacs
|
ctx.kind == DiscKind::Aacs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,10 @@ impl Default for CssUnlocker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Unlocker for CssUnlocker {
|
impl crate::Unlocker for CssUnlocker {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"CSS"
|
||||||
|
}
|
||||||
|
|
||||||
fn matches(&self, ctx: &crate::UnlockCtx) -> bool {
|
fn matches(&self, ctx: &crate::UnlockCtx) -> bool {
|
||||||
ctx.kind == crate::DiscKind::Css
|
ctx.kind == crate::DiscKind::Css
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,10 +121,22 @@ impl Unlocker for LibreDrive {
|
|||||||
/// probed (`kind == Unknown`) and keys off the drive identity. It must NOT
|
/// probed (`kind == Unknown`) and keys off the drive identity. It must NOT
|
||||||
/// fire during the later content-keyed dispatch (Aacs/Css), or a DVD/Blu-ray
|
/// fire during the later content-keyed dispatch (Aacs/Css), or a DVD/Blu-ray
|
||||||
/// in a profiled drive would be re-firmware-unlocked.
|
/// in a profiled drive would be re-firmware-unlocked.
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"LibreDrive"
|
||||||
|
}
|
||||||
|
|
||||||
fn matches(&self, ctx: &UnlockCtx) -> bool {
|
fn matches(&self, ctx: &UnlockCtx) -> bool {
|
||||||
ctx.kind == crate::DiscKind::Unknown && profile::find_bundled(ctx.drive_id).is_some()
|
ctx.kind == crate::DiscKind::Unknown && profile::find_bundled(ctx.drive_id).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For the report, the drive unlocker applies whenever it recognises the
|
||||||
|
/// DRIVE — independent of disc kind (its live `matches` is gated to the
|
||||||
|
/// Unknown-kind init phase, which would falsely read "no" once the disc kind
|
||||||
|
/// is known).
|
||||||
|
fn applies_to(&self, ctx: &UnlockCtx) -> bool {
|
||||||
|
profile::find_bundled(ctx.drive_id).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Firmware-unlock the drive and report its OEM Volume ID. The unlocked drive
|
/// Firmware-unlock the drive and report its OEM Volume ID. The unlocked drive
|
||||||
/// serves CLEAR content, so `drive_unlocked: true` and there is no bus key.
|
/// serves CLEAR content, so `drive_unlocked: true` and there is no bus key.
|
||||||
///
|
///
|
||||||
|
|||||||
+1
-4
@@ -290,10 +290,7 @@ fn load_from_str(data: &str) -> Result<Profiles> {
|
|||||||
/// profile; the looser pass lets a drive whose firmware date we don't have
|
/// profile; the looser pass lets a drive whose firmware date we don't have
|
||||||
/// on file still match a same-model profile. All comparisons are
|
/// on file still match a same-model profile. All comparisons are
|
||||||
/// whitespace-trimmed. Returns the first section that yields a match.
|
/// whitespace-trimmed. Returns the first section that yields a match.
|
||||||
pub fn find_by_drive_id(
|
pub fn find_by_drive_id(profiles: &Profiles, drive_id: &crate::DriveId) -> Option<ProfileMatch> {
|
||||||
profiles: &Profiles,
|
|
||||||
drive_id: &crate::DriveId,
|
|
||||||
) -> Option<ProfileMatch> {
|
|
||||||
let v = drive_id.vendor_id.trim();
|
let v = drive_id.vendor_id.trim();
|
||||||
let r = drive_id.product_revision.trim();
|
let r = drive_id.product_revision.trim();
|
||||||
let vs = drive_id.vendor_specific.trim();
|
let vs = drive_id.vendor_specific.trim();
|
||||||
|
|||||||
+19
-1
@@ -110,8 +110,26 @@ pub enum UnlockError {
|
|||||||
/// NOTE: drive tuning (e.g. SET CD SPEED to lift riplock) is deliberately NOT
|
/// NOTE: drive tuning (e.g. SET CD SPEED to lift riplock) is deliberately NOT
|
||||||
/// here — that is the consumer's concern, not bus removal.
|
/// here — that is the consumer's concern, not bus removal.
|
||||||
pub trait Unlocker: Send + Sync {
|
pub trait Unlocker: Send + Sync {
|
||||||
/// True if this unlocker applies to the given context (drive id + disc kind).
|
/// Short, stable identifier for this unlocker (e.g. "LibreDrive", "AACS",
|
||||||
|
/// "CSS"). The ONE place a name lives — apps render the unlocker report from
|
||||||
|
/// [`all_unlockers`], never hardcoding names, so adding/removing an unlocker
|
||||||
|
/// updates every report with no app change.
|
||||||
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// True if this unlocker applies to the given context (drive id + disc kind)
|
||||||
|
/// during live dispatch — the gate [`crate::all_unlockers`] uses to decide
|
||||||
|
/// whether to RUN it.
|
||||||
fn matches(&self, ctx: &UnlockCtx) -> bool;
|
fn matches(&self, ctx: &UnlockCtx) -> bool;
|
||||||
|
|
||||||
|
/// Report-only: would this unlocker apply to this drive + disc, for a
|
||||||
|
/// user-facing unlocker matrix? Distinct from [`matches`](Unlocker::matches),
|
||||||
|
/// which is phase-gated (e.g. the drive-prep unlocker only `matches` at the
|
||||||
|
/// Unknown-kind init phase). Default: same as `matches`; the drive-keyed
|
||||||
|
/// unlocker overrides it to report on drive identity regardless of disc kind.
|
||||||
|
fn applies_to(&self, ctx: &UnlockCtx) -> bool {
|
||||||
|
self.matches(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove the bus-encryption barrier, returning what was learned.
|
/// Remove the bus-encryption barrier, returning what was learned.
|
||||||
fn unlock(
|
fn unlock(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
Reference in New Issue
Block a user