1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-26 14:17:45 +00:00

Make install_game no longer unsafe, propagates errors

This commit is contained in:
Joshua Goins 2022-08-09 23:39:31 -04:00
parent 6f9b5c59d7
commit 642cb94896

View file

@ -1,4 +1,4 @@
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString, NulError};
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@ -46,8 +46,25 @@ extern "C" {
fn unshield_file_save(unshield: *mut Unshield, index : i32, filename: *const c_char) -> bool; fn unshield_file_save(unshield: *mut Unshield, index : i32, filename: *const c_char) -> bool;
} }
pub enum InstallError {
IOFailure,
FFIFailure
}
impl From<std::io::Error> for InstallError {
fn from(_: std::io::Error) -> Self {
InstallError::IOFailure
}
}
impl From<NulError> for InstallError {
fn from(_: NulError) -> Self {
InstallError::FFIFailure
}
}
/// Installs the game from the provided retail installer. /// Installs the game from the provided retail installer.
pub unsafe fn install_game(installer_path : &str, game_directory : &str) { pub fn install_game(installer_path : &str, game_directory : &str) -> Result<(), InstallError> {
let installer_file = fs::read(installer_path).unwrap(); let installer_file = fs::read(installer_path).unwrap();
let mut last_position = 0; let mut last_position = 0;
@ -66,9 +83,9 @@ pub unsafe fn install_game(installer_path : &str, game_directory : &str) {
let mut new_file = File::create(last_filename).unwrap(); let mut new_file = File::create(last_filename).unwrap();
if last_filename == "data1.hdr" { if last_filename == "data1.hdr" {
new_file.write(&installer_file[last_position + 30..position - 42]); new_file.write(&installer_file[last_position + 30..position - 42])?;
} else { } else {
new_file.write(&installer_file[last_position + 33..position - 42]); new_file.write(&installer_file[last_position + 33..position - 42])?;
} }
} }
@ -78,35 +95,39 @@ pub unsafe fn install_game(installer_path : &str, game_directory : &str) {
let mut new_file = File::create(last_filename).unwrap(); let mut new_file = File::create(last_filename).unwrap();
new_file.write(&installer_file[last_position + 33..installer_file.len() - 42]); new_file.write(&installer_file[last_position + 33..installer_file.len() - 42])?;
fs::create_dir_all(format!("{game_directory}/boot")); fs::create_dir_all(format!("{game_directory}/boot"))?;
fs::create_dir_all(format!("{game_directory}/game")); fs::create_dir_all(format!("{game_directory}/game"))?;
// set unshield to shut up // set unshield to shut up
unshield_set_log_level(0); unsafe { unshield_set_log_level(0) };
let unshield = unshield_open(b"data1.cab".as_ptr() as *const c_char); let unshield = unsafe { unshield_open(b"data1.cab".as_ptr() as *const c_char) };
let file_count = unshield_file_count(unshield); let file_count = unsafe { unshield_file_count(unshield) };
for i in 0..file_count { for i in 0..file_count {
let filename = CStr::from_ptr(unshield_file_name(unshield, i)).to_string_lossy(); let filename = unsafe { CStr::from_ptr(unshield_file_name(unshield, i)).to_string_lossy() };
for boot_name in BOOT_COMPONENT_FILES { for boot_name in BOOT_COMPONENT_FILES {
if boot_name == filename { if boot_name == filename {
let save_filename = format!("{game_directory}/boot/{boot_name}"); let save_filename = format!("{game_directory}/boot/{boot_name}");
unshield_file_save(unshield, i, CString::new(save_filename).unwrap().as_ptr()); let save_filename_c = CString::new(save_filename)?;
unsafe { unshield_file_save(unshield, i, save_filename_c.as_ptr()) };
} }
} }
for game_name in GAME_COMPONENT_FILES { for game_name in GAME_COMPONENT_FILES {
if game_name == filename { if game_name == filename {
let save_filename = format!("{game_directory}/game/{game_name}"); let save_filename = format!("{game_directory}/game/{game_name}");
unshield_file_save(unshield, i, CString::new(save_filename).unwrap().as_ptr()); let save_filename_c = CString::new(save_filename)?;
unsafe { unshield_file_save(unshield, i, save_filename_c.as_ptr()) };
} }
} }
} }
unshield_close(unshield); unsafe { unshield_close(unshield); }
Ok(())
} }