diff --git a/nod/src/common.rs b/nod/src/common.rs index 55f9692..bb7966d 100644 --- a/nod/src/common.rs +++ b/nod/src/common.rs @@ -38,6 +38,8 @@ pub enum Format { Rvz, /// WBFS Wbfs, + /// Partition stripped WBFS + StrippedWbfs([bool; 64]), /// WIA Wia, /// TGC @@ -53,6 +55,7 @@ impl Format { Format::Gcz => crate::io::gcz::DEFAULT_BLOCK_SIZE, Format::Rvz => crate::io::wia::RVZ_DEFAULT_CHUNK_SIZE, Format::Wbfs => crate::io::wbfs::DEFAULT_BLOCK_SIZE, + Format::StrippedWbfs(_) => crate::io::wbfs::DEFAULT_BLOCK_SIZE, Format::Wia => crate::io::wia::WIA_DEFAULT_CHUNK_SIZE, _ => 0, } @@ -80,6 +83,7 @@ impl fmt::Display for Format { Format::Nfs => write!(f, "NFS"), Format::Rvz => write!(f, "RVZ"), Format::Wbfs => write!(f, "WBFS"), + Format::StrippedWbfs(_) => write!(f, "Stripped WBFS"), Format::Wia => write!(f, "WIA"), Format::Tgc => write!(f, "TGC"), } diff --git a/nod/src/disc/writer.rs b/nod/src/disc/writer.rs index bbf76d6..9830784 100644 --- a/nod/src/disc/writer.rs +++ b/nod/src/disc/writer.rs @@ -200,12 +200,18 @@ pub(crate) fn check_block( lfg: &mut LaggedFibonacci, disc_id: [u8; 4], disc_num: u8, + strip_partitions: [bool; 64] ) -> io::Result { let start_sector = (input_position / SECTOR_SIZE as u64) as u32; let end_sector = ((input_position + buf.len() as u64) / SECTOR_SIZE as u64) as u32; if let Some(partition) = partition_info.iter().find(|p| { p.has_hashes && start_sector >= p.data_start_sector && end_sector < p.data_end_sector }) { + // Strip partition data + if strip_partitions[partition.index] { + return Ok(CheckBlockResult::Zeroed); + } + if input_position % SECTOR_SIZE as u64 != 0 { return Err(io::Error::other("Partition block not aligned to sector boundary")); } diff --git a/nod/src/io/block.rs b/nod/src/io/block.rs index 319b47f..e3ac55a 100644 --- a/nod/src/io/block.rs +++ b/nod/src/io/block.rs @@ -53,7 +53,7 @@ pub fn new(mut stream: Box) -> Result> { Some(Format::Nfs) => { return Err(Error::DiscFormat("NFS requires a filesystem path".to_string())); } - Some(Format::Wbfs) => crate::io::wbfs::BlockReaderWBFS::new(stream)?, + Some(Format::Wbfs | Format::StrippedWbfs(_)) => crate::io::wbfs::BlockReaderWBFS::new(stream)?, Some(Format::Wia | Format::Rvz) => crate::io::wia::BlockReaderWIA::new(stream)?, Some(Format::Tgc) => crate::io::tgc::BlockReaderTGC::new(stream)?, None => return Err(Error::DiscFormat("Unknown disc format".to_string())), @@ -99,7 +99,7 @@ pub fn open(filename: &Path) -> Result> { } }, Some(Format::Tgc) => crate::io::tgc::BlockReaderTGC::new(stream)?, - Some(Format::Wbfs) => crate::io::wbfs::BlockReaderWBFS::new(stream)?, + Some(Format::Wbfs | Format::StrippedWbfs(_)) => crate::io::wbfs::BlockReaderWBFS::new(stream)?, Some(Format::Wia | Format::Rvz) => crate::io::wia::BlockReaderWIA::new(stream)?, None => return Err(Error::DiscFormat("Unknown disc format".to_string())), }; diff --git a/nod/src/io/ciso.rs b/nod/src/io/ciso.rs index 2da458d..1b86c00 100644 --- a/nod/src/io/ciso.rs +++ b/nod/src/io/ciso.rs @@ -178,6 +178,7 @@ impl BlockProcessor for BlockProcessorCISO { &mut self.lfg, self.disc_id, self.disc_num, + [false; 64] )? { CheckBlockResult::Normal => { BlockResult { block_idx, disc_data, block_data, meta: CheckBlockResult::Normal } diff --git a/nod/src/io/wbfs.rs b/nod/src/io/wbfs.rs index 94766f4..2ee97b9 100644 --- a/nod/src/io/wbfs.rs +++ b/nod/src/io/wbfs.rs @@ -165,6 +165,7 @@ struct BlockProcessorWBFS { lfg: LaggedFibonacci, disc_id: [u8; 4], disc_num: u8, + strip_partitions: [bool; 64] } impl Clone for BlockProcessorWBFS { @@ -177,6 +178,7 @@ impl Clone for BlockProcessorWBFS { lfg: LaggedFibonacci::default(), disc_id: self.disc_id, disc_num: self.disc_num, + strip_partitions: self.strip_partitions, } } } @@ -199,6 +201,7 @@ impl BlockProcessor for BlockProcessorWBFS { &mut self.lfg, self.disc_id, self.disc_num, + self.strip_partitions )? { CheckBlockResult::Normal => { BlockResult { block_idx, disc_data, block_data, meta: CheckBlockResult::Normal } @@ -226,15 +229,19 @@ pub struct DiscWriterWBFS { header: WBFSHeader, disc_table: Box<[u8]>, block_count: u16, + strip_partitions: [bool; 64], } pub const DEFAULT_BLOCK_SIZE: u32 = 0x200000; // 2 MiB impl DiscWriterWBFS { pub fn new(mut inner: DiscReader, options: &FormatOptions) -> Result> { - if options.format != Format::Wbfs { - return Err(Error::DiscFormat("Invalid format for WBFS writer".to_string())); - } + let strip_partitions = match options.format { + Format::Wbfs => [false; 64], + Format::StrippedWbfs(strip_partitions) => strip_partitions, + _ => return Err(Error::DiscFormat("Invalid format for WBFS writer".to_string())), + }; + if options.compression != Compression::None { return Err(Error::DiscFormat("WBFS does not support compression".to_string())); } @@ -275,7 +282,7 @@ impl DiscWriterWBFS { } inner.rewind().context("Seeking to start")?; - Ok(Box::new(Self { inner, header, disc_table, block_count })) + Ok(Box::new(Self { inner, header, disc_table, block_count, strip_partitions })) } } @@ -317,6 +324,7 @@ impl DiscWriter for DiscWriterWBFS { lfg: LaggedFibonacci::default(), disc_id, disc_num, + strip_partitions: self.strip_partitions }, self.block_count as u32, options.processor_threads, diff --git a/nod/src/write.rs b/nod/src/write.rs index 21a8972..49ed896 100644 --- a/nod/src/write.rs +++ b/nod/src/write.rs @@ -107,6 +107,7 @@ impl DiscWriter { Format::Gcz => crate::io::gcz::DiscWriterGCZ::new(reader, &options)?, Format::Tgc => crate::io::tgc::DiscWriterTGC::new(reader, &options)?, Format::Wbfs => crate::io::wbfs::DiscWriterWBFS::new(reader, &options)?, + Format::StrippedWbfs(_) => crate::io::wbfs::DiscWriterWBFS::new(reader, &options)?, Format::Wia | Format::Rvz => crate::io::wia::DiscWriterWIA::new(reader, &options)?, format => return Err(Error::Other(format!("Unsupported write format: {format}"))), };