Fix disc VFS layout & update nod
This commit is contained in:
parent
f346239b81
commit
1f4b452bd5
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.24.1"
|
version = "0.24.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gimli",
|
"gimli",
|
||||||
]
|
]
|
||||||
|
@ -34,18 +34,6 @@ dependencies = [
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.8.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
"version_check",
|
|
||||||
"zerocopy 0.7.35",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -395,7 +383,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decomp-toolkit"
|
name = "decomp-toolkit"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
|
@ -447,7 +435,7 @@ dependencies = [
|
||||||
"tracing-attributes",
|
"tracing-attributes",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"xxhash-rust",
|
"xxhash-rust",
|
||||||
"zerocopy 0.8.0",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -577,6 +565,12 @@ version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
|
@ -598,9 +592,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.0"
|
version = "0.31.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
|
@ -608,20 +602,14 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.14.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
|
||||||
dependencies = [
|
|
||||||
"ahash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
|
@ -672,7 +660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.15.0",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -918,9 +906,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nod"
|
name = "nod"
|
||||||
version = "1.4.1"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fc8822a8dac202a8589b1c49c7916bf8dec0adb8e8048f4f5cb979f9f4bc5e9"
|
checksum = "89c1186fb8e051c71e3f7b0b67bc2ab4e82c34c59d4fcc91d58ec2a030a9aff5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"aes",
|
"aes",
|
||||||
|
@ -937,15 +925,15 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
"sha1",
|
"sha1",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"zerocopy 0.8.0",
|
"zerocopy",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodtool"
|
name = "nodtool"
|
||||||
version = "1.4.1"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f838d5c364ae3f04fbec424baa64facadb401b8114a6b1f96ea35b2d99f5e13"
|
checksum = "331755fd6f5f07bcafa5a5bde23dcdf3a68aa34b922bfa17af8a16a4669cbe15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argp",
|
"argp",
|
||||||
"base16ct",
|
"base16ct",
|
||||||
|
@ -968,7 +956,7 @@ dependencies = [
|
||||||
"tracing-attributes",
|
"tracing-attributes",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"xxhash-rust",
|
"xxhash-rust",
|
||||||
"zerocopy 0.8.0",
|
"zerocopy",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1046,12 +1034,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.36.4"
|
version = "0.36.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
|
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
@ -2154,38 +2142,18 @@ checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "dd2e5ce961dea177d282ec084dca2aa411b7411199a68d79eb1beacb305a6cd9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive 0.7.35",
|
"zerocopy-derive",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerocopy"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df7885ffcb82507a0f213c593e77c5f13d12cb96588d4e835ad7e9423ba034db"
|
|
||||||
dependencies = [
|
|
||||||
"zerocopy-derive 0.8.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.35"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
checksum = "b06304eeddb6081af98ac59db08c868ac197e586086b996d15a86ed70e09a754"
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.79",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerocopy-derive"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "930ad75608219e8ffdb8962a5433cb2b30064c7ccb564d3b76c2963390b1e435"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -3,7 +3,7 @@ name = "decomp-toolkit"
|
||||||
description = "Yet another GameCube/Wii decompilation toolkit."
|
description = "Yet another GameCube/Wii decompilation toolkit."
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
repository = "https://github.com/encounter/decomp-toolkit"
|
repository = "https://github.com/encounter/decomp-toolkit"
|
||||||
|
|
171
src/vfs/disc.rs
171
src/vfs/disc.rs
|
@ -7,8 +7,9 @@ use std::{
|
||||||
use filetime::FileTime;
|
use filetime::FileTime;
|
||||||
use nodtool::{
|
use nodtool::{
|
||||||
nod,
|
nod,
|
||||||
nod::{DiscStream, Fst, NodeKind, OwnedFileStream, PartitionBase, PartitionMeta},
|
nod::{Disc, DiscStream, Fst, NodeKind, OwnedFileStream, PartitionBase, PartitionMeta},
|
||||||
};
|
};
|
||||||
|
use zerocopy::IntoBytes;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
next_non_empty, StaticFile, Vfs, VfsError, VfsFile, VfsFileType, VfsMetadata, VfsResult,
|
next_non_empty, StaticFile, Vfs, VfsError, VfsFile, VfsFileType, VfsMetadata, VfsResult,
|
||||||
|
@ -16,72 +17,100 @@ use super::{
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DiscFs {
|
pub struct DiscFs {
|
||||||
|
disc: Arc<Disc>,
|
||||||
base: Box<dyn PartitionBase>,
|
base: Box<dyn PartitionBase>,
|
||||||
meta: Box<PartitionMeta>,
|
meta: Box<PartitionMeta>,
|
||||||
mtime: Option<FileTime>,
|
mtime: Option<FileTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DiscNode<'a> {
|
enum SpecialDir {
|
||||||
None,
|
|
||||||
Root,
|
Root,
|
||||||
Sys,
|
Sys,
|
||||||
|
Disc,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DiscNode<'a> {
|
||||||
|
None,
|
||||||
|
Special(SpecialDir),
|
||||||
Node(Fst<'a>, usize, nod::Node),
|
Node(Fst<'a>, usize, nod::Node),
|
||||||
Static(&'a [u8]),
|
Static(&'a [u8]),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiscFs {
|
impl DiscFs {
|
||||||
pub fn new(mut base: Box<dyn PartitionBase>, mtime: Option<FileTime>) -> io::Result<Self> {
|
pub fn new(
|
||||||
|
disc: Arc<Disc>,
|
||||||
|
mut base: Box<dyn PartitionBase>,
|
||||||
|
mtime: Option<FileTime>,
|
||||||
|
) -> io::Result<Self> {
|
||||||
let meta = base.meta().map_err(nod_to_io_error)?;
|
let meta = base.meta().map_err(nod_to_io_error)?;
|
||||||
Ok(Self { base, meta, mtime })
|
Ok(Self { disc, base, meta, mtime })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find(&self, path: &str) -> VfsResult<DiscNode> {
|
fn find(&self, path: &str) -> VfsResult<DiscNode> {
|
||||||
let path = path.trim_matches('/');
|
let path = path.trim_matches('/');
|
||||||
let mut split = path.split('/');
|
let mut split = path.split('/');
|
||||||
let mut segment = next_non_empty(&mut split);
|
let mut segment = next_non_empty(&mut split);
|
||||||
if segment.is_empty() {
|
match segment.to_ascii_lowercase().as_str() {
|
||||||
return Ok(DiscNode::Root);
|
"" => Ok(DiscNode::Special(SpecialDir::Root)),
|
||||||
}
|
"files" => {
|
||||||
if segment.eq_ignore_ascii_case("files") {
|
let fst = Fst::new(&self.meta.raw_fst)?;
|
||||||
let fst = Fst::new(&self.meta.raw_fst)?;
|
if next_non_empty(&mut split).is_empty() {
|
||||||
if next_non_empty(&mut split).is_empty() {
|
let root = fst.nodes[0];
|
||||||
let root = fst.nodes[0];
|
return Ok(DiscNode::Node(fst, 0, root));
|
||||||
return Ok(DiscNode::Node(fst, 0, root));
|
|
||||||
}
|
|
||||||
let remainder = &path[segment.len() + 1..];
|
|
||||||
match fst.find(remainder) {
|
|
||||||
Some((idx, node)) => Ok(DiscNode::Node(fst, idx, node)),
|
|
||||||
None => Ok(DiscNode::None),
|
|
||||||
}
|
|
||||||
} else if segment.eq_ignore_ascii_case("sys") {
|
|
||||||
segment = next_non_empty(&mut split);
|
|
||||||
// No directories in sys
|
|
||||||
if split.next().is_some() {
|
|
||||||
return Ok(DiscNode::None);
|
|
||||||
}
|
|
||||||
match segment.to_ascii_lowercase().as_str() {
|
|
||||||
"" => Ok(DiscNode::Sys),
|
|
||||||
"boot.bin" => Ok(DiscNode::Static(self.meta.raw_boot.as_slice())),
|
|
||||||
"bi2.bin" => Ok(DiscNode::Static(self.meta.raw_bi2.as_slice())),
|
|
||||||
"apploader.bin" => Ok(DiscNode::Static(self.meta.raw_apploader.as_ref())),
|
|
||||||
"fst.bin" => Ok(DiscNode::Static(self.meta.raw_fst.as_ref())),
|
|
||||||
"main.dol" => Ok(DiscNode::Static(self.meta.raw_dol.as_ref())),
|
|
||||||
"ticket.bin" => {
|
|
||||||
Ok(DiscNode::Static(self.meta.raw_ticket.as_deref().ok_or(VfsError::NotFound)?))
|
|
||||||
}
|
}
|
||||||
"tmd.bin" => {
|
let remainder = &path[segment.len() + 1..];
|
||||||
Ok(DiscNode::Static(self.meta.raw_tmd.as_deref().ok_or(VfsError::NotFound)?))
|
match fst.find(remainder) {
|
||||||
|
Some((idx, node)) => Ok(DiscNode::Node(fst, idx, node)),
|
||||||
|
None => Ok(DiscNode::None),
|
||||||
}
|
}
|
||||||
"cert.bin" => Ok(DiscNode::Static(
|
|
||||||
self.meta.raw_cert_chain.as_deref().ok_or(VfsError::NotFound)?,
|
|
||||||
)),
|
|
||||||
"h3.bin" => Ok(DiscNode::Static(
|
|
||||||
self.meta.raw_h3_table.as_deref().ok_or(VfsError::NotFound)?,
|
|
||||||
)),
|
|
||||||
_ => Ok(DiscNode::None),
|
|
||||||
}
|
}
|
||||||
} else {
|
"sys" => {
|
||||||
return Ok(DiscNode::None);
|
segment = next_non_empty(&mut split);
|
||||||
|
// No directories in sys
|
||||||
|
if !next_non_empty(&mut split).is_empty() {
|
||||||
|
return Ok(DiscNode::None);
|
||||||
|
}
|
||||||
|
match segment.to_ascii_lowercase().as_str() {
|
||||||
|
"" => Ok(DiscNode::Special(SpecialDir::Sys)),
|
||||||
|
"boot.bin" => Ok(DiscNode::Static(self.meta.raw_boot.as_slice())),
|
||||||
|
"bi2.bin" => Ok(DiscNode::Static(self.meta.raw_bi2.as_slice())),
|
||||||
|
"apploader.img" => Ok(DiscNode::Static(self.meta.raw_apploader.as_ref())),
|
||||||
|
"fst.bin" => Ok(DiscNode::Static(self.meta.raw_fst.as_ref())),
|
||||||
|
"main.dol" => Ok(DiscNode::Static(self.meta.raw_dol.as_ref())),
|
||||||
|
_ => Ok(DiscNode::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"disc" => {
|
||||||
|
if !self.disc.header().is_wii() {
|
||||||
|
return Ok(DiscNode::None);
|
||||||
|
}
|
||||||
|
segment = next_non_empty(&mut split);
|
||||||
|
// No directories in disc
|
||||||
|
if !next_non_empty(&mut split).is_empty() {
|
||||||
|
return Ok(DiscNode::None);
|
||||||
|
}
|
||||||
|
match segment.to_ascii_lowercase().as_str() {
|
||||||
|
"" => Ok(DiscNode::Special(SpecialDir::Disc)),
|
||||||
|
"header.bin" => Ok(DiscNode::Static(&self.disc.header().as_bytes()[..0x100])),
|
||||||
|
"region.bin" => {
|
||||||
|
Ok(DiscNode::Static(self.disc.region().ok_or(VfsError::NotFound)?))
|
||||||
|
}
|
||||||
|
_ => Ok(DiscNode::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"ticket.bin" => {
|
||||||
|
Ok(DiscNode::Static(self.meta.raw_ticket.as_deref().ok_or(VfsError::NotFound)?))
|
||||||
|
}
|
||||||
|
"tmd.bin" => {
|
||||||
|
Ok(DiscNode::Static(self.meta.raw_tmd.as_deref().ok_or(VfsError::NotFound)?))
|
||||||
|
}
|
||||||
|
"cert.bin" => {
|
||||||
|
Ok(DiscNode::Static(self.meta.raw_cert_chain.as_deref().ok_or(VfsError::NotFound)?))
|
||||||
|
}
|
||||||
|
"h3.bin" => {
|
||||||
|
Ok(DiscNode::Static(self.meta.raw_h3_table.as_deref().ok_or(VfsError::NotFound)?))
|
||||||
|
}
|
||||||
|
_ => Ok(DiscNode::None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,8 +119,7 @@ impl Vfs for DiscFs {
|
||||||
fn open(&mut self, path: &str) -> VfsResult<Box<dyn VfsFile>> {
|
fn open(&mut self, path: &str) -> VfsResult<Box<dyn VfsFile>> {
|
||||||
match self.find(path)? {
|
match self.find(path)? {
|
||||||
DiscNode::None => Err(VfsError::NotFound),
|
DiscNode::None => Err(VfsError::NotFound),
|
||||||
DiscNode::Root => Err(VfsError::IsADirectory),
|
DiscNode::Special(_) => Err(VfsError::IsADirectory),
|
||||||
DiscNode::Sys => Err(VfsError::IsADirectory),
|
|
||||||
DiscNode::Node(_, _, node) => match node.kind() {
|
DiscNode::Node(_, _, node) => match node.kind() {
|
||||||
NodeKind::File => {
|
NodeKind::File => {
|
||||||
if node.length() > 2048 {
|
if node.length() > 2048 {
|
||||||
|
@ -119,28 +147,41 @@ impl Vfs for DiscFs {
|
||||||
fn read_dir(&mut self, path: &str) -> VfsResult<Vec<String>> {
|
fn read_dir(&mut self, path: &str) -> VfsResult<Vec<String>> {
|
||||||
match self.find(path)? {
|
match self.find(path)? {
|
||||||
DiscNode::None => Err(VfsError::NotFound),
|
DiscNode::None => Err(VfsError::NotFound),
|
||||||
DiscNode::Root => Ok(vec!["files".to_string(), "sys".to_string()]),
|
DiscNode::Special(SpecialDir::Root) => {
|
||||||
DiscNode::Sys => {
|
let mut entries = vec!["files".to_string(), "sys".to_string()];
|
||||||
let mut sys = vec![
|
if self.disc.header().is_wii() {
|
||||||
"boot.bin".to_string(),
|
entries.push("disc".to_string());
|
||||||
"bi2.bin".to_string(),
|
|
||||||
"apploader.bin".to_string(),
|
|
||||||
"fst.bin".to_string(),
|
|
||||||
"main.dol".to_string(),
|
|
||||||
];
|
|
||||||
if self.meta.raw_ticket.is_some() {
|
|
||||||
sys.push("ticket.bin".to_string());
|
|
||||||
}
|
|
||||||
if self.meta.raw_tmd.is_some() {
|
|
||||||
sys.push("tmd.bin".to_string());
|
|
||||||
}
|
}
|
||||||
if self.meta.raw_cert_chain.is_some() {
|
if self.meta.raw_cert_chain.is_some() {
|
||||||
sys.push("cert.bin".to_string());
|
entries.push("cert.bin".to_string());
|
||||||
}
|
}
|
||||||
if self.meta.raw_h3_table.is_some() {
|
if self.meta.raw_h3_table.is_some() {
|
||||||
sys.push("h3.bin".to_string());
|
entries.push("h3.bin".to_string());
|
||||||
}
|
}
|
||||||
Ok(sys)
|
if self.meta.raw_ticket.is_some() {
|
||||||
|
entries.push("ticket.bin".to_string());
|
||||||
|
}
|
||||||
|
if self.meta.raw_tmd.is_some() {
|
||||||
|
entries.push("tmd.bin".to_string());
|
||||||
|
}
|
||||||
|
Ok(entries)
|
||||||
|
}
|
||||||
|
DiscNode::Special(SpecialDir::Sys) => Ok(vec![
|
||||||
|
"boot.bin".to_string(),
|
||||||
|
"bi2.bin".to_string(),
|
||||||
|
"apploader.img".to_string(),
|
||||||
|
"fst.bin".to_string(),
|
||||||
|
"main.dol".to_string(),
|
||||||
|
]),
|
||||||
|
DiscNode::Special(SpecialDir::Disc) => {
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
if self.disc.header().is_wii() {
|
||||||
|
entries.push("header.bin".to_string());
|
||||||
|
if self.disc.region().is_some() {
|
||||||
|
entries.push("region.bin".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(entries)
|
||||||
}
|
}
|
||||||
DiscNode::Node(fst, idx, node) => {
|
DiscNode::Node(fst, idx, node) => {
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
|
@ -173,7 +214,7 @@ impl Vfs for DiscFs {
|
||||||
fn metadata(&mut self, path: &str) -> VfsResult<VfsMetadata> {
|
fn metadata(&mut self, path: &str) -> VfsResult<VfsMetadata> {
|
||||||
match self.find(path)? {
|
match self.find(path)? {
|
||||||
DiscNode::None => Err(VfsError::NotFound),
|
DiscNode::None => Err(VfsError::NotFound),
|
||||||
DiscNode::Root | DiscNode::Sys => {
|
DiscNode::Special(_) => {
|
||||||
Ok(VfsMetadata { file_type: VfsFileType::Directory, len: 0, mtime: self.mtime })
|
Ok(VfsMetadata { file_type: VfsFileType::Directory, len: 0, mtime: self.mtime })
|
||||||
}
|
}
|
||||||
DiscNode::Node(_, _, node) => {
|
DiscNode::Node(_, _, node) => {
|
||||||
|
|
|
@ -325,10 +325,11 @@ pub fn open_fs(mut file: Box<dyn VfsFile>, kind: ArchiveKind) -> io::Result<Box<
|
||||||
ArchiveKind::Rarc => Ok(Box::new(RarcFs::new(file)?)),
|
ArchiveKind::Rarc => Ok(Box::new(RarcFs::new(file)?)),
|
||||||
ArchiveKind::U8 => Ok(Box::new(U8Fs::new(file)?)),
|
ArchiveKind::U8 => Ok(Box::new(U8Fs::new(file)?)),
|
||||||
ArchiveKind::Disc(_) => {
|
ArchiveKind::Disc(_) => {
|
||||||
let disc = nod::Disc::new_stream(file.into_disc_stream()).map_err(nod_to_io_error)?;
|
let disc =
|
||||||
|
Arc::new(nod::Disc::new_stream(file.into_disc_stream()).map_err(nod_to_io_error)?);
|
||||||
let partition =
|
let partition =
|
||||||
disc.open_partition_kind(nod::PartitionKind::Data).map_err(nod_to_io_error)?;
|
disc.open_partition_kind(nod::PartitionKind::Data).map_err(nod_to_io_error)?;
|
||||||
Ok(Box::new(DiscFs::new(partition, metadata.mtime)?))
|
Ok(Box::new(DiscFs::new(disc, partition, metadata.mtime)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue