Browse Source

Finish up SSLC, SOC, ROMFS and PS

pull/134/head
Andrea Ciliberti 1 year ago
parent
commit
fde168cb17
  1. 4
      ctru-rs/src/services/am.rs
  2. 71
      ctru-rs/src/services/ps.rs
  3. 33
      ctru-rs/src/services/romfs.rs
  4. 92
      ctru-rs/src/services/soc.rs
  5. 14
      ctru-rs/src/services/sslc.rs

4
ctru-rs/src/services/am.rs

@ -157,14 +157,12 @@ impl Am { @@ -157,14 +157,12 @@ impl Am {
Ok(info
.into_iter()
.map(|title| {
Title {
.map(|title| Title {
id: title.titleID,
mediatype,
size: title.size,
version: title.version,
_am: PhantomData,
}
})
.collect())
}

71
ctru-rs/src/services/ps.rs

@ -1,14 +1,15 @@ @@ -1,14 +1,15 @@
//! Process Services.
//!
//! This is used for miscellaneous utility tasks, but
//! is particularly important because it is used to generate random data, which
//! is required for common things like [`HashMap`](std::collections::HashMap).
//! This service handles miscellaneous utility tasks used by the various processes.
//! However, it is particularly important because it is used to generate cryptographically secure random data, which
//! is required for commonly used functionality such as hashing (e.g. [`HashMap`](std::collections::HashMap) will not work without it).
//!
//! See also <https://www.3dbrew.org/wiki/Process_Services>
use crate::error::ResultCode;
use crate::Result;
/// Kind of AES algorithm to use.
/// Type of AES algorithm to use.
#[doc(alias = "PS_AESAlgorithm")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
@ -59,6 +60,20 @@ pub struct Ps(()); @@ -59,6 +60,20 @@ pub struct Ps(());
impl Ps {
/// Initialize a new service handle.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::ps::Ps;
///
/// let ps = Ps::new()?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "psInit")]
pub fn new() -> Result<Self> {
unsafe {
@ -68,6 +83,21 @@ impl Ps { @@ -68,6 +83,21 @@ impl Ps {
}
/// Returns the console's local friend code seed.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::ps::Ps;
/// let ps = Ps::new()?;
///
/// let friend_code_seed = ps.local_friend_code_seed()?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "PS_GetLocalFriendCodeSeed")]
pub fn local_friend_code_seed(&self) -> crate::Result<u64> {
let mut seed: u64 = 0;
@ -77,6 +107,21 @@ impl Ps { @@ -77,6 +107,21 @@ impl Ps {
}
/// Returns the console's devide ID.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::ps::Ps;
/// let ps = Ps::new()?;
///
/// let device_id = ps.device_id()?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "PS_GetDeviceId")]
pub fn device_id(&self) -> crate::Result<u32> {
let mut id: u32 = 0;
@ -86,6 +131,24 @@ impl Ps { @@ -86,6 +131,24 @@ impl Ps {
}
/// Generates cryptografically secure random bytes and writes them into the `out` buffer.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::ps::Ps;
/// let ps = Ps::new()?;
///
/// let mut buffer = vec![0; 128];
///
/// // The buffer is now randomized!
/// ps.generate_random_bytes(&mut buffer)?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "PS_GenerateRandomBytes")]
pub fn generate_random_bytes(&self, out: &mut [u8]) -> crate::Result<()> {
ResultCode(unsafe {

33
ctru-rs/src/services/romfs.rs

@ -1,9 +1,14 @@ @@ -1,9 +1,14 @@
//! Read-Only Memory FileSystem service.
//!
//! This service lets the application access a virtual mounted device created using a folder included within the application bundle.
//! After mounting the RomFS file system, the included files and folders will be accessible exactly like any other file, just by using the drive prefix `romfs:/<file-path>`.
//!
//! # Usage
//!
//! This module only gets compiled if the configured RomFS directory is found and the `romfs`
//! feature is enabled.
//!
//! Configure the path in Cargo.toml (the default path is "romfs"). Paths are relative to the
//! Configure the path in your project's `Cargo.toml` manifest (the default path is "romfs"). Paths are relative to the
//! `CARGO_MANIFEST_DIR` environment variable, which is the directory containing the manifest of
//! your package.
//!
@ -11,6 +16,8 @@ @@ -11,6 +16,8 @@
//! [package.metadata.cargo-3ds]
//! romfs_dir = "romfs"
//! ```
//!
//! Alternatively, you can include the RomFS archive manually when building with `3dsxtool`.
use crate::error::ResultCode;
use std::ffi::CStr;
@ -19,11 +26,6 @@ use std::sync::Mutex; @@ -19,11 +26,6 @@ use std::sync::Mutex;
use crate::services::ServiceReference;
/// Handle to the RomFS service.
///
/// This service lets the application access a virtual mounted device created using a folder included within the application bundle.
/// `ctru-rs` will include as RomFS the folder specified in the `Cargo.toml` manifest (or use `./romfs` by default). Look at the [`romfs`](self) module for more information.
///
/// After mounting the RomFS file system, the included files and folders will be accessible exactly like any other file, just by using the drive prefix `romfs:/`.
pub struct RomFS {
_service_handler: ServiceReference,
}
@ -31,7 +33,24 @@ pub struct RomFS { @@ -31,7 +33,24 @@ pub struct RomFS {
static ROMFS_ACTIVE: Mutex<usize> = Mutex::new(0);
impl RomFS {
/// Mount the specified RomFS folder as a virtual drive.
/// Mount the bundled RomFS archive as a virtual drive.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::romfs::RomFS;
///
/// let romfs = RomFS::new()?;
///
/// // Remember to include the RomFS archive and to use your actual files!
/// let contents = std::fs::read_to_string("romfs:/test-file.txt");
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "romfsMountSelf")]
pub fn new() -> crate::Result<Self> {
let _service_handler = ServiceReference::new(

92
ctru-rs/src/services/soc.rs

@ -1,4 +1,7 @@ @@ -1,4 +1,7 @@
//! Network Socket service.
//!
//! By using this service the program enables the use of network sockets and utilities such as those found in `std::net`, which are completely inaccessible by default.
//! As such, remember to hold a handle to this service handle while using any network functionality, or else the `std::net` methods will return generic OS errors.
use libc::memalign;
use std::net::Ipv4Addr;
@ -8,10 +11,7 @@ use crate::error::ResultCode; @@ -8,10 +11,7 @@ use crate::error::ResultCode;
use crate::services::ServiceReference;
use crate::Error;
/// Network socket service
///
/// Initializing this service will enable the use of network sockets and utilities
/// such as those found in `std::net`. The service will close once this struct gets dropped.
/// Handle to the Network Socket service.
pub struct Soc {
_service_handler: ServiceReference,
sock_3dslink: libc::c_int,
@ -20,22 +20,51 @@ pub struct Soc { @@ -20,22 +20,51 @@ pub struct Soc {
static SOC_ACTIVE: Mutex<usize> = Mutex::new(0);
impl Soc {
/// Initialize a new service handle using a socket buffer size of 0x100000 bytes.
/// Initialize a new service handle using a socket buffer size of `0x100000` bytes.
///
/// # Errors
///
/// This function will return an error if the [`Soc`] service is already initialized
/// This function will return an error if the [`Soc`] service is already being used.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::soc::Soc;
///
/// let soc = Soc::new()?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "socInit")]
pub fn new() -> crate::Result<Self> {
Self::init_with_buffer_size(0x100000)
}
/// Initialize the Soc service with a custom buffer size in bytes. The size should be
/// 0x100000 bytes or greater.
/// Initialize a new service handle using a custom socket buffer size.
///
/// The size should be `0x100000` bytes or greater.
///
/// # Errors
///
/// This function will return an error if the [`Soc`] service is already initialized
/// This function will return an error if the [`Soc`] service is already being used.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::soc::Soc;
///
/// let soc = Soc::init_with_buffer_size(0x100000)?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "socInit")]
pub fn init_with_buffer_size(num_bytes: usize) -> crate::Result<Self> {
let _service_handler = ServiceReference::new(
@ -62,20 +91,55 @@ impl Soc { @@ -62,20 +91,55 @@ impl Soc {
})
}
/// IP Address of the Nintendo 3DS system.
/// Returns the local IP Address of the Nintendo 3DS system.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::soc::Soc;
/// let soc = Soc::new()?;
///
/// let address = soc.host_address();
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "gethostid")]
pub fn host_address(&self) -> Ipv4Addr {
let raw_id = unsafe { libc::gethostid() };
Ipv4Addr::from(raw_id.to_ne_bytes())
}
/// Redirect output streams (i.e. [`println`] and [`eprintln`]) to the `3dslink` server.
/// Requires `3dslink` >= 0.6.1 and `new-hbmenu` >= 2.3.0.
/// Redirect output streams (i.e. `println` and `eprintln`) to the `3dslink` server.
///
/// Requires `3dslink` >= 0.6.1 and `new-hbmenu` >= 2.3.0 and the use of the `--server` flag.
/// The `--server` flag is also availble to use via `cargo-3ds` if the requirements are met.
///
/// # Errors
///
/// Returns an error if a connection cannot be established to the server, or
/// output was already previously redirected.
/// Returns an error if a connection cannot be established to the server,
/// or if the output was already being redirected.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::soc::Soc;
/// let mut soc = Soc::new()?;
///
/// // Redirect to the `3dslink` server that sent this program.
/// let address = soc.redirect_to_3dslink(true, true)?;
///
/// println!("I'm visible from a PC!");
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "link3dsConnectToHost")]
pub fn redirect_to_3dslink(&mut self, stdout: bool, stderr: bool) -> crate::Result<()> {
if self.sock_3dslink >= 0 {

14
ctru-rs/src/services/sslc.rs

@ -9,6 +9,20 @@ pub struct SslC(()); @@ -9,6 +9,20 @@ pub struct SslC(());
impl SslC {
/// Initialize a new service handle.
///
/// # Example
///
/// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use ctru::services::sslc::SslC;
///
/// let sslc = SslC::new()?;
/// #
/// # Ok(())
/// # }
/// ```
#[doc(alias = "sslcInit")]
pub fn new() -> crate::Result<Self> {
unsafe {

Loading…
Cancel
Save