0.31.0: hardening and correctness pass across mux, codec, AACS/CSS, UDF/MPLS/CLPI, recovery, drive/SCSI, labels, and I/O
Library-wide review-and-fix pass: tightened AACS keydb/handshake/variant handling and trailing-partial-unit policy, corrected MPLS mark offset and added UDF allocation bounds, hardened the mux/codec framing and M2TS paths, guarded SCSI READ CAPACITY short transfers and unified error mapping, added overflow guards on untrusted disc input, and made prefetch shutdown deterministic. Release profile now builds with thin LTO + single codegen unit.
This commit is contained in:
+23
-8
@@ -1,9 +1,18 @@
|
||||
//! Windows drive discovery and device resolution.
|
||||
|
||||
use crate::drive::DeviceResolution;
|
||||
use crate::error::Result;
|
||||
use crate::identity::DriveId;
|
||||
use std::path::Path;
|
||||
|
||||
/// SCSI peripheral device type 5 = MMC / optical, in the low 5 bits of
|
||||
/// INQUIRY byte 0.
|
||||
const SCSI_PERIPHERAL_TYPE_OPTICAL: u8 = 0x05;
|
||||
|
||||
/// Discover optical drives. Probes `\\.\CdRom0..15` first; only if none
|
||||
/// are found does it fall back to scanning drive letters `D..Z`. Each
|
||||
/// candidate is opened, INQUIRY'd, and kept only if its peripheral device
|
||||
/// type is optical (MMC, type 0x05). Returns normalized `\\.\` paths.
|
||||
pub fn find_drives() -> Vec<(String, DriveId)> {
|
||||
let mut drives = Vec::new();
|
||||
|
||||
@@ -12,7 +21,9 @@ pub fn find_drives() -> Vec<(String, DriveId)> {
|
||||
let path = format!("\\\\.\\CdRom{}", i);
|
||||
if let Ok(mut transport) = crate::scsi::open(Path::new(&path)) {
|
||||
if let Ok(id) = DriveId::from_drive(transport.as_mut()) {
|
||||
if !id.raw_inquiry.is_empty() && (id.raw_inquiry[0] & 0x1F) == 0x05 {
|
||||
if !id.raw_inquiry.is_empty()
|
||||
&& (id.raw_inquiry[0] & 0x1F) == SCSI_PERIPHERAL_TYPE_OPTICAL
|
||||
{
|
||||
drives.push((path, id));
|
||||
}
|
||||
}
|
||||
@@ -25,8 +36,12 @@ pub fn find_drives() -> Vec<(String, DriveId)> {
|
||||
let path = format!("{}:", letter as char);
|
||||
if let Ok(mut transport) = crate::scsi::open(Path::new(&path)) {
|
||||
if let Ok(id) = DriveId::from_drive(transport.as_mut()) {
|
||||
if !id.raw_inquiry.is_empty() && (id.raw_inquiry[0] & 0x1F) == 0x05 {
|
||||
drives.push((path, id));
|
||||
if !id.raw_inquiry.is_empty()
|
||||
&& (id.raw_inquiry[0] & 0x1F) == SCSI_PERIPHERAL_TYPE_OPTICAL
|
||||
{
|
||||
// Normalize so returned paths are consistently in
|
||||
// \\.\ form regardless of which loop matched.
|
||||
drives.push((normalize_path(&path), id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,8 +51,11 @@ pub fn find_drives() -> Vec<(String, DriveId)> {
|
||||
drives
|
||||
}
|
||||
|
||||
pub fn resolve_device(path: &str) -> Result<(String, Option<String>)> {
|
||||
Ok((normalize_path(path), None))
|
||||
/// Resolve a device path to its normalized Windows `\\.\` form. Windows
|
||||
/// has no `sr`→`sg` symlink-target indirection, so resolution is purely a
|
||||
/// path normalization and always reports [`DeviceResolution::Direct`].
|
||||
pub fn resolve_device(path: &str) -> Result<(String, DeviceResolution)> {
|
||||
Ok((normalize_path(path), DeviceResolution::Direct))
|
||||
}
|
||||
|
||||
/// Normalize a device path to Windows \\.\X: format.
|
||||
@@ -55,9 +73,6 @@ fn normalize_path(path: &str) -> String {
|
||||
if trimmed.len() == 2 && trimmed.as_bytes()[1] == b':' {
|
||||
return format!("\\\\.\\{}", trimmed);
|
||||
}
|
||||
if path.to_lowercase().starts_with("cdrom") {
|
||||
return format!("\\\\.\\{}", path);
|
||||
}
|
||||
format!("\\\\.\\{}", path)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user