diff --git a/Cargo.toml b/Cargo.toml index 80e6f7a..f5111a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libfreemkv" -version = "0.29.0" +version = "0.30.0" edition = "2024" rust-version = "1.86" license = "AGPL-3.0-only" diff --git a/src/disc/mod.rs b/src/disc/mod.rs index b7c6192..3a5c9c5 100644 --- a/src/disc/mod.rs +++ b/src/disc/mod.rs @@ -1672,6 +1672,16 @@ impl Disc { // Content samples need the disc reader, which scan does not retain; // the caller fills these for sources that validate against ciphertext. samples: Vec::new(), + // Human title: prefer the UDF/ISO volume identifier, fall back to the + // BDMV display name. Identity only — a key service may catalog it. + volume_label: { + let v = self.volume_id.trim(); + if v.is_empty() { + self.meta_title.clone() + } else { + Some(v.to_string()) + } + }, }) } diff --git a/src/keysource.rs b/src/keysource.rs index d14b991..20f7923 100644 --- a/src/keysource.rs +++ b/src/keysource.rs @@ -35,6 +35,12 @@ pub struct DiscInputs { /// the disc reader, which the library's scan does not retain — so /// [`crate::Disc::inputs`] leaves it empty for the caller to fill. pub samples: Vec>, + /// The disc's human title — the UDF/ISO volume identifier (e.g. + /// `WICKED_FOR_GOOD`), falling back to the BDMV `` when present. + /// `None` when not captured. Identity only, no secret; a key service may + /// record it (keyed by `disc_hash`) to build a hash→title catalog. Not used + /// in any AACS derivation. + pub volume_label: Option, } /// A key source: a stateful provider that hands a disc's candidate [`Key`]s out