Add disc commands: info, extract, convert, verify

Utilizing https://github.com/encounter/nod-rs
This commit is contained in:
Luke Street 2024-05-01 00:12:20 -06:00
parent 9452ca8b8c
commit 4dacf2f39a
6 changed files with 380 additions and 2 deletions

299
Cargo.lock generated
View File

@ -17,6 +17,17 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.10" version = "0.8.10"
@ -165,17 +176,60 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "block-padding"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.11+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cbc"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [
"cipher",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.90" version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
dependencies = [
"jobserver",
"libc",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -183,6 +237,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.34.0" version = "2.34.0"
@ -198,6 +262,19 @@ dependencies = [
"vec_map", "vec_map",
] ]
[[package]]
name = "console"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.12" version = "0.2.12"
@ -281,6 +358,7 @@ dependencies = [
"memmap2", "memmap2",
"multimap", "multimap",
"nintendo-lz", "nintendo-lz",
"nodtool",
"num_enum", "num_enum",
"objdiff-core", "objdiff-core",
"object 0.35.0", "object 0.35.0",
@ -317,6 +395,12 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "dyn-clone"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]] [[package]]
name = "either" name = "either"
version = "1.10.0" version = "1.10.0"
@ -332,6 +416,21 @@ dependencies = [
"windows-sys 0.42.0", "windows-sys 0.42.0",
] ]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -463,6 +562,9 @@ name = "hex"
version = "0.4.3" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "indent" name = "indent"
@ -480,6 +582,38 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "indicatif"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
dependencies = [
"console",
"instant",
"number_prefix",
"portable-atomic",
"unicode-width",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"block-padding",
"generic-array",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "is-terminal" name = "is-terminal"
version = "0.4.12" version = "0.4.12"
@ -512,6 +646,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "jobserver"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -524,6 +667,26 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "liblzma"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "599133771f99c14ca089a8db3a4565f482ea6eeb66991b262bffc2b72acff69c"
dependencies = [
"liblzma-sys",
]
[[package]]
name = "liblzma-sys"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be9aaba5f9c8f8f615d41570909338b6284fbb1813dc057ecc68563d98a65097"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.21"
@ -539,6 +702,16 @@ dependencies = [
"regex-automata 0.1.10", "regex-automata 0.1.10",
] ]
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.2"
@ -582,6 +755,58 @@ dependencies = [
"clap", "clap",
] ]
[[package]]
name = "nod"
version = "1.2.0"
source = "git+https://github.com/encounter/nod-rs?rev=03b83484cb17f94408fa0ef8e50d94951464d1b2#03b83484cb17f94408fa0ef8e50d94951464d1b2"
dependencies = [
"adler",
"aes",
"base16ct",
"bzip2",
"cbc",
"digest",
"dyn-clone",
"encoding_rs",
"itertools",
"liblzma",
"log",
"miniz_oxide",
"rayon",
"sha1",
"thiserror",
"zerocopy",
"zstd",
]
[[package]]
name = "nodtool"
version = "1.2.0"
source = "git+https://github.com/encounter/nod-rs?rev=03b83484cb17f94408fa0ef8e50d94951464d1b2#03b83484cb17f94408fa0ef8e50d94951464d1b2"
dependencies = [
"argp",
"base16ct",
"crc32fast",
"digest",
"enable-ansi-support",
"hex",
"indicatif",
"itertools",
"log",
"md-5",
"nod",
"quick-xml",
"serde",
"sha1",
"size",
"supports-color 3.0.0",
"tracing",
"tracing-attributes",
"tracing-subscriber",
"xxhash-rust",
"zerocopy",
]
[[package]] [[package]]
name = "nu-ansi-term" name = "nu-ansi-term"
version = "0.46.0" version = "0.46.0"
@ -622,6 +847,12 @@ dependencies = [
"syn 2.0.52", "syn 2.0.52",
] ]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]] [[package]]
name = "objdiff-core" name = "objdiff-core"
version = "1.0.0" version = "1.0.0"
@ -724,6 +955,18 @@ version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "portable-atomic"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]] [[package]]
name = "ppc750cl" name = "ppc750cl"
version = "0.3.0" version = "0.3.0"
@ -759,6 +1002,16 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "quick-xml"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
dependencies = [
"memchr",
"serde",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.35" version = "1.0.35"
@ -940,6 +1193,17 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@ -955,6 +1219,12 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640"
[[package]]
name = "size"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fed904c7fb2856d868b92464fc8fa597fce366edea1a9cbfaa8cb5fe080bd6d"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.13.2" version = "1.13.2"
@ -1402,6 +1672,7 @@ version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [ dependencies = [
"byteorder",
"zerocopy-derive", "zerocopy-derive",
] ]
@ -1415,3 +1686,31 @@ dependencies = [
"quote", "quote",
"syn 2.0.52", "syn 2.0.52",
] ]
[[package]]
name = "zstd"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "7.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a"
dependencies = [
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.10+zstd.1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa"
dependencies = [
"cc",
"pkg-config",
]

View File

@ -44,6 +44,8 @@ memchr = "2.7.2"
memmap2 = "0.9.4" memmap2 = "0.9.4"
multimap = "0.10.0" multimap = "0.10.0"
nintendo-lz = "0.1.3" nintendo-lz = "0.1.3"
nodtool = { git = "https://github.com/encounter/nod-rs", rev = "03b83484cb17f94408fa0ef8e50d94951464d1b2" }
#nodtool = { path = "../nod-rs/nodtool" }
num_enum = "0.7.2" num_enum = "0.7.2"
objdiff-core = { git = "https://github.com/encounter/objdiff", rev = "2c46286affd11fe37f620ba919a3e57c4b80ccdb", features = ["ppc"] } objdiff-core = { git = "https://github.com/encounter/objdiff", rev = "2c46286affd11fe37f620ba919a3e57c4b80ccdb", features = ["ppc"] }
#objdiff-core = { path = "../objdiff/objdiff-core", features = ["ppc"] } #objdiff-core = { path = "../objdiff/objdiff-core", features = ["ppc"] }

View File

@ -22,6 +22,10 @@ project structure and build system that uses decomp-toolkit under the hood.
- [ar create](#ar-create) - [ar create](#ar-create)
- [ar extract](#ar-extract) - [ar extract](#ar-extract)
- [demangle](#demangle) - [demangle](#demangle)
- [disc info](#disc-info)
- [disc extract](#disc-extract)
- [disc convert](#disc-convert)
- [disc verify](#disc-verify)
- [dol info](#dol-info) - [dol info](#dol-info)
- [dol split](#dol-split) - [dol split](#dol-split)
- [dol diff](#dol-diff) - [dol diff](#dol-diff)
@ -167,6 +171,62 @@ $ dtk demangle 'BuildLight__9CGuiLightCFv'
CGuiLight::BuildLight() const CGuiLight::BuildLight() const
``` ```
### disc info
_`disc` commands are wrappers around the [nod](https://github.com/encounter/nod-rs) library
and its `nodtool` command line tool._
Displays information about disc images.
Supported disc image formats:
- ISO (GCM)
- WIA / RVZ
- WBFS (+ NKit 2 lossless)
- CISO (+ NKit 2 lossless)
- NFS (Wii U VC)
- GCZ
```shell
$ dtk disc info /path/to/game.iso
```
### disc extract
Extracts the contents of disc images to a directory.
See [disc info](#disc-info) for supported formats.
```shell
$ dtk disc extract /path/to/game.iso [outdir]
```
By default, only the main **data** partition is extracted.
Use the `-p`/`--partition` option to choose a different partition.
(Options: `all`, `data`, `update`, `channel`, or a partition index)
### disc convert
Converts any supported disc image to raw ISO (GCM).
If the format is lossless, the output will be identical to the original disc image.
See [disc info](#disc-info) for supported formats.
```shell
$ dtk disc convert /path/to/game.wia /path/to/game.iso
```
### disc verify
Hashes the contents of a disc image and verifies it against a built-in [Redump](http://redump.org/) database.
See [disc info](#disc-info) for supported formats.
```shell
$ dtk disc verify /path/to/game.iso
```
### dol info ### dol info
Analyzes a DOL file and outputs information section and symbol information. Analyzes a DOL file and outputs information section and symbol information.

13
src/cmd/disc.rs Normal file
View File

@ -0,0 +1,13 @@
use anyhow::{Error, Result};
use argp::FromArgs;
use nodtool::SubCommand;
#[derive(FromArgs, Debug)]
/// Commands for processing disc images.
#[argp(subcommand, name = "disc")]
pub struct Args {
#[argp(subcommand)]
command: SubCommand,
}
pub fn run(args: Args) -> Result<()> { nodtool::run(args.command).map_err(Error::new) }

View File

@ -1,6 +1,7 @@
pub mod alf; pub mod alf;
pub mod ar; pub mod ar;
pub mod demangle; pub mod demangle;
pub mod disc;
pub mod dol; pub mod dol;
pub mod dwarf; pub mod dwarf;
pub mod elf; pub mod elf;

View File

@ -56,7 +56,7 @@ impl FromArgValue for LogLevel {
} }
} }
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, Debug)]
/// Yet another GameCube/Wii decompilation toolkit. /// Yet another GameCube/Wii decompilation toolkit.
struct TopLevel { struct TopLevel {
#[argp(subcommand)] #[argp(subcommand)]
@ -70,18 +70,20 @@ struct TopLevel {
log_level: Option<LogLevel>, log_level: Option<LogLevel>,
/// Print version information and exit. /// Print version information and exit.
#[argp(switch, short = 'V')] #[argp(switch, short = 'V')]
#[allow(dead_code)]
version: bool, version: bool,
/// Disable color output. (env: NO_COLOR) /// Disable color output. (env: NO_COLOR)
#[argp(switch)] #[argp(switch)]
no_color: bool, no_color: bool,
} }
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, Debug)]
#[argp(subcommand)] #[argp(subcommand)]
enum SubCommand { enum SubCommand {
Alf(cmd::alf::Args), Alf(cmd::alf::Args),
Ar(cmd::ar::Args), Ar(cmd::ar::Args),
Demangle(cmd::demangle::Args), Demangle(cmd::demangle::Args),
Disc(cmd::disc::Args),
Dol(cmd::dol::Args), Dol(cmd::dol::Args),
Dwarf(cmd::dwarf::Args), Dwarf(cmd::dwarf::Args),
Elf(cmd::elf::Args), Elf(cmd::elf::Args),
@ -155,6 +157,7 @@ fn main() {
SubCommand::Alf(c_args) => cmd::alf::run(c_args), SubCommand::Alf(c_args) => cmd::alf::run(c_args),
SubCommand::Ar(c_args) => cmd::ar::run(c_args), SubCommand::Ar(c_args) => cmd::ar::run(c_args),
SubCommand::Demangle(c_args) => cmd::demangle::run(c_args), SubCommand::Demangle(c_args) => cmd::demangle::run(c_args),
SubCommand::Disc(c_args) => cmd::disc::run(c_args),
SubCommand::Dol(c_args) => cmd::dol::run(c_args), SubCommand::Dol(c_args) => cmd::dol::run(c_args),
SubCommand::Dwarf(c_args) => cmd::dwarf::run(c_args), SubCommand::Dwarf(c_args) => cmd::dwarf::run(c_args),
SubCommand::Elf(c_args) => cmd::elf::run(c_args), SubCommand::Elf(c_args) => cmd::elf::run(c_args),