-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from ieee802dot11ac/main
Initial multitool work
- Loading branch information
Showing
9 changed files
with
364 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "milo" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
byteorder = "1.5.0" | ||
clap = { version = "4.4.16", features = ["derive"] } | ||
flate2 = "1.0.28" | ||
tempfile = "3.9.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use std::error::Error; | ||
use std::fs::File; | ||
|
||
use crate::fio::read_u32; | ||
use crate::traits::Load; | ||
pub mod amp; | ||
pub mod freq; | ||
|
||
pub enum ArkTypes { | ||
FreqArk(freq::FreqArchive), | ||
AmpArk(amp::AmpArchive), | ||
} | ||
|
||
pub fn load_ark_file(f: &mut File) -> Result<ArkTypes, Box<dyn Error>> { | ||
let vercheck = read_u32(f, true)?; | ||
let ark: ArkTypes; | ||
match vercheck { | ||
0x004B5241 => { | ||
let mut freq = freq::FreqArchive::new(); | ||
freq.load(f, 0)?; | ||
ark = ArkTypes::FreqArk(freq); | ||
} | ||
0..=2 => { | ||
let mut amp = amp::AmpArchive::new(); | ||
amp.load(f, 0)?; | ||
ark = ArkTypes::AmpArk(amp); | ||
} | ||
_ => { | ||
println!("unrecognized ark version. if gh1 or later, use the .hdr and not the .ark"); | ||
return Err::<_, Box<dyn Error>>("unkver".into()); | ||
} | ||
} | ||
Ok(ark) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use std::fmt::{Formatter, Display}; | ||
use std::error::Error; | ||
|
||
use crate::traits::Load; | ||
use crate::fio; | ||
|
||
#[derive(Clone, Copy)] | ||
struct AmpFileEntry { | ||
offset: u32, | ||
file_name_idx: u32, | ||
folder_name_idx: u32, | ||
size: u32, | ||
inflated_size: u32, | ||
} | ||
|
||
impl AmpFileEntry { | ||
pub fn new() -> Self { | ||
Self { | ||
offset: 0, | ||
file_name_idx: 0, | ||
folder_name_idx: 0, | ||
size: 0, | ||
inflated_size: 0, | ||
} | ||
} | ||
} | ||
|
||
impl Load for AmpFileEntry { | ||
fn load(&mut self, f: &mut std::fs::File, ver: u32) -> Result<(), Box<dyn std::error::Error>> { | ||
if ver != 1 {self.offset = fio::read_u32(f, true)?;} | ||
self.file_name_idx = fio::read_u32(f, true)?; | ||
self.folder_name_idx = fio::read_u32(f, true)?; | ||
if ver == 1 {self.offset = fio::read_u32(f, true)?;} | ||
self.size = fio::read_u32(f, true)?; | ||
self.inflated_size = fio::read_u32(f, true)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Display for AmpFileEntry { | ||
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { | ||
fmt.write_fmt(format_args!("Offset: {}", self.offset))?; | ||
fmt.write_fmt(format_args!("File name index: {}", self.file_name_idx))?; | ||
fmt.write_fmt(format_args!("Folder name index: {}", self.folder_name_idx))?; | ||
fmt.write_fmt(format_args!("Size: {}", self.size))?; | ||
fmt.write_fmt(format_args!("Inflated size: {}", self.inflated_size))?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct AmpArchive { | ||
version: u32, | ||
entry_ct: u32, | ||
entries: Vec<AmpFileEntry>, | ||
str_table_size: u32, | ||
string_table: Vec<String>, | ||
string_idx_count: u32, | ||
string_idx_entries: Vec<u32> | ||
} | ||
|
||
impl AmpArchive { | ||
pub fn new() -> Self { | ||
Self { | ||
version: 0, | ||
entry_ct: 0, | ||
entries: vec![], | ||
str_table_size: 0, | ||
string_table: vec![], | ||
string_idx_count: 0, | ||
string_idx_entries: vec![] | ||
} | ||
} | ||
} | ||
|
||
impl Load for AmpArchive { | ||
fn load(&mut self, f: &mut std::fs::File, _: u32) -> Result<(), Box<dyn Error>> { | ||
self.version = fio::read_u32(f, true)?; | ||
self.entry_ct = fio::read_u32(f, true)?; | ||
for _ in 0..self.entry_ct { | ||
let mut ent = AmpFileEntry::new(); | ||
ent.load(f, self.version)?; | ||
self.entries.push(ent); | ||
} | ||
self.str_table_size = fio::read_u32(f, true)?; | ||
for _ in 0..self.str_table_size { | ||
let st = fio::readstr(f)?; | ||
self.string_table.push(st); | ||
} | ||
self.string_idx_count = fio::read_u32(f, true)?; | ||
for _ in 0..self.string_idx_count { | ||
let idx = fio::read_u32(f, true)?; | ||
self.string_idx_entries.push(idx); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Display for AmpArchive { | ||
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { | ||
fmt.write_fmt(format_args!("Version: {}", self.version))?; | ||
fmt.write_str("BEGIN ENTRIES")?; | ||
for ent in self.entries.clone() { | ||
ent.fmt(fmt)?; | ||
} | ||
fmt.write_str("END ENTRIES")?; | ||
fmt.write_fmt(format_args!("String table size: {}", self.str_table_size))?; | ||
for i in 0..self.str_table_size { | ||
fmt.write_fmt(format_args!("Entry {i}: {}", self.string_table[i as usize]))?; | ||
} | ||
fmt.write_fmt(format_args!("String index count: {}", self.string_idx_count))?; | ||
for i in 0..self.string_idx_entries.len() { | ||
fmt.write_fmt(format_args!("Index {i}: {}", self.string_idx_entries[i]))?; | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use crate::traits::Load; | ||
use crate::fio; | ||
use std::fmt::Display; | ||
use std::fs::File; | ||
use std::error::Error; | ||
|
||
#[derive(Clone, Copy)] | ||
struct FreqFileEntry { // 24 bytes | ||
unknown: u32, // Path name hash? | ||
file_name_offset: u32, | ||
folder_name_index: u16, | ||
block_offset: u16, | ||
block: u32, // Use block * block_size + block_offset to get file position | ||
file_size: u32, | ||
inflated_size: u32, // Same as file size if not compressed | ||
fake_file_offset: u32 // = (block * 2048) + block_offset; | ||
} | ||
|
||
impl Load for FreqFileEntry { | ||
fn load(&mut self, f: &mut File, _: u32) -> Result<(), Box<dyn Error>> { | ||
self.unknown = fio::read_u32(f, true)?; | ||
self.file_name_offset = fio::read_u32(f, true)?; | ||
self.folder_name_index = fio::read_u16(f, true)?; | ||
self.block_offset = fio::read_u16(f, true)?; | ||
self.block = fio::read_u32(f, true)?; | ||
self.file_size = fio::read_u32(f, true)?; | ||
self.inflated_size = fio::read_u32(f, true)?; | ||
self.fake_file_offset = (self.block * 2048) + self.block_offset as u32; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Display for FreqFileEntry { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_fmt(format_args!("Unknown value (possibly a pathname hash?): {}", self.unknown))?; | ||
f.write_fmt(format_args!("File name offset: {}", self.file_name_offset))?; | ||
f.write_fmt(format_args!("Folder name index: {}", self.folder_name_index))?; | ||
f.write_fmt(format_args!("Block offset: {}", self.block_offset))?; | ||
f.write_fmt(format_args!("Block #: {}", self.block))?; | ||
f.write_fmt(format_args!("File offset (calculated): {}", self.fake_file_offset))?; | ||
f.write_fmt(format_args!("File size: {}", self.file_size))?; | ||
f.write_fmt(format_args!("Inflated filesize: {}", self.inflated_size))?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy)] | ||
pub struct FreqArchive { | ||
magic: u32, // technically a char[4] but 0x204B5241 is easier to check | ||
version: u32, | ||
file_entry_offset: u32, // Always 256 | ||
file_entry_count: u32, | ||
folder_entry_offset: u32, | ||
folder_entry_count: u32, | ||
string_table_offset: u32, | ||
string_count: u32, | ||
total_hdr_size: u32, // Size of header + string offsets + string table | ||
block_size: u32, // Used for padding, always 2048? | ||
} | ||
|
||
impl FreqArchive { | ||
pub fn new() -> Self { | ||
Self { | ||
magic: 0x204B5241, | ||
version: 0, | ||
file_entry_offset: 256, | ||
file_entry_count: 0, | ||
folder_entry_offset: 0, | ||
folder_entry_count: 0, | ||
string_table_offset: 0, | ||
string_count: 0, | ||
total_hdr_size: 40, | ||
block_size: 2048 | ||
} | ||
} | ||
} | ||
|
||
impl Load for FreqArchive { | ||
fn load(&mut self, f: &mut File, _: u32) -> Result<(), Box<dyn Error>> { | ||
self.magic = fio::read_u32(f, true)?; | ||
self.version = fio::read_u32(f, true)?; | ||
self.file_entry_offset = fio::read_u32(f, true)?; | ||
self.file_entry_count = fio::read_u32(f, true)?; | ||
self.folder_entry_offset = fio::read_u32(f, true)?; | ||
self.folder_entry_count = fio::read_u32(f, true)?; | ||
self.string_table_offset = fio::read_u32(f, true)?; | ||
self.string_count = fio::read_u32(f, true)?; | ||
self.total_hdr_size = fio::read_u32(f, true)?; | ||
self.block_size = fio::read_u32(f, true)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Display for FreqArchive { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_fmt(format_args!("Magic value: {:#010X} \n", self.magic))?; | ||
f.write_fmt(format_args!("Should be 0x004B5241.\n"))?; | ||
f.write_fmt(format_args!("Version: {}\n", self.version))?; | ||
f.write_fmt(format_args!("File entry offset: {}\n", self.file_entry_offset))?; | ||
f.write_fmt(format_args!("File entry count: {}\n", self.file_entry_count))?; | ||
f.write_fmt(format_args!("Folder entry offset: {}\n", self.folder_entry_offset))?; | ||
f.write_fmt(format_args!("Folder entry count: {}\n", self.folder_entry_count))?; | ||
f.write_fmt(format_args!("String table offset: {}\n", self.string_table_offset))?; | ||
f.write_fmt(format_args!("String count: {}\n", self.string_count))?; | ||
f.write_fmt(format_args!("Total header size (includes string table): {}\n", self.total_hdr_size))?; | ||
f.write_fmt(format_args!("Block size: {}\n", self.block_size))?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use std::fs::File; | ||
use std::error::Error; | ||
use std::io::Read; | ||
use byteorder::{LittleEndian, BigEndian, ReadBytesExt}; | ||
|
||
fn readlen(f: &mut File, len: usize) -> Result<Vec<u8>, Box<dyn Error>> { | ||
let mut buf = vec![0u8; len]; | ||
f.read_exact(&mut buf)?; | ||
Ok(buf) | ||
} | ||
|
||
pub fn readstr(src: &mut File) -> Result<String, Box<dyn Error>> { | ||
let mut ret: String = String::with_capacity(256); | ||
for _ in 0..256 { // 256 is a good length limit, right | ||
let asciidiot = readlen(src, 1)?[0]; | ||
if asciidiot == 0 { | ||
ret.shrink_to_fit(); | ||
break | ||
} | ||
let test = char::from_u32(asciidiot as u32); | ||
ret.push(test.expect("found eof")); | ||
} | ||
Ok(ret) | ||
} | ||
|
||
pub fn read_u32(f: &mut File, little_endian: bool) -> Result<u32, Box<dyn Error>> { | ||
if little_endian { Ok(f.read_u32::<LittleEndian>()?) } | ||
else { Ok(f.read_u32::<BigEndian>()?) } | ||
} | ||
|
||
pub fn read_i32(f: &mut File, little_endian: bool) -> Result<i32, Box<dyn Error>> { | ||
if little_endian { Ok(f.read_i32::<LittleEndian>()?) } | ||
else { Ok(f.read_i32::<BigEndian>()?) } | ||
} | ||
|
||
pub fn read_u16(f: &mut File, little_endian: bool) -> Result<u16, Box<dyn Error>> { | ||
if little_endian { Ok(f.read_u16::<LittleEndian>()?) } | ||
else { Ok(f.read_u16::<BigEndian>()?) } | ||
} | ||
|
||
pub fn read_i16(f: &mut File, little_endian: bool) -> Result<i16, Box<dyn Error>> { | ||
if little_endian { Ok(f.read_i16::<LittleEndian>()?) } | ||
else { Ok(f.read_i16::<BigEndian>()?) } | ||
} | ||
|
||
pub fn read_u8(f: &mut File) -> Result<u8, Box<dyn Error>> { Ok(f.read_u8()?) } | ||
pub fn read_i8(f: &mut File) -> Result<i8, Box<dyn Error>> { Ok(f.read_i8()?) } | ||
|
||
pub fn read_f32(f: &mut File, little_endian: bool) -> Result<f32, Box<dyn Error>> { | ||
if little_endian { Ok(f.read_f32::<LittleEndian>()?) } | ||
else { Ok(f.read_f32::<BigEndian>()?) } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod ark; | ||
pub mod traits; | ||
mod fio; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use std::fs::File; | ||
use std::error::Error; | ||
use std::path::PathBuf; | ||
use clap::Parser; | ||
use milo::ark; | ||
use milo::traits::Load; | ||
|
||
#[derive(clap::Parser)] | ||
struct Args { | ||
input: PathBuf, | ||
} | ||
|
||
fn main() -> Result<(), Box<dyn Error>> { | ||
println!("Hello, world!"); | ||
let args = Args::parse(); | ||
let mut infile = File::open(args.input)?; | ||
let mut freqindasheets = ark::freq::FreqArchive::new(); | ||
freqindasheets.load(&mut infile, 0)?; | ||
println!("{}", freqindasheets); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
use std::error::Error; | ||
use std::fs::File; | ||
|
||
pub trait Load { | ||
fn load(&mut self, f: &mut File, ver: u32) -> Result<(), Box<dyn Error>>; | ||
} | ||
|
||
pub trait Save { | ||
fn save(&mut self, f: &mut File) -> Result<(), Box<dyn Error>>; | ||
} | ||
|
||
pub trait Port { | ||
fn import(&mut self, f: &mut File) -> Result<(), Box<dyn Error>>; | ||
fn export(&mut self, f: &mut File) -> Result<(), Box<dyn Error>>; | ||
} |