From 7da735f141634c626532413e6ad86bc1973854d4 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Thu, 23 Oct 2025 12:29:59 -0600 Subject: [PATCH] Rewrite async runtime handling and port to tracing --- Cargo.lock | 22 +++++++++++ ffi/Cargo.toml | 1 + ffi/src/adapter.rs | 14 +++---- ffi/src/afc.rs | 31 +++++++++------- ffi/src/amfi.rs | 12 +++--- ffi/src/core_device/app_service.rs | 18 ++++----- ffi/src/core_device/diagnosticsservice.rs | 12 +++--- ffi/src/core_device_proxy.rs | 15 +++++--- ffi/src/debug_proxy.rs | 18 ++++----- ffi/src/dvt/location_simulation.rs | 8 ++-- ffi/src/dvt/process_control.rs | 10 ++--- ffi/src/dvt/remote_server.rs | 6 +-- ffi/src/dvt/screenshot.rs | 6 +-- ffi/src/heartbeat.rs | 10 +++-- ffi/src/installation_proxy.rs | 24 ++++++------ ffi/src/lib.rs | 45 ++++++++++++++++++++--- ffi/src/lockdown.rs | 12 +++--- ffi/src/logging.rs | 45 +++++++++++++++-------- ffi/src/misagent.rs | 10 ++--- ffi/src/mobile_image_mounter.rs | 34 +++++++++-------- ffi/src/os_trace_relay.rs | 11 +++--- ffi/src/provider.rs | 4 +- ffi/src/rsd.rs | 4 +- ffi/src/springboardservices.rs | 9 +++-- ffi/src/syslog_relay.rs | 6 +-- ffi/src/tcp_object_stack.rs | 10 ++--- ffi/src/usbmuxd.rs | 22 +++++------ idevice/src/services/dvt/message.rs | 15 +++++++- 28 files changed, 267 insertions(+), 167 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c670922..bf0814c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -1085,6 +1094,7 @@ dependencies = [ "plist_ffi", "tokio", "tracing", + "tracing-appender", "tracing-subscriber", "ureq", "uuid", @@ -2515,6 +2525,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror 1.0.69", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.30" diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index d6d78bd..a651654 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -9,6 +9,7 @@ idevice = { path = "../idevice", default-features = false } futures = { version = "0.3", optional = true } tracing = { version = "0.1.41" } tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } +tracing-appender = { version = "0.2" } once_cell = "1.21.1" tokio = { version = "1.44.1", features = ["full"] } libc = "0.2.171" diff --git a/ffi/src/adapter.rs b/ffi/src/adapter.rs index eec1753..675e38c 100644 --- a/ffi/src/adapter.rs +++ b/ffi/src/adapter.rs @@ -7,7 +7,7 @@ use idevice::tcp::handle::StreamHandle; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::core_device_proxy::AdapterHandle; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync}; pub struct AdapterStreamHandle(pub StreamHandle); @@ -36,7 +36,7 @@ pub unsafe extern "C" fn adapter_connect( } let adapter = unsafe { &mut (*adapter_handle).0 }; - let res = RUNTIME.block_on(async move { adapter.connect(port).await }); + let res = run_sync(async move { adapter.connect(port).await }); match res { Ok(r) => { @@ -81,7 +81,7 @@ pub unsafe extern "C" fn adapter_pcap( Err(_) => return ffi_err!(IdeviceError::FfiInvalidString), }; - let res = RUNTIME.block_on(async move { adapter.pcap(path_str).await }); + let res = run_sync(async move { adapter.pcap(path_str).await }); match res { Ok(_) => null_mut(), @@ -111,7 +111,7 @@ pub unsafe extern "C" fn adapter_stream_close( } let adapter = unsafe { &mut (*handle).0 }; - RUNTIME.block_on(async move { adapter.close() }); + run_sync(async move { adapter.close() }); null_mut() } @@ -133,7 +133,7 @@ pub unsafe extern "C" fn adapter_close(handle: *mut AdapterHandle) -> *mut Idevi } let adapter = unsafe { &mut (*handle).0 }; - RUNTIME.block_on(async move { adapter.close().await.ok() }); + run_sync(async move { adapter.close().await.ok() }); null_mut() } @@ -164,7 +164,7 @@ pub unsafe extern "C" fn adapter_send( let adapter = unsafe { &mut (*handle).0 }; let data_slice = unsafe { std::slice::from_raw_parts(data, length) }; - let res = RUNTIME.block_on(async move { adapter.write_all(data_slice).await }); + let res = run_sync(async move { adapter.write_all(data_slice).await }); match res { Ok(_) => null_mut(), @@ -202,7 +202,7 @@ pub unsafe extern "C" fn adapter_recv( } let adapter = unsafe { &mut (*handle).0 }; - let res: Result, std::io::Error> = RUNTIME.block_on(async move { + let res: Result, std::io::Error> = run_sync(async move { let mut buf = [0; 2048]; let res = adapter.read(&mut buf).await?; Ok(buf[..res].to_vec()) diff --git a/ffi/src/afc.rs b/ffi/src/afc.rs index bf0ca7a..4f1d3ab 100644 --- a/ffi/src/afc.rs +++ b/ffi/src/afc.rs @@ -8,7 +8,10 @@ use idevice::{ provider::IdeviceProvider, }; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, LOCAL_RUNTIME, ffi_err, provider::IdeviceProviderHandle, + run_sync, run_sync_local, +}; pub struct AfcClientHandle(pub AfcClient); @@ -34,7 +37,7 @@ pub unsafe extern "C" fn afc_client_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; AfcClient::connect(provider_ref).await @@ -122,7 +125,7 @@ pub unsafe extern "C" fn afc_list_directory( // Use to_string_lossy to handle non-UTF8 paths let path = path_cstr.to_string_lossy(); - let res: Result, IdeviceError> = RUNTIME.block_on(async move { + let res: Result, IdeviceError> = run_sync_local(async move { // SAFETY: We're assuming client is a valid pointer here let client_ref = unsafe { &mut (*client).0 }; client_ref.list_dir(&path.to_string()).await @@ -194,7 +197,7 @@ pub unsafe extern "C" fn afc_make_directory( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.mk_dir(path).await }); @@ -246,7 +249,7 @@ pub unsafe extern "C" fn afc_get_file_info( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.get_file_info(path).await }); @@ -331,7 +334,7 @@ pub unsafe extern "C" fn afc_get_device_info( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.get_device_info().await }); @@ -395,7 +398,7 @@ pub unsafe extern "C" fn afc_remove_path( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.remove(path).await }); @@ -433,7 +436,7 @@ pub unsafe extern "C" fn afc_remove_path_and_contents( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.remove_all(path).await }); @@ -506,7 +509,7 @@ pub unsafe extern "C" fn afc_file_open( let mode = mode.into(); - let res: Result<*mut AfcFileHandle, IdeviceError> = RUNTIME.block_on(async move { + let res: Result<*mut AfcFileHandle, IdeviceError> = LOCAL_RUNTIME.block_on(async move { let client_ref = unsafe { &mut (*client).0 }; let result = client_ref.open(path, mode).await; match result { @@ -544,7 +547,7 @@ pub unsafe extern "C" fn afc_file_close(handle: *mut AfcFileHandle) -> *mut Idev } let fd = unsafe { Box::from_raw(handle as *mut idevice::afc::file::FileDescriptor) }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { fd.close().await }); + let res: Result<(), IdeviceError> = run_sync(async move { fd.close().await }); match res { Ok(_) => null_mut(), @@ -575,7 +578,7 @@ pub unsafe extern "C" fn afc_file_read( } let fd = unsafe { &mut *(handle as *mut idevice::afc::file::FileDescriptor) }; - let res: Result, IdeviceError> = RUNTIME.block_on(async move { fd.read().await }); + let res: Result, IdeviceError> = run_sync(async move { fd.read().await }); match res { Ok(bytes) => { @@ -617,7 +620,7 @@ pub unsafe extern "C" fn afc_file_write( let fd = unsafe { &mut *(handle as *mut idevice::afc::file::FileDescriptor) }; let data_slice = unsafe { std::slice::from_raw_parts(data, length) }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { fd.write(data_slice).await }); + let res: Result<(), IdeviceError> = run_sync(async move { fd.write(data_slice).await }); match res { Ok(_) => null_mut(), @@ -674,7 +677,7 @@ pub unsafe extern "C" fn afc_make_link( AfcLinkType::Symbolic => idevice::afc::opcode::LinkType::Symlink, }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.link(target, source, link_type).await }); @@ -720,7 +723,7 @@ pub unsafe extern "C" fn afc_rename_path( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.rename(source, target).await }); diff --git a/ffi/src/amfi.rs b/ffi/src/amfi.rs index f23d89d..3a5b098 100644 --- a/ffi/src/amfi.rs +++ b/ffi/src/amfi.rs @@ -4,7 +4,9 @@ use std::ptr::null_mut; use idevice::{IdeviceError, IdeviceService, amfi::AmfiClient, provider::IdeviceProvider}; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync_local, +}; pub struct AmfiClientHandle(pub AmfiClient); @@ -30,7 +32,7 @@ pub unsafe extern "C" fn amfi_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; // Connect using the reference @@ -94,7 +96,7 @@ pub unsafe extern "C" fn amfi_reveal_developer_mode_option_in_ui( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.reveal_developer_mode_option_in_ui().await }); @@ -122,7 +124,7 @@ pub unsafe extern "C" fn amfi_enable_developer_mode( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.enable_developer_mode().await }); @@ -150,7 +152,7 @@ pub unsafe extern "C" fn amfi_accept_developer_mode( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.accept_developer_mode().await }); diff --git a/ffi/src/core_device/app_service.rs b/ffi/src/core_device/app_service.rs index 6078635..aa0bfe3 100644 --- a/ffi/src/core_device/app_service.rs +++ b/ffi/src/core_device/app_service.rs @@ -9,7 +9,7 @@ use idevice::{IdeviceError, ReadWrite, RsdService}; use crate::core_device_proxy::AdapterHandle; use crate::rsd::RsdHandshakeHandle; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync, run_sync_local}; /// Opaque handle to an AppServiceClient pub struct AppServiceHandle(pub AppServiceClient>); @@ -91,7 +91,7 @@ pub unsafe extern "C" fn app_service_connect_rsd( } let res: Result>, IdeviceError> = - RUNTIME.block_on(async move { + run_sync_local(async move { let provider_ref = unsafe { &mut (*provider).0 }; let handshake_ref = unsafe { &mut (*handshake).0 }; @@ -130,7 +130,7 @@ pub unsafe extern "C" fn app_service_new( } let socket = unsafe { Box::from_raw(socket) }; - let res = RUNTIME.block_on(async move { AppServiceClient::new(socket.inner.unwrap()).await }); + let res = run_sync(async move { AppServiceClient::new(socket.inner.unwrap()).await }); match res { Ok(client) => { @@ -186,7 +186,7 @@ pub unsafe extern "C" fn app_service_list_apps( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { + let res = run_sync(async move { client .list_apps( app_clips != 0, @@ -347,7 +347,7 @@ pub unsafe extern "C" fn app_service_launch_app( }; let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { + let res = run_sync(async move { client .launch_application( bundle_id_str, @@ -430,7 +430,7 @@ pub unsafe extern "C" fn app_service_list_processes( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.list_processes().await }); + let res = run_sync(async move { client.list_processes().await }); match res { Ok(process_list) => { @@ -513,7 +513,7 @@ pub unsafe extern "C" fn app_service_uninstall_app( }; let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.uninstall_app(bundle_id_str).await }); + let res = run_sync(async move { client.uninstall_app(bundle_id_str).await }); match res { Ok(_) => null_mut(), @@ -546,7 +546,7 @@ pub unsafe extern "C" fn app_service_send_signal( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.send_signal(pid, signal).await }); + let res = run_sync(async move { client.send_signal(pid, signal).await }); match res { Ok(signal_response) => { @@ -628,7 +628,7 @@ pub unsafe extern "C" fn app_service_fetch_app_icon( }; let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { + let res = run_sync(async move { client .fetch_app_icon(bundle_id_str, width, height, scale, allow_placeholder != 0) .await diff --git a/ffi/src/core_device/diagnosticsservice.rs b/ffi/src/core_device/diagnosticsservice.rs index af3b003..2fe9ecc 100644 --- a/ffi/src/core_device/diagnosticsservice.rs +++ b/ffi/src/core_device/diagnosticsservice.rs @@ -11,7 +11,7 @@ use tracing::debug; use crate::core_device_proxy::AdapterHandle; use crate::rsd::RsdHandshakeHandle; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync, run_sync_local}; /// Opaque handle to an AppServiceClient pub struct DiagnosticsServiceHandle(pub DiagnostisServiceClient>); @@ -43,7 +43,7 @@ pub unsafe extern "C" fn diagnostics_service_connect_rsd( } let res: Result>, IdeviceError> = - RUNTIME.block_on(async move { + run_sync_local(async move { let provider_ref = unsafe { &mut (*provider).0 }; let handshake_ref = unsafe { &mut (*handshake).0 }; debug!( @@ -87,8 +87,8 @@ pub unsafe extern "C" fn diagnostics_service_new( } let socket = unsafe { Box::from_raw(socket) }; - let res = RUNTIME - .block_on(async move { DiagnostisServiceClient::from_stream(socket.inner.unwrap()).await }); + let res = + run_sync(async move { DiagnostisServiceClient::from_stream(socket.inner.unwrap()).await }); match res { Ok(client) => { @@ -134,7 +134,7 @@ pub unsafe extern "C" fn diagnostics_service_capture_sysdiagnose( return ffi_err!(IdeviceError::FfiInvalidArg); } let handle = unsafe { &mut *handle }; - let res = RUNTIME.block_on(async move { handle.0.capture_sysdiagnose(dry_run).await }); + let res = run_sync_local(async move { handle.0.capture_sysdiagnose(dry_run).await }); match res { Ok(res) => { let filename = CString::new(res.preferred_filename).unwrap(); @@ -172,7 +172,7 @@ pub unsafe extern "C" fn sysdiagnose_stream_next( return ffi_err!(IdeviceError::FfiInvalidArg); } let handle = unsafe { &mut *handle }; - let res = RUNTIME.block_on(async move { handle.0.next().await }); + let res = run_sync_local(async move { handle.0.next().await }); match res { Some(Ok(res)) => { let mut res = res.into_boxed_slice(); diff --git a/ffi/src/core_device_proxy.rs b/ffi/src/core_device_proxy.rs index 902ee7b..15a74b7 100644 --- a/ffi/src/core_device_proxy.rs +++ b/ffi/src/core_device_proxy.rs @@ -9,7 +9,10 @@ use idevice::{ IdeviceError, IdeviceService, core_device_proxy::CoreDeviceProxy, provider::IdeviceProvider, }; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync, + run_sync_local, +}; pub struct CoreDeviceProxyHandle(pub CoreDeviceProxy); pub struct AdapterHandle(pub idevice::tcp::handle::AdapterHandle); @@ -36,7 +39,7 @@ pub unsafe extern "C" fn core_device_proxy_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; // Connect using the reference @@ -76,7 +79,7 @@ pub unsafe extern "C" fn core_device_proxy_new( } let socket = unsafe { Box::from_raw(socket) }.0; let r: Result = - RUNTIME.block_on(async move { CoreDeviceProxy::new(socket).await }); + run_sync(async move { CoreDeviceProxy::new(socket).await }); match r { Ok(r) => { let boxed = Box::new(CoreDeviceProxyHandle(r)); @@ -113,7 +116,7 @@ pub unsafe extern "C" fn core_device_proxy_send( let proxy = unsafe { &mut (*handle).0 }; let data_slice = unsafe { std::slice::from_raw_parts(data, length) }; - let res = RUNTIME.block_on(async move { proxy.send(data_slice).await }); + let res = run_sync(async move { proxy.send(data_slice).await }); match res { Ok(_) => null_mut(), @@ -149,7 +152,7 @@ pub unsafe extern "C" fn core_device_proxy_recv( let proxy = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { proxy.recv().await }); + let res = run_sync(async move { proxy.recv().await }); match res { Ok(received_data) => { @@ -312,7 +315,7 @@ pub unsafe extern "C" fn core_device_proxy_create_tcp_adapter( match result { Ok(adapter_obj) => { // We have to run this in the RUNTIME since we're spawning a new thread - let adapter_handle = RUNTIME.block_on(async move { adapter_obj.to_async_handle() }); + let adapter_handle = run_sync(async move { adapter_obj.to_async_handle() }); let boxed = Box::new(AdapterHandle(adapter_handle)); unsafe { *adapter = Box::into_raw(boxed) }; diff --git a/ffi/src/debug_proxy.rs b/ffi/src/debug_proxy.rs index 8d7152a..38b89c6 100644 --- a/ffi/src/debug_proxy.rs +++ b/ffi/src/debug_proxy.rs @@ -9,7 +9,7 @@ use idevice::{IdeviceError, ReadWrite, RsdService}; use crate::core_device_proxy::AdapterHandle; use crate::rsd::RsdHandshakeHandle; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync, run_sync_local}; /// Opaque handle to a DebugProxyClient pub struct DebugProxyHandle(pub DebugProxyClient>); @@ -136,7 +136,7 @@ pub unsafe extern "C" fn debug_proxy_connect_rsd( return ffi_err!(IdeviceError::FfiInvalidArg); } let res: Result>, IdeviceError> = - RUNTIME.block_on(async move { + run_sync_local(async move { let provider_ref = unsafe { &mut (*provider).0 }; let handshake_ref = unsafe { &mut (*handshake).0 }; @@ -241,7 +241,7 @@ pub unsafe extern "C" fn debug_proxy_send_command( }, }; - let res = RUNTIME.block_on(async move { client.send_command(cmd).await }); + let res = run_sync(async move { client.send_command(cmd).await }); match res { Ok(Some(r)) => { @@ -282,7 +282,7 @@ pub unsafe extern "C" fn debug_proxy_read_response( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.read_response().await }); + let res = run_sync(async move { client.read_response().await }); match res { Ok(Some(r)) => { @@ -326,7 +326,7 @@ pub unsafe extern "C" fn debug_proxy_send_raw( let client = unsafe { &mut (*handle).0 }; let data_slice = unsafe { std::slice::from_raw_parts(data, len) }; - let res = RUNTIME.block_on(async move { client.send_raw(data_slice).await }); + let res = run_sync(async move { client.send_raw(data_slice).await }); match res { Ok(_) => null_mut(), @@ -358,7 +358,7 @@ pub unsafe extern "C" fn debug_proxy_read( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.read(len).await }); + let res = run_sync(async move { client.read(len).await }); match res { Ok(r) => { @@ -416,7 +416,7 @@ pub unsafe extern "C" fn debug_proxy_set_argv( .collect() }; - let res = RUNTIME.block_on(async move { client.set_argv(argv_vec).await }); + let res = run_sync(async move { client.set_argv(argv_vec).await }); match res { Ok(r) => { @@ -450,7 +450,7 @@ pub unsafe extern "C" fn debug_proxy_send_ack( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.send_ack().await }); + let res = run_sync(async move { client.send_ack().await }); match res { Ok(_) => null_mut(), @@ -477,7 +477,7 @@ pub unsafe extern "C" fn debug_proxy_send_nack( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.send_noack().await }); + let res = run_sync(async move { client.send_noack().await }); match res { Ok(_) => null_mut(), diff --git a/ffi/src/dvt/location_simulation.rs b/ffi/src/dvt/location_simulation.rs index 2bd5488..5f8579e 100644 --- a/ffi/src/dvt/location_simulation.rs +++ b/ffi/src/dvt/location_simulation.rs @@ -4,7 +4,7 @@ use std::ptr::null_mut; use idevice::{ReadWrite, dvt::location_simulation::LocationSimulationClient}; -use crate::{IdeviceFfiError, RUNTIME, dvt::remote_server::RemoteServerHandle, ffi_err}; +use crate::{IdeviceFfiError, dvt::remote_server::RemoteServerHandle, ffi_err, run_sync}; /// Opaque handle to a ProcessControlClient pub struct LocationSimulationHandle<'a>(pub LocationSimulationClient<'a, Box>); @@ -31,7 +31,7 @@ pub unsafe extern "C" fn location_simulation_new( } let server = unsafe { &mut (*server).0 }; - let res = RUNTIME.block_on(async move { LocationSimulationClient::new(server).await }); + let res = run_sync(async move { LocationSimulationClient::new(server).await }); match res { Ok(client) => { @@ -76,7 +76,7 @@ pub unsafe extern "C" fn location_simulation_clear( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.clear().await }); + let res = run_sync(async move { client.clear().await }); match res { Ok(_) => null_mut(), @@ -107,7 +107,7 @@ pub unsafe extern "C" fn location_simulation_set( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.set(latitude, longitude).await }); + let res = run_sync(async move { client.set(latitude, longitude).await }); match res { Ok(_) => null_mut(), diff --git a/ffi/src/dvt/process_control.rs b/ffi/src/dvt/process_control.rs index f0bbce2..3b40f9e 100644 --- a/ffi/src/dvt/process_control.rs +++ b/ffi/src/dvt/process_control.rs @@ -8,7 +8,7 @@ use std::{ use idevice::{ReadWrite, dvt::process_control::ProcessControlClient}; use plist::{Dictionary, Value}; -use crate::{IdeviceFfiError, RUNTIME, dvt::remote_server::RemoteServerHandle, ffi_err}; +use crate::{IdeviceFfiError, dvt::remote_server::RemoteServerHandle, ffi_err, run_sync}; /// Opaque handle to a ProcessControlClient pub struct ProcessControlHandle<'a>(pub ProcessControlClient<'a, Box>); @@ -35,7 +35,7 @@ pub unsafe extern "C" fn process_control_new( } let server = unsafe { &mut (*server).0 }; - let res = RUNTIME.block_on(async move { ProcessControlClient::new(server).await }); + let res = run_sync(async move { ProcessControlClient::new(server).await }); match res { Ok(client) => { @@ -128,7 +128,7 @@ pub unsafe extern "C" fn process_control_launch_app( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { + let res = run_sync(async move { client .launch_app( bundle_id, @@ -170,7 +170,7 @@ pub unsafe extern "C" fn process_control_kill_app( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.kill_app(pid).await }); + let res = run_sync(async move { client.kill_app(pid).await }); match res { Ok(_) => null_mut(), @@ -199,7 +199,7 @@ pub unsafe extern "C" fn process_control_disable_memory_limit( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.disable_memory_limit(pid).await }); + let res = run_sync(async move { client.disable_memory_limit(pid).await }); match res { Ok(_) => null_mut(), diff --git a/ffi/src/dvt/remote_server.rs b/ffi/src/dvt/remote_server.rs index a9d3c54..ddab14a 100644 --- a/ffi/src/dvt/remote_server.rs +++ b/ffi/src/dvt/remote_server.rs @@ -4,7 +4,7 @@ use std::ptr::null_mut; use crate::core_device_proxy::AdapterHandle; use crate::rsd::RsdHandshakeHandle; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync, run_sync_local}; use idevice::dvt::remote_server::RemoteServerClient; use idevice::{IdeviceError, ReadWrite, RsdService}; @@ -37,7 +37,7 @@ pub unsafe extern "C" fn remote_server_new( let res: Result>, IdeviceError> = match wrapper.inner.take() { - Some(stream) => RUNTIME.block_on(async move { + Some(stream) => run_sync(async move { let mut client = RemoteServerClient::new(stream); client.read_message(0).await?; Ok(client) @@ -77,7 +77,7 @@ pub unsafe extern "C" fn remote_server_connect_rsd( return ffi_err!(IdeviceError::FfiInvalidArg); } let res: Result>, IdeviceError> = - RUNTIME.block_on(async move { + run_sync_local(async move { let provider_ref = unsafe { &mut (*provider).0 }; let handshake_ref = unsafe { &mut (*handshake).0 }; diff --git a/ffi/src/dvt/screenshot.rs b/ffi/src/dvt/screenshot.rs index 6c3848a..f8ef9f7 100644 --- a/ffi/src/dvt/screenshot.rs +++ b/ffi/src/dvt/screenshot.rs @@ -4,7 +4,7 @@ use std::ptr::null_mut; use idevice::{ReadWrite, dvt::screenshot::ScreenshotClient}; -use crate::{IdeviceFfiError, RUNTIME, dvt::remote_server::RemoteServerHandle, ffi_err}; +use crate::{IdeviceFfiError, dvt::remote_server::RemoteServerHandle, ffi_err, run_sync}; /// An opaque FFI handle for a [`ScreenshotClient`]. /// @@ -36,7 +36,7 @@ pub unsafe extern "C" fn screenshot_client_new( } let server = unsafe { &mut (*server).0 }; - let res = RUNTIME.block_on(async move { ScreenshotClient::new(server).await }); + let res = run_sync(async move { ScreenshotClient::new(server).await }); match res { Ok(client) => { @@ -96,7 +96,7 @@ pub unsafe extern "C" fn screenshot_client_take_screenshot( } let client = unsafe { &mut (*handle).0 }; - let res = RUNTIME.block_on(async move { client.take_screenshot().await }); + let res = run_sync(async move { client.take_screenshot().await }); match res { Ok(r) => { diff --git a/ffi/src/heartbeat.rs b/ffi/src/heartbeat.rs index bebe115..be6275a 100644 --- a/ffi/src/heartbeat.rs +++ b/ffi/src/heartbeat.rs @@ -6,7 +6,9 @@ use idevice::{ IdeviceError, IdeviceService, heartbeat::HeartbeatClient, provider::IdeviceProvider, }; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync_local, +}; pub struct HeartbeatClientHandle(pub HeartbeatClient); @@ -32,7 +34,7 @@ pub unsafe extern "C" fn heartbeat_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; // Connect using the reference HeartbeatClient::connect(provider_ref).await @@ -95,7 +97,7 @@ pub unsafe extern "C" fn heartbeat_send_polo( if client.is_null() { return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.send_polo().await }); @@ -126,7 +128,7 @@ pub unsafe extern "C" fn heartbeat_get_marco( if client.is_null() || new_interval.is_null() { return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.get_marco(interval).await }); diff --git a/ffi/src/installation_proxy.rs b/ffi/src/installation_proxy.rs index 079cb84..fff53c4 100644 --- a/ffi/src/installation_proxy.rs +++ b/ffi/src/installation_proxy.rs @@ -8,7 +8,9 @@ use idevice::{ }; use plist_ffi::{PlistWrapper, plist_t}; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync_local, +}; pub struct InstallationProxyClientHandle(pub InstallationProxyClient); @@ -34,7 +36,7 @@ pub unsafe extern "C" fn installation_proxy_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; InstallationProxyClient::connect(provider_ref).await }); @@ -134,7 +136,7 @@ pub unsafe extern "C" fn installation_proxy_get_apps( ) }; - let res: Result, IdeviceError> = RUNTIME.block_on(async { + let res: Result, IdeviceError> = run_sync_local(async { client.0.get_apps(app_type, bundle_ids).await.map(|apps| { apps.into_values() .map(|v| PlistWrapper::new_node(v).into_ptr()) @@ -210,7 +212,7 @@ pub unsafe extern "C" fn installation_proxy_install( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { unsafe { &mut *client } .0 .install(package_path, options) @@ -261,7 +263,7 @@ pub unsafe extern "C" fn installation_proxy_install_with_callback( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { let callback_wrapper = |(progress, context)| async move { callback(progress, context); }; @@ -312,7 +314,7 @@ pub unsafe extern "C" fn installation_proxy_upgrade( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { unsafe { &mut *client } .0 .upgrade(package_path, options) @@ -363,7 +365,7 @@ pub unsafe extern "C" fn installation_proxy_upgrade_with_callback( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { let callback_wrapper = |(progress, context)| async move { callback(progress, context); }; @@ -414,7 +416,7 @@ pub unsafe extern "C" fn installation_proxy_uninstall( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { unsafe { &mut *client } .0 .uninstall(bundle_id, options) @@ -465,7 +467,7 @@ pub unsafe extern "C" fn installation_proxy_uninstall_with_callback( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { let callback_wrapper = |(progress, context)| async move { callback(progress, context); }; @@ -527,7 +529,7 @@ pub unsafe extern "C" fn installation_proxy_check_capabilities_match( } .map(|x| x.borrow_self().clone()); - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { unsafe { &mut *client } .0 .check_capabilities_match(capabilities, options) @@ -577,7 +579,7 @@ pub unsafe extern "C" fn installation_proxy_browse( } .map(|x| x.borrow_self().clone()); - let res: Result, IdeviceError> = RUNTIME.block_on(async { + let res: Result, IdeviceError> = run_sync_local(async { unsafe { &mut *client }.0.browse(options).await.map(|apps| { apps.into_iter() .map(|v| PlistWrapper::new_node(v).into_ptr()) diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index c0f8219..b75ea91 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -55,7 +55,7 @@ use tokio::runtime::{self, Runtime}; #[cfg(unix)] use crate::util::{idevice_sockaddr, idevice_socklen_t}; -static RUNTIME: Lazy = Lazy::new(|| { +static GLOBAL_RUNTIME: Lazy = Lazy::new(|| { runtime::Builder::new_multi_thread() .enable_io() .enable_time() @@ -63,6 +63,39 @@ static RUNTIME: Lazy = Lazy::new(|| { .unwrap() }); +static LOCAL_RUNTIME: Lazy = Lazy::new(|| { + runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +/// Spawn the future on the global runtime and block current (FFI) thread until result. +/// F and R must be Send + 'static. +pub fn run_sync(fut: F) -> R +where + F: std::future::Future + Send + 'static, + R: Send + 'static, +{ + let (tx, rx) = std::sync::mpsc::sync_channel(1); + + GLOBAL_RUNTIME.handle().spawn(async move { + let res = fut.await; + // best-effort send; ignore if receiver dropped + let _ = tx.send(res); + }); + + rx.recv().expect("runtime worker panicked") +} + +pub fn run_sync_local(fut: F) -> R +where + F: std::future::Future, + R: 'static, +{ + LOCAL_RUNTIME.block_on(fut) +} + pub const LOCKDOWN_PORT: u16 = 62078; #[repr(C)] @@ -144,7 +177,7 @@ pub unsafe extern "C" fn idevice_from_fd( if let Err(e) = socket.set_nonblocking(true) { return ffi_err!(e); } - let socket = match RUNTIME.block_on(async move { tokio::net::TcpStream::from_std(socket) }) { + let socket = match run_sync(async move { tokio::net::TcpStream::from_std(socket) }) { Ok(s) => s, Err(e) => return ffi_err!(e), }; @@ -204,7 +237,7 @@ pub unsafe extern "C" fn idevice_new_tcp_socket( Err(e) => return ffi_err!(e), }; - let device = RUNTIME.block_on(async move { + let device = run_sync(async move { let stream = tokio::net::TcpStream::connect(addr).await?; Ok::(idevice::Idevice::new( Box::new(stream), @@ -247,7 +280,7 @@ pub unsafe extern "C" fn idevice_get_type( let dev = unsafe { &mut (*idevice).0 }; // Run the get_type method in the runtime - let result = RUNTIME.block_on(async { dev.get_type().await }); + let result = run_sync(async { dev.get_type().await }); match result { Ok(type_str) => match CString::new(type_str) { @@ -281,7 +314,7 @@ pub unsafe extern "C" fn idevice_rsd_checkin(idevice: *mut IdeviceHandle) -> *mu let dev = unsafe { &mut (*idevice).0 }; // Run the rsd_checkin method in the runtime - let result = RUNTIME.block_on(async { dev.rsd_checkin().await }); + let result = run_sync(async { dev.rsd_checkin().await }); match result { Ok(_) => null_mut(), @@ -317,7 +350,7 @@ pub unsafe extern "C" fn idevice_start_session( let pf = unsafe { &(*pairing_file).0 }; // Run the start_session method in the runtime - let result = RUNTIME.block_on(async { dev.start_session(pf).await }); + let result = run_sync(async { dev.start_session(pf).await }); match result { Ok(_) => null_mut(), diff --git a/ffi/src/lockdown.rs b/ffi/src/lockdown.rs index c3325c5..0912797 100644 --- a/ffi/src/lockdown.rs +++ b/ffi/src/lockdown.rs @@ -6,8 +6,8 @@ use idevice::{IdeviceError, IdeviceService, lockdown::LockdownClient, provider:: use plist_ffi::plist_t; use crate::{ - IdeviceFfiError, IdeviceHandle, IdevicePairingFile, RUNTIME, ffi_err, - provider::IdeviceProviderHandle, + IdeviceFfiError, IdeviceHandle, IdevicePairingFile, ffi_err, provider::IdeviceProviderHandle, + run_sync_local, }; pub struct LockdowndClientHandle(pub LockdownClient); @@ -34,7 +34,7 @@ pub unsafe extern "C" fn lockdownd_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; LockdownClient::connect(provider_ref).await }); @@ -97,7 +97,7 @@ pub unsafe extern "C" fn lockdownd_start_session( client: *mut LockdowndClientHandle, pairing_file: *mut IdevicePairingFile, ) -> *mut IdeviceFfiError { - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; let pairing_file_ref = unsafe { &(*pairing_file).0 }; @@ -140,7 +140,7 @@ pub unsafe extern "C" fn lockdownd_start_service( .to_string_lossy() .into_owned(); - let res: Result<(u16, bool), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(u16, bool), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.start_service(identifier).await }); @@ -205,7 +205,7 @@ pub unsafe extern "C" fn lockdownd_get_value( }) }; - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.get_value(value, domain).await }); diff --git a/ffi/src/logging.rs b/ffi/src/logging.rs index e274213..15b372c 100644 --- a/ffi/src/logging.rs +++ b/ffi/src/logging.rs @@ -7,7 +7,8 @@ use std::{ }; use tracing::Level; -use tracing_subscriber::{EnvFilter, Layer, fmt::writer::BoxMakeWriter}; +use tracing_appender::non_blocking; +use tracing_subscriber::{EnvFilter, Layer}; use tracing_subscriber::{Registry, fmt, layer::SubscriberExt, util::SubscriberInitExt}; #[repr(C)] @@ -58,6 +59,10 @@ impl IdeviceLogLevel { // ensures we only init once static INIT: Once = Once::new(); +static mut GUARDS: Option<( + Option, + Option, +)> = None; /// Initializes the global logger /// @@ -76,18 +81,23 @@ pub unsafe extern "C" fn idevice_init_logger( let file_filter = file_level.as_filter(); let mut layers = Vec::new(); + let mut console_guard = None; + let mut file_guard = None; - // Console layer + // ---- Console layer ---- if console_level != IdeviceLogLevel::Disabled { + let (non_blocking, guard) = non_blocking(std::io::stdout()); + console_guard = Some(guard); let console_layer = fmt::layer() - .with_writer(std::io::stdout) + .with_writer(non_blocking) .with_ansi(true) .with_target(false) + .with_target(true) .with_filter(EnvFilter::new(console_filter)); layers.push(console_layer.boxed()); } - // File layer + // ---- File layer ---- if !file_path.is_null() && file_level != IdeviceLogLevel::Disabled { let path = match unsafe { CStr::from_ptr(file_path).to_str() } { Ok(p) => p, @@ -97,28 +107,33 @@ pub unsafe extern "C" fn idevice_init_logger( } }; - let file = match File::create(path) { - Ok(f) => f, + match File::create(path) { + Ok(f) => { + let (non_blocking, guard) = non_blocking(f); + file_guard = Some(guard); + let file_layer = fmt::layer() + .with_writer(non_blocking) + .with_ansi(false) + .with_target(false) + .with_filter(EnvFilter::new(file_filter)); + layers.push(file_layer.boxed()); + } Err(_) => { init_result = IdeviceLoggerError::FileError; return; } }; - - let file_layer = fmt::layer() - .with_writer(BoxMakeWriter::new(file)) - .with_ansi(false) - .with_target(false) - .with_filter(EnvFilter::new(file_filter)); - layers.push(file_layer.boxed()); } - // Compose and set as global subscriber + // Keep guards alive (otherwise background threads die) + unsafe { + GUARDS = Some((console_guard, file_guard)); + } + let subscriber = Registry::default().with(layers); subscriber.init(); }); - // If it was already initialized, Once won't run again if !INIT.is_completed() { IdeviceLoggerError::AlreadyInitialized } else { diff --git a/ffi/src/misagent.rs b/ffi/src/misagent.rs index aca5aaf..31b7d64 100644 --- a/ffi/src/misagent.rs +++ b/ffi/src/misagent.rs @@ -6,7 +6,7 @@ use std::ptr::null_mut; use idevice::{IdeviceError, IdeviceService, misagent::MisagentClient, provider::IdeviceProvider}; -use crate::{IdeviceFfiError, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{IdeviceFfiError, ffi_err, provider::IdeviceProviderHandle, run_sync_local}; pub struct MisagentClientHandle(pub MisagentClient); @@ -32,7 +32,7 @@ pub unsafe extern "C" fn misagent_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; MisagentClient::connect(provider_ref).await }); @@ -72,7 +72,7 @@ pub unsafe extern "C" fn misagent_install( let profile = unsafe { std::slice::from_raw_parts(profile_data, profile_len) }.to_vec(); - let res = RUNTIME.block_on(async { unsafe { &mut *client }.0.install(profile).await }); + let res = run_sync_local(async { unsafe { &mut *client }.0.install(profile).await }); match res { Ok(_) => null_mut(), @@ -105,7 +105,7 @@ pub unsafe extern "C" fn misagent_remove( .to_string_lossy() .into_owned(); - let res = RUNTIME.block_on(async { unsafe { &mut *client }.0.remove(&id).await }); + let res = run_sync_local(async { unsafe { &mut *client }.0.remove(&id).await }); match res { Ok(_) => null_mut(), @@ -143,7 +143,7 @@ pub unsafe extern "C" fn misagent_copy_all( } let res: Result>, IdeviceError> = - RUNTIME.block_on(async { unsafe { &mut *client }.0.copy_all().await }); + run_sync_local(async { unsafe { &mut *client }.0.copy_all().await }); match res { Ok(profiles) => { diff --git a/ffi/src/mobile_image_mounter.rs b/ffi/src/mobile_image_mounter.rs index 6bcf0ef..3b29a47 100644 --- a/ffi/src/mobile_image_mounter.rs +++ b/ffi/src/mobile_image_mounter.rs @@ -8,7 +8,9 @@ use idevice::{ use plist::Value; use plist_ffi::{PlistWrapper, plist_t}; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync_local, +}; pub struct ImageMounterHandle(pub ImageMounter); @@ -34,7 +36,7 @@ pub unsafe extern "C" fn image_mounter_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; ImageMounter::connect(provider_ref).await }); @@ -114,7 +116,7 @@ pub unsafe extern "C" fn image_mounter_copy_devices( devices: *mut *mut plist_t, devices_len: *mut libc::size_t, ) -> *mut IdeviceFfiError { - let res: Result, IdeviceError> = RUNTIME.block_on(async move { + let res: Result, IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.copy_devices().await }); @@ -171,7 +173,7 @@ pub unsafe extern "C" fn image_mounter_lookup_image( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result, IdeviceError> = RUNTIME.block_on(async move { + let res: Result, IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.lookup_image(image_type).await }); @@ -228,7 +230,7 @@ pub unsafe extern "C" fn image_mounter_upload_image( let image_slice = unsafe { std::slice::from_raw_parts(image, image_len) }; let signature_slice = unsafe { std::slice::from_raw_parts(signature, signature_len) }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref .upload_image(image_type, image_slice, signature_slice.to_vec()) @@ -295,7 +297,7 @@ pub unsafe extern "C" fn image_mounter_mount_image( None }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref .mount_image( @@ -340,7 +342,7 @@ pub unsafe extern "C" fn image_mounter_unmount_image( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.unmount_image(mount_path).await }); @@ -372,7 +374,7 @@ pub unsafe extern "C" fn image_mounter_query_developer_mode_status( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.query_developer_mode_status().await }); @@ -415,7 +417,7 @@ pub unsafe extern "C" fn image_mounter_mount_developer( let image_slice = unsafe { std::slice::from_raw_parts(image, image_len) }; let signature_slice = unsafe { std::slice::from_raw_parts(signature, signature_len) }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref .mount_developer(image_slice, signature_slice.to_vec()) @@ -465,7 +467,7 @@ pub unsafe extern "C" fn image_mounter_query_personalization_manifest( let signature_slice = unsafe { std::slice::from_raw_parts(signature, signature_len) }; - let res: Result, IdeviceError> = RUNTIME.block_on(async move { + let res: Result, IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref .query_personalization_manifest(image_type, signature_slice.to_vec()) @@ -521,7 +523,7 @@ pub unsafe extern "C" fn image_mounter_query_nonce( None }; - let res: Result, IdeviceError> = RUNTIME.block_on(async move { + let res: Result, IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.query_nonce(image_type).await }); @@ -573,7 +575,7 @@ pub unsafe extern "C" fn image_mounter_query_personalization_identifiers( None }; - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref .query_personalization_identifiers(image_type) @@ -604,7 +606,7 @@ pub unsafe extern "C" fn image_mounter_query_personalization_identifiers( pub unsafe extern "C" fn image_mounter_roll_personalization_nonce( client: *mut ImageMounterHandle, ) -> *mut IdeviceFfiError { - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.roll_personalization_nonce().await }); @@ -629,7 +631,7 @@ pub unsafe extern "C" fn image_mounter_roll_personalization_nonce( pub unsafe extern "C" fn image_mounter_roll_cryptex_nonce( client: *mut ImageMounterHandle, ) -> *mut IdeviceFfiError { - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; client_ref.roll_cryptex_nonce().await }); @@ -692,7 +694,7 @@ pub unsafe extern "C" fn image_mounter_mount_personalized( None }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; client_ref @@ -769,7 +771,7 @@ pub unsafe extern "C" fn image_mounter_mount_personalized_with_callback( None }; - let res: Result<(), IdeviceError> = RUNTIME.block_on(async move { + let res: Result<(), IdeviceError> = run_sync_local(async move { let client_ref = unsafe { &mut (*client).0 }; let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; diff --git a/ffi/src/os_trace_relay.rs b/ffi/src/os_trace_relay.rs index e87d193..2a45477 100644 --- a/ffi/src/os_trace_relay.rs +++ b/ffi/src/os_trace_relay.rs @@ -5,7 +5,8 @@ use idevice::{ IdeviceError, IdeviceService, os_trace_relay::OsTraceRelayClient, provider::IdeviceProvider, }; -use crate::{IdeviceFfiError, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::run_sync_local; +use crate::{IdeviceFfiError, ffi_err, provider::IdeviceProviderHandle}; pub struct OsTraceRelayClientHandle(pub OsTraceRelayClient); pub struct OsTraceRelayReceiverHandle(pub idevice::os_trace_relay::OsTraceRelayReceiver); @@ -50,7 +51,7 @@ pub unsafe extern "C" fn os_trace_relay_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; OsTraceRelayClient::connect(provider_ref).await }); @@ -114,7 +115,7 @@ pub unsafe extern "C" fn os_trace_relay_start_trace( let client_owned = unsafe { Box::from_raw(client) }; - let res = RUNTIME.block_on(async { client_owned.0.start_trace(pid_option).await }); + let res = run_sync_local(async { client_owned.0.start_trace(pid_option).await }); match res { Ok(relay) => { @@ -158,7 +159,7 @@ pub unsafe extern "C" fn os_trace_relay_get_pid_list( client: *mut OsTraceRelayClientHandle, list: *mut *mut Vec, ) -> *mut IdeviceFfiError { - let res = RUNTIME.block_on(async { unsafe { &mut *client }.0.get_pid_list().await }); + let res = run_sync_local(async { unsafe { &mut *client }.0.get_pid_list().await }); match res { Ok(r) => { @@ -190,7 +191,7 @@ pub unsafe extern "C" fn os_trace_relay_next( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res = RUNTIME.block_on(async { unsafe { &mut *client }.0.next().await }); + let res = run_sync_local(async { unsafe { &mut *client }.0.next().await }); match res { Ok(r) => { diff --git a/ffi/src/provider.rs b/ffi/src/provider.rs index 89c020f..9b54418 100644 --- a/ffi/src/provider.rs +++ b/ffi/src/provider.rs @@ -7,7 +7,7 @@ use std::{ffi::CStr, ptr::null_mut}; use crate::util::{SockAddr, idevice_sockaddr}; use crate::{IdeviceFfiError, ffi_err, usbmuxd::UsbmuxdAddrHandle, util}; -use crate::{IdevicePairingFile, RUNTIME}; +use crate::{IdevicePairingFile, run_sync}; pub struct IdeviceProviderHandle(pub Box); @@ -156,7 +156,7 @@ pub unsafe extern "C" fn idevice_provider_get_pairing_file( ) -> *mut IdeviceFfiError { let provider = unsafe { &mut *provider }; - let res = RUNTIME.block_on(async move { provider.0.get_pairing_file().await }); + let res = run_sync(async move { provider.0.get_pairing_file().await }); match res { Ok(pf) => { let pf = Box::new(IdevicePairingFile(pf)); diff --git a/ffi/src/rsd.rs b/ffi/src/rsd.rs index 0ac757f..01877aa 100644 --- a/ffi/src/rsd.rs +++ b/ffi/src/rsd.rs @@ -7,7 +7,7 @@ use std::ptr::{self, null_mut}; use idevice::rsd::RsdHandshake; -use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; +use crate::{IdeviceFfiError, ReadWriteOpaque, ffi_err, run_sync}; /// Opaque handle to an RsdHandshake #[derive(Clone)] @@ -66,7 +66,7 @@ pub unsafe extern "C" fn rsd_handshake_new( let wrapper = unsafe { &mut *socket }; let res = match wrapper.inner.take() { - Some(mut w) => RUNTIME.block_on(async move { RsdHandshake::new(w.as_mut()).await }), + Some(mut w) => run_sync(async move { RsdHandshake::new(w.as_mut()).await }), None => { return ffi_err!(IdeviceError::FfiInvalidArg); } diff --git a/ffi/src/springboardservices.rs b/ffi/src/springboardservices.rs index c969344..50d56d5 100644 --- a/ffi/src/springboardservices.rs +++ b/ffi/src/springboardservices.rs @@ -8,7 +8,10 @@ use idevice::{ springboardservices::SpringBoardServicesClient, }; -use crate::{IdeviceFfiError, IdeviceHandle, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{ + IdeviceFfiError, IdeviceHandle, ffi_err, provider::IdeviceProviderHandle, run_sync, + run_sync_local, +}; pub struct SpringBoardServicesClientHandle(pub SpringBoardServicesClient); @@ -34,7 +37,7 @@ pub unsafe extern "C" fn springboard_services_connect( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; SpringBoardServicesClient::connect(provider_ref).await }); @@ -115,7 +118,7 @@ pub unsafe extern "C" fn springboard_services_get_icon( }; let res: Result, IdeviceError> = - RUNTIME.block_on(async { client.0.get_icon_pngdata(bundle_id).await }); + run_sync(async { client.0.get_icon_pngdata(bundle_id).await }); match res { Ok(r) => { diff --git a/ffi/src/syslog_relay.rs b/ffi/src/syslog_relay.rs index 747d91a..5919ff5 100644 --- a/ffi/src/syslog_relay.rs +++ b/ffi/src/syslog_relay.rs @@ -4,7 +4,7 @@ use idevice::{ IdeviceError, IdeviceService, provider::IdeviceProvider, syslog_relay::SyslogRelayClient, }; -use crate::{IdeviceFfiError, RUNTIME, ffi_err, provider::IdeviceProviderHandle}; +use crate::{IdeviceFfiError, ffi_err, provider::IdeviceProviderHandle, run_sync_local}; pub struct SyslogRelayClientHandle(pub SyslogRelayClient); @@ -27,7 +27,7 @@ pub unsafe extern "C" fn syslog_relay_connect_tcp( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync_local(async move { let provider_ref: &dyn IdeviceProvider = unsafe { &*(*provider).0 }; SyslogRelayClient::connect(provider_ref).await }); @@ -81,7 +81,7 @@ pub unsafe extern "C" fn syslog_relay_next( return ffi_err!(IdeviceError::FfiInvalidArg); } - let res = RUNTIME.block_on(async { unsafe { &mut *client }.0.next().await }); + let res = run_sync_local(async { unsafe { &mut *client }.0.next().await }); match res { Ok(log) => { diff --git a/ffi/src/tcp_object_stack.rs b/ffi/src/tcp_object_stack.rs index 8917305..8d1b8b0 100644 --- a/ffi/src/tcp_object_stack.rs +++ b/ffi/src/tcp_object_stack.rs @@ -14,7 +14,7 @@ use tokio::{ net::tcp::{OwnedReadHalf, OwnedWriteHalf}, }; -use crate::{IdeviceFfiError, RUNTIME, core_device_proxy::AdapterHandle, ffi_err}; +use crate::{IdeviceFfiError, core_device_proxy::AdapterHandle, ffi_err, run_sync, run_sync_local}; pub struct TcpFeedObject { sender: Arc>, @@ -63,7 +63,7 @@ pub unsafe extern "C" fn idevice_tcp_stack_into_sync_objects( } }; - let res = RUNTIME.block_on(async { + let res = run_sync(async { let mut port = 4000; loop { if port > 4050 { @@ -105,7 +105,7 @@ pub unsafe extern "C" fn idevice_tcp_stack_into_sync_objects( let eat_object = TcpEatObject { receiver: r }; // we must be inside the runtime for the inner function to spawn threads - let new_adapter = RUNTIME.block_on(async { + let new_adapter = run_sync_local(async { idevice::tcp::adapter::Adapter::new(Box::new(stream), our_ip, their_ip).to_async_handle() }); // this object can now be used with the rest of the idevice FFI library @@ -133,7 +133,7 @@ pub unsafe extern "C" fn idevice_tcp_feed_object_write( } let object = unsafe { &mut *object }; let data = unsafe { std::slice::from_raw_parts(data, len) }; - RUNTIME.block_on(async move { + run_sync_local(async move { let mut lock = object.sender.lock().await; match lock.write_all(data).await { Ok(_) => { @@ -163,7 +163,7 @@ pub unsafe extern "C" fn idevice_tcp_eat_object_read( ) -> *mut IdeviceFfiError { let object = unsafe { &mut *object }; let mut buf = [0; 2048]; - RUNTIME.block_on(async { + run_sync_local(async { let lock = object.receiver.lock().await; match lock.try_read(&mut buf) { Ok(size) => { diff --git a/ffi/src/usbmuxd.rs b/ffi/src/usbmuxd.rs index 3d0a24b..bdae2f3 100644 --- a/ffi/src/usbmuxd.rs +++ b/ffi/src/usbmuxd.rs @@ -7,7 +7,7 @@ use std::{ }; use crate::{ - IdeviceFfiError, IdeviceHandle, IdevicePairingFile, RUNTIME, ffi_err, + IdeviceFfiError, IdeviceHandle, IdevicePairingFile, ffi_err, run_sync, run_sync_local, util::{SockAddr, c_socket_to_rust, idevice_sockaddr, idevice_socklen_t}, }; use futures::{Stream, StreamExt}; @@ -57,7 +57,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_new_tcp_connection( Err(e) => return ffi_err!(e), }; - let res = RUNTIME.block_on(async move { + let res = run_sync(async move { let stream = tokio::net::TcpStream::connect(addr).await?; Ok::<_, IdeviceError>(UsbmuxdConnection::new(Box::new(stream), tag)) }); @@ -96,7 +96,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_new_unix_socket_connection( Err(_) => return ffi_err!(IdeviceError::FfiInvalidArg), }; - let res: Result = RUNTIME.block_on(async move { + let res: Result = run_sync(async move { let stream = tokio::net::UnixStream::connect(addr).await?; Ok(UsbmuxdConnection::new(Box::new(stream), tag)) }); @@ -138,7 +138,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_new_default_connection( }; let res: Result = - RUNTIME.block_on(async move { addr.connect(tag).await }); + run_sync(async move { addr.connect(tag).await }); match res { Ok(r) => { @@ -176,7 +176,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_get_devices( } let conn = unsafe { &mut (*usbmuxd_conn).0 }; - let res = RUNTIME.block_on(async { conn.get_devices().await }); + let res = run_sync(async { conn.get_devices().await }); match res { Ok(device_vec) => { @@ -244,7 +244,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_connect_to_device( } }; - let res = RUNTIME.block_on(async move { conn.connect_to_device(device_id, port, label).await }); + let res = run_sync(async move { conn.connect_to_device(device_id, port, label).await }); match res { Ok(device_conn) => { @@ -292,7 +292,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_get_pair_record( } }; - let res = RUNTIME.block_on(async { conn.get_pair_record(udid_str).await }); + let res = run_sync(async { conn.get_pair_record(udid_str).await }); match res { Ok(pf) => { @@ -344,7 +344,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_save_pair_record( } }; - let res = RUNTIME.block_on(async { + let res = run_sync_local(async { conn.save_pair_record(device_id, udid_str, pair_record) .await }); @@ -371,7 +371,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_listen( } let conn = unsafe { &mut (*usbmuxd_conn).0 }; - let res = RUNTIME.block_on(async { conn.listen().await }); + let res = run_sync_local(async { conn.listen().await }); match res { Ok(s) => { @@ -425,7 +425,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_listener_next( } let stream = unsafe { &mut (*stream_handle).0 }; - let res = RUNTIME.block_on(async { stream.next().await }); + let res = run_sync_local(async { stream.next().await }); match res { Some(res) => match res { @@ -477,7 +477,7 @@ pub unsafe extern "C" fn idevice_usbmuxd_get_buid( } let conn = unsafe { &mut (*usbmuxd_conn).0 }; - let res = RUNTIME.block_on(async { conn.get_buid().await }); + let res = run_sync(async { conn.get_buid().await }); match res { Ok(buid_str) => match CString::new(buid_str) { diff --git a/idevice/src/services/dvt/message.rs b/idevice/src/services/dvt/message.rs index a852ce8..2cb3f5e 100644 --- a/idevice/src/services/dvt/message.rs +++ b/idevice/src/services/dvt/message.rs @@ -61,7 +61,7 @@ use plist::Value; use tokio::io::{AsyncRead, AsyncReadExt}; -use crate::IdeviceError; +use crate::{IdeviceError, pretty_print_plist}; /// Message header containing metadata about the message /// @@ -141,7 +141,7 @@ pub enum AuxValue { } /// Complete protocol message -#[derive(Debug, PartialEq)] +#[derive(PartialEq)] pub struct Message { /// Message metadata header pub message_header: MessageHeader, @@ -525,3 +525,14 @@ impl std::fmt::Debug for AuxValue { } } } + +impl std::fmt::Debug for Message { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Message") + .field("message_header", &self.message_header) + .field("payload_header", &self.payload_header) + .field("aux", &self.aux) + .field("data", &self.data.as_ref().map(pretty_print_plist)) + .finish() + } +}