From f3d54eb6522eee991ed4ca7667430fe6c97bd54a Mon Sep 17 00:00:00 2001 From: Brian Allred Date: Tue, 19 May 2026 15:00:48 -0500 Subject: [PATCH] Fix crash when creating missing folders --- switch/src/lib.rs | 45 ++++++++++++++++++++++++++++---------- switch/src/stage_config.rs | 5 +++-- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/switch/src/lib.rs b/switch/src/lib.rs index 29f36c6..60d451b 100644 --- a/switch/src/lib.rs +++ b/switch/src/lib.rs @@ -22,6 +22,32 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); static WEB_DIR: Dir = include_dir!("./web-build/renderer"); +// Workaround for a crash in ::_create +pub fn mkdir_p>(path: P) -> std::result::Result<(), String> { + let path = path.as_ref(); + if path.exists() { + return Ok(()); + } + let mut to_create: Vec = Vec::new(); + let mut cur: Option<&Path> = Some(path); + while let Some(p) = cur { + if p.exists() { + break; + } + to_create.push(p.to_path_buf()); + cur = p.parent(); + } + while let Some(p) = to_create.pop() { + if p.exists() { + continue; + } + if std::fs::create_dir(&p).is_err() && !p.exists() { + return Err(format!("failed to create directory: {}", p.display())); + } + } + Ok(()) +} + pub fn is_emulator() -> bool { let text_addr = unsafe { skyline::hooks::getRegionAddress(skyline::hooks::Region::Text) as u64 }; text_addr == 0x8504000 || text_addr == 0x80004000 @@ -76,7 +102,7 @@ pub fn check_for_self_updates() { return; } if std::fs::metadata("sd:/downloads").is_err() { - std::fs::create_dir_all("sd:/downloads"); + let _ = mkdir_p("sd:/downloads"); } match Curler::new().download( "https://github.com/techyCoder81/hdr-launcher-react/releases/latest/download/hdr-launcher.nro".to_owned(), @@ -90,7 +116,6 @@ pub fn check_for_self_updates() { return; }, }; - println!("finished get"); match std::fs::copy("sd:/downloads/hdr-launcher.nro.dl", "sd:/atmosphere/contents/01006A800016E000/romfs/skyline/plugins/hdr-launcher.nro") { Ok(_) => println!("new update installed!"), @@ -120,13 +145,11 @@ pub fn main() { println!("starting browser!"); let browser_thread = thread::spawn(move || { - unsafe { extern "C" { #[link_name = "_ZN2nn2oe24SetExpectedVolumeBalanceEff"] fn set_volume_balance(applet: f32, system: f32); } - set_volume_balance(0.5, 1.0); } @@ -162,7 +185,6 @@ pub fn main() { }; let assets = manifest.as_object().unwrap(); - let mut files: HashMap = HashMap::new(); // for each asset, add it to the webpage @@ -183,7 +205,7 @@ pub fn main() { let folder_path = Path::new("sd:/atmosphere/contents") .join(&format!("{:016X}", program_id)) .join(&format!("manual_html/html-document/{}.htdocs/", htdocs_dir)); - + // remove previous files if necessary if std::fs::metadata(&folder_path).is_ok() { std::fs::remove_dir_all(&folder_path); @@ -200,9 +222,9 @@ pub fn main() { page.file(key, contents); let fullpath = Path::join(&folder_path, key); println!("adding file: {}", fullpath.display()); - match fs::create_dir_all(fullpath.parent().unwrap()) { + match mkdir_p(fullpath.parent().unwrap()) { Ok(_) => {}, - Err(e) => {println!("Error while making file path: {:?}", e); return;} + Err(e) => {println!("Error while making file path: {}", e); return;} } } @@ -288,7 +310,7 @@ pub fn main() { Err(e) => return Err(format!("Error while removing existing {}: {}", &dest_mod, e.to_string())) } } - + // create a new pr folder match fs::create_dir(&dest) { Ok(()) => {}, @@ -328,7 +350,7 @@ pub fn main() { Ok(_) => {}, Err(e) => return Err(format!("Error while handling path: {}", path.display())) }, - false => match std::fs::create_dir_all(pr_path) { + false => match mkdir_p(&pr_path) { Ok(_) => {}, Err(e) => return Err(format!("Error while handling path: {}", path.display())) } @@ -344,7 +366,6 @@ pub fn main() { } }) .start(); - }); // End thread so match can actually start @@ -367,4 +388,4 @@ pub fn try_open_arcropolis() { println!("Error: We cannot open arcrop because arcrop is out of date!"); skyline_web::DialogOk::ok("Error: Cannot open arcropolis menu because your arcropolis is out of date! You may want to update in the launcher."); } -} \ No newline at end of file +} diff --git a/switch/src/stage_config.rs b/switch/src/stage_config.rs index f40977d..f2b8931 100644 --- a/switch/src/stage_config.rs +++ b/switch/src/stage_config.rs @@ -1,6 +1,7 @@ use std::path::Path; use std::fs::OpenOptions; use std::io::prelude::*; +use crate::mkdir_p; const FILE_PATH: &str = "sd:/ultimate/mods/hdr-stages/ui/param/database/ui_stage_db.prcxml"; @@ -90,9 +91,9 @@ pub fn new_temp_file() -> Result { }; } - match std::fs::create_dir_all(CONFIG_PATH) { + match mkdir_p(CONFIG_PATH) { Ok(()) => (), - Err(e) => return Err(format!("error creating config paths: {:?}", e)) + Err(e) => return Err(format!("error creating config paths: {}", e)) }; return match std::fs::write(STAGING_FILE, "") { Ok(()) => Ok("file created successfully.".to_string()),