From d73b008754596723e53eefeea5801c41aae54cfc Mon Sep 17 00:00:00 2001 From: XorTroll Date: Tue, 9 Dec 2025 19:45:50 +0100 Subject: [PATCH 1/5] Derive Debug on some NFP enums --- src/ipc/sf/nfp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipc/sf/nfp.rs b/src/ipc/sf/nfp.rs index 1c154a76..18a0e481 100755 --- a/src/ipc/sf/nfp.rs +++ b/src/ipc/sf/nfp.rs @@ -27,14 +27,14 @@ pub struct DeviceHandle { } const_assert!(core::mem::size_of::() == 0x8); -#[derive(Request, Response, Copy, Clone, PartialEq, Eq)] +#[derive(Request, Response, Copy, Clone, PartialEq, Eq, Debug)] #[repr(u32)] pub enum State { NonInitialized = 0, Initialized = 1, } -#[derive(Request, Response, Copy, Clone, PartialEq, Eq)] +#[derive(Request, Response, Copy, Clone, PartialEq, Eq, Debug)] #[repr(u32)] pub enum DeviceState { Initialized = 0, From e35f6b14488d12fcf416cc15417893103b096a3b Mon Sep 17 00:00:00 2001 From: XorTroll Date: Tue, 9 Dec 2025 19:46:11 +0100 Subject: [PATCH 2/5] Correct some SVC comments --- src/svc.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/svc.rs b/src/svc.rs index 5f046d84..e0e3422e 100755 --- a/src/svc.rs +++ b/src/svc.rs @@ -828,7 +828,7 @@ pub fn send_sync_request_light(handle: Handle) -> Result<()> { } } -/// Sends an IPC synchronization request to a session. +/// Sends a synchronous IPC request to a session. #[inline(always)] pub fn send_sync_request(handle: Handle) -> Result<()> { unsafe { @@ -837,7 +837,7 @@ pub fn send_sync_request(handle: Handle) -> Result<()> { } } -/// Sends an IPC synchronization request to a session from an user allocated buffer. +/// Sends a synchronous IPC request to a session from an user allocated buffer. /// /// The buffer size must be a multiple of the system page size (0x1000). #[inline(always)] @@ -848,7 +848,7 @@ pub unsafe fn send_sync_request_with_user_data(buffer: &mut [u8], handle: Handle } } -/// Sends an IPC synchronization request to a session from an user allocated buffer (asynchronous version). +/// Sends an asynchronous IPC request to a session from an user allocated buffer . /// /// The buffer size must be a multiple of the system page size (0x1000). #[inline(always)] From d71d3486f7d6b3f8d524e98fde2e2c35738375fa Mon Sep 17 00:00:00 2001 From: XorTroll Date: Tue, 9 Dec 2025 19:46:29 +0100 Subject: [PATCH 3/5] Fix some IPC server mistakes --- src/ipc/server.rs | 20 +++++++++++++------- src/ipc/sf.rs | 3 +-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ipc/server.rs b/src/ipc/server.rs index a504f73a..1e886d48 100755 --- a/src/ipc/server.rs +++ b/src/ipc/server.rs @@ -511,18 +511,24 @@ impl ServerHolder { #[cfg(feature = "services")] { let mut sm = service::new_named_port_object::()?; - match (self.is_mitm_service, self.handle_type) { - (true, WaitHandleType::Server) => { + + if self.handle_type == WaitHandleType::Server { + if self.is_mitm_service { debug_assert!( self.info.owns_handle, "MitM server objects should always own their handles." ); sm.atmosphere_uninstall_mitm(self.service_name)?; - sf::Session::from(self.mitm_forward_info).close(); } - (false, _) => sm.unregister_service(self.service_name)?, - _ => {} - }; + else { + sm.unregister_service(self.service_name)?; + } + } + + if self.is_mitm_service { + sf::Session::from(self.mitm_forward_info).close(); + } + sm.detach_client(sf::ProcessId::new())?; } } @@ -698,7 +704,7 @@ impl ServerManager

{ let mut handles_index: usize = 0; for server_holder in &mut self.server_holders { let server_info = server_holder.info; - if server_info.handle != 0 { + if server_info.handle != svc::INVALID_HANDLE { self.wait_handles[handles_index] = server_info.handle; handles_index += 1; } diff --git a/src/ipc/sf.rs b/src/ipc/sf.rs index 83965277..d926a2cb 100755 --- a/src/ipc/sf.rs +++ b/src/ipc/sf.rs @@ -333,7 +333,6 @@ impl< } impl< - const IN: bool, const MAP_ALIAS: bool, const POINTER: bool, const FIXED_SIZE: bool, @@ -344,7 +343,7 @@ impl< > Buffer< '_, - IN, + true, true, MAP_ALIAS, POINTER, From 4619f6f63a73ed16146d1755ffe3cd6a1c7a6c11 Mon Sep 17 00:00:00 2001 From: XorTroll Date: Sun, 21 Dec 2025 13:18:36 +0100 Subject: [PATCH 4/5] Finally fix MitM server issues --- src/ipc/server.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ipc/server.rs b/src/ipc/server.rs index 1e886d48..def75830 100755 --- a/src/ipc/server.rs +++ b/src/ipc/server.rs @@ -464,7 +464,7 @@ impl ServerHolder { new_mitm_server_fn: self.new_mitm_server_fn, handle_type: WaitHandleType::Session, mitm_forward_info: mitm_fwd_info, - is_mitm_service: forward_handle != 0, + is_mitm_service: forward_handle != svc::INVALID_HANDLE, service_name: sm::ServiceName::empty(), domain_table: self.domain_table.clone(), }) @@ -525,14 +525,15 @@ impl ServerHolder { } } - if self.is_mitm_service { - sf::Session::from(self.mitm_forward_info).close(); - } - sm.detach_client(sf::ProcessId::new())?; } } + // Forward info may be valid despite having an empty service name (like a cloned session) + if self.is_mitm_service { + sf::Session::from(self.mitm_forward_info).close(); + } + // Don't close our session like a normal one (like the forward session below) as we allocated the object IDs ourselves, the only thing we do have to close is the handle if self.info.owns_handle { svc::close_handle(self.info.handle)?; From 626318e3055cb0396d73819064e4be6b79d2c430 Mon Sep 17 00:00:00 2001 From: XorTroll Date: Sun, 21 Dec 2025 13:43:45 +0100 Subject: [PATCH 5/5] Fix support with last Rust nightly changes --- src/ipc/server.rs | 3 +-- src/thread.rs | 20 ++++++++++---------- src/thread/scoped.rs | 8 ++++---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ipc/server.rs b/src/ipc/server.rs index def75830..08890d15 100755 --- a/src/ipc/server.rs +++ b/src/ipc/server.rs @@ -519,8 +519,7 @@ impl ServerHolder { "MitM server objects should always own their handles." ); sm.atmosphere_uninstall_mitm(self.service_name)?; - } - else { + } else { sm.unregister_service(self.service_name)?; } } diff --git a/src/thread.rs b/src/thread.rs index a0cc1370..3fae0206 100755 --- a/src/thread.rs +++ b/src/thread.rs @@ -292,23 +292,23 @@ impl Builder { f: F, ) -> crate::result::Result> where - F: FnOnce() -> T, + F: FnOnce() -> T + 'static, F: Send, - T: Send, + T: Send + 'static, { Ok(JoinHandle(unsafe { self.spawn_unchecked_(f, None) }?)) } #[allow(unsafe_op_in_unsafe_fn)] - unsafe fn spawn_unchecked_<'scope, F, T>( + unsafe fn spawn_unchecked_( self, f: F, scope_data: Option>, - ) -> crate::result::Result> + ) -> crate::result::Result> where - F: FnOnce() -> T, + F: FnOnce() -> T + 'static, F: Send, - T: Send, + T: Send + 'static, { let Builder { name, @@ -327,7 +327,7 @@ impl Builder { let my_thread = Thread::new_inner(name); let _their_thread = my_thread.clone(); - let my_packet: Arc> = Arc::new(Packet { + let my_packet: Arc> = Arc::new(Packet { scope: scope_data, result: UnsafeCell::new(None), _marker: PhantomData, @@ -370,7 +370,7 @@ impl Builder { // will call `decrement_num_running_threads` and therefore signal that this thread is // done. drop(their_packet); - // Here, the lifetime `'scope` can end. `main` keeps running for a bit + // Here, the lifetime `'static` can end. `main` keeps running for a bit // after that before returning itself. }; @@ -803,9 +803,9 @@ impl Drop for Packet<'_, T> { // Book-keeping so the scope knows when it's done. if let Some(scope) = &self.scope { // Now that there will be no more user code running on this thread - // that can use 'scope, mark the thread as 'finished'. + // that can use 'static, mark the thread as 'finished'. // It's important we only do this after the `result` has been dropped, - // since dropping it might still use things it borrowed from 'scope. + // since dropping it might still use things it borrowed from 'static. scope.decrement_num_running_threads(unhandled_panic); } } diff --git a/src/thread/scoped.rs b/src/thread/scoped.rs index 07bf73e9..1350ee44 100755 --- a/src/thread/scoped.rs +++ b/src/thread/scoped.rs @@ -189,8 +189,8 @@ impl<'scope> Scope<'scope, '_> { /// [`join`]: ScopedJoinHandle::join pub fn spawn(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> where - F: FnOnce() -> T + Send + 'scope, - T: Send + 'scope, + F: FnOnce() -> T + Send + 'scope + 'static, + T: Send + 'scope + 'static, { Builder::new() .spawn_scoped(self, f) @@ -251,8 +251,8 @@ impl Builder { f: F, ) -> crate::result::Result> where - F: FnOnce() -> T + Send + 'scope, - T: Send + 'scope, + F: FnOnce() -> T + Send + 'scope + 'static, + T: Send + 'scope + 'static, { Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(f, Some(scope.data.clone()))