diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ad31104 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rsfus" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e1bb776 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,105 @@ +use std::env; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::Path; + +fn main() { + let args: Vec = env::args().collect(); + + let iso_mount_dir = Path::new(args.get(1) + .expect("Arguments: rsfus (path to XP ISO mount)")) + .canonicalize().expect("Can't canonicalize path to XP ISO mount."); + + if !iso_mount_dir.exists() || !iso_mount_dir.is_dir() { + panic!("XP ISO mount is not a directory."); + } + + let amd64_basedir = iso_mount_dir.join("amd64"); + let i386_basedir = iso_mount_dir.join("i386"); + + { + let mut ntdetect = File::open(amd64_basedir.join("ntdetect.com")) + .or(File::open(i386_basedir.join("ntdetect.com"))) + .expect("Can't open file ntdetect.com."); + let mut ntdetect_copy = File::create(iso_mount_dir.join("ntdetect.com")) + .expect("Can't create file ntdetect.com."); + + let mut ntdetect_contents = Vec::new(); + println!("Reading {ntdetect:?}"); + ntdetect.read_to_end(&mut ntdetect_contents).expect("Can't read ntdetect.com."); + println!("Writing {ntdetect_copy:?}"); + ntdetect_copy.write_all(&ntdetect_contents).expect("Can't write to ntdetect.com."); + } + + { + let mut txtsetup = File::open(amd64_basedir.join("txtsetup.sif")) + .or(File::open(i386_basedir.join("txtsetup.sif"))) + .expect("Can't open file txtsetup.sif"); + let mut txtsetup_copy = File::create(iso_mount_dir.join("txtsetup.sif")) + .expect("Can't create file txtsetup.sif"); + + let mut txtsetup_contents = String::new(); + println!("Reading {txtsetup:?}"); + txtsetup.read_to_string(&mut txtsetup_contents).expect("Can't read from txtsetup.sif."); + let mut txtsetup_lines: Vec<&str> = Vec::new(); + for line in txtsetup_contents.lines() { + txtsetup_lines.push(line); + if line == "[SetupData]" { + println!("TXTSETP: Found [SetupData]"); + txtsetup_lines.push(r#"SetupSourceDevice = "\device\harddisk1\partition1""#); + } + } + println!("Writing {txtsetup_copy:?}"); + txtsetup_copy.write_all(txtsetup_lines.join("\r\n").as_bytes()) + .expect("Couldn't write to txtsetup.sif."); + } + + { + let mut bootmgr = File::open(amd64_basedir.join("setupldr.bin")) + .or(File::open(i386_basedir.join("setupldr.bin"))) + .expect("Can't open file setupldr.bin"); + let mut bootmgr_copy = File::create(iso_mount_dir.join("BOOTMGR")) + .expect("Can't create file BOOTMGR"); + + let mut bootmgr_contents = Vec::new(); + println!("Reading {bootmgr:?}"); + bootmgr.read_to_end(&mut bootmgr_contents).expect("Can't read from setupldr.bin"); + + if bootmgr_contents.len() > 0x2061 + && bootmgr_contents[0x2060] == 0x74 + && bootmgr_contents[0x2061] == 0x03 { + bootmgr_contents[0x2060] = 0xeb; + bootmgr_contents[0x2061] = 0x1a; + println!("BOOTMGR: 0x00002060 0x74 0x03 --> 0xeb 0x1a (Disable Win2k3 CRC check)"); + } + + let rdisk0 = b"rdisk(0)".as_slice(); + let win_nt_bt = b"$win_nt$.~bt".as_slice(); + let win_nt_bt_caps = b"$WIN_NT$.~BT".as_slice(); + let amd64_bytes = b"amd64"; + + for index in 0..(bootmgr_contents.len() - win_nt_bt.len()) { + if &bootmgr_contents[index..index+rdisk0.len()] == rdisk0 { + println!("BOOTMGR: {index:#010x} Patching rdisk(0) --> rdisk(1)"); + bootmgr_contents[index+6] = 0x31; + } + + // $WIN_NT$_~BT -> i386/amd64 + if &bootmgr_contents[index..index+win_nt_bt.len()] == win_nt_bt + || &bootmgr_contents[index..index+win_nt_bt.len()] == win_nt_bt_caps { + println!("BOOTMGR: {index:#010x} Patching {:?} --> \"amd64\"", bootmgr_contents[index..index+win_nt_bt.len()].to_vec()); + for i in 0..amd64_bytes.len() { + bootmgr_contents[index+i] = amd64_bytes[i]; + } + bootmgr_contents[index + amd64_bytes.len()] = 0; + bootmgr_contents[index + amd64_bytes.len()] = bootmgr_contents[index + win_nt_bt.len()]; + bootmgr_contents[index + amd64_bytes.len() + 1] = 0; + } + } + + println!("Writing {bootmgr_copy:?}"); + bootmgr_copy.write_all(bootmgr_contents.as_slice()).expect("Couldn't write to BOOTMGR"); + } + + println!("Done! :D"); +}