├── .gitignore ├── Cargo.toml ├── README.md ├── aarch64-skyline-switch.json └── src ├── common_types.rs ├── extensions.rs ├── lib.rs ├── nn ├── account.rs ├── account │ └── detail.rs ├── aoc.rs ├── audio.rs ├── crypto.rs ├── crypto │ └── detail.rs ├── diag.rs ├── diag │ └── detail.rs ├── err.rs ├── friends.rs ├── fs.rs ├── hid.rs ├── image.rs ├── init.rs ├── init │ └── detail.rs ├── ldn.rs ├── mem.rs ├── mod.rs ├── nifm.rs ├── oe.rs ├── os.rs ├── os │ └── detail.rs ├── prepo.rs ├── ro.rs ├── settings.rs ├── settings │ └── system.rs ├── socket.rs ├── ssl.rs ├── svc.rs ├── swkbd.rs ├── time.rs ├── ui2d.rs ├── ui2d │ └── resources.rs ├── util.rs ├── vi.rs ├── web.rs └── web │ └── offlinewebsession.rs └── rtld.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nnsdk" 3 | version = "0.4.0" 4 | authors = ["jam1garner "] 5 | edition = "2018" 6 | license = "MIT" 7 | description = "Cleanroom reverse-engineered bindings for nnsdk (Nintendo Switch SDK)" 8 | documentation = "https://docs.rs/nnsdk" 9 | 10 | [dependencies] 11 | libc-nnsdk = "0.4.0" 12 | 13 | # rustc-dep-of-std 14 | core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" } 15 | alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" } 16 | compiler_builtins = { version = "0.1", optional = true } 17 | 18 | [features] 19 | rustc-dep-of-std = [ 20 | "libc-nnsdk/rustc-dep-of-std", 21 | "core", 22 | "alloc", 23 | "compiler_builtins" 24 | ] 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nnSdk 2 | 3 | Rust bindings for the Nintendo SDK. All bindings have been generated using header files derived from reverse engineering and therefore: 4 | 5 | 1. May not be accurate 6 | 2. Are in no way derived from the intellectual property of Nintendo 7 | -------------------------------------------------------------------------------- /aarch64-skyline-switch.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi-blacklist": [ 3 | "stdcall", 4 | "fastcall", 5 | "vectorcall", 6 | "thiscall", 7 | "win64", 8 | "sysv64" 9 | ], 10 | "arch": "aarch64", 11 | "crt-static-default": false, 12 | "crt-static-respected": false, 13 | "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", 14 | "dynamic-linking": true, 15 | "dynamic-linking-available": true, 16 | "executables": true, 17 | "has-elf-tls": false, 18 | "has-rpath": false, 19 | "linker": "rust-lld", 20 | "linker-flavor": "ld.lld", 21 | "llvm-target": "aarch64-unknown-none", 22 | "max-atomic-width": 128, 23 | "os": "switch", 24 | "panic-strategy": "abort", 25 | "position-independent-executables": true, 26 | "pre-link-args": { 27 | "ld.lld": [ 28 | "-Tlink.T", 29 | "-init=__custom_init", 30 | "-fini=__custom_fini", 31 | "--export-dynamic" 32 | ] 33 | }, 34 | "post-link-args": { 35 | "ld.lld": [ 36 | "--no-gc-sections", 37 | "--eh-frame-hdr" 38 | ] 39 | }, 40 | "relro-level": "off", 41 | "target-c-int-width": "32", 42 | "target-endian": "little", 43 | "target-pointer-width": "64", 44 | "vendor": "roblabla" 45 | } 46 | -------------------------------------------------------------------------------- /src/common_types.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[derive(Default)] 3 | pub struct __IncompleteArrayField(::core::marker::PhantomData, [T; 0]); 4 | impl __IncompleteArrayField { 5 | #[inline] 6 | pub const fn new() -> Self { 7 | __IncompleteArrayField(::core::marker::PhantomData, []) 8 | } 9 | #[inline] 10 | pub fn as_ptr(&self) -> *const T { 11 | self as *const _ as *const T 12 | } 13 | #[inline] 14 | pub fn as_mut_ptr(&mut self) -> *mut T { 15 | self as *mut _ as *mut T 16 | } 17 | #[inline] 18 | pub unsafe fn as_slice(&self, len: usize) -> &[T] { 19 | ::core::slice::from_raw_parts(self.as_ptr(), len) 20 | } 21 | #[inline] 22 | pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { 23 | ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len) 24 | } 25 | } 26 | impl ::core::fmt::Debug for __IncompleteArrayField { 27 | fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { 28 | fmt.write_str("__IncompleteArrayField") 29 | } 30 | } 31 | #[repr(C)] 32 | pub struct __BindgenUnionField(::core::marker::PhantomData); 33 | impl __BindgenUnionField { 34 | #[inline] 35 | pub const fn new() -> Self { 36 | __BindgenUnionField(::core::marker::PhantomData) 37 | } 38 | #[inline] 39 | pub unsafe fn as_ref(&self) -> &T { 40 | ::core::mem::transmute(self) 41 | } 42 | #[inline] 43 | pub unsafe fn as_mut(&mut self) -> &mut T { 44 | ::core::mem::transmute(self) 45 | } 46 | } 47 | impl ::core::default::Default for __BindgenUnionField { 48 | #[inline] 49 | fn default() -> Self { 50 | Self::new() 51 | } 52 | } 53 | impl ::core::clone::Clone for __BindgenUnionField { 54 | #[inline] 55 | fn clone(&self) -> Self { 56 | Self::new() 57 | } 58 | } 59 | impl ::core::marker::Copy for __BindgenUnionField {} 60 | impl ::core::fmt::Debug for __BindgenUnionField { 61 | fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { 62 | fmt.write_str("__BindgenUnionField") 63 | } 64 | } 65 | impl ::core::hash::Hash for __BindgenUnionField { 66 | fn hash(&self, _state: &mut H) {} 67 | } 68 | impl ::core::cmp::PartialEq for __BindgenUnionField { 69 | fn eq(&self, _other: &__BindgenUnionField) -> bool { 70 | true 71 | } 72 | } 73 | impl ::core::cmp::Eq for __BindgenUnionField {} 74 | #[allow(unused_imports)] 75 | use self::super::root; 76 | pub type __u_char = u8; 77 | pub type __u_short = u16; 78 | pub type __u_int = u32; 79 | pub type __u_long = u64; 80 | pub type __int8_t = i8; 81 | pub type __uint8_t = u8; 82 | pub type __int16_t = i16; 83 | pub type __uint16_t = u16; 84 | pub type __int32_t = i32; 85 | pub type __uint32_t = u32; 86 | pub type __int64_t = i64; 87 | pub type __uint64_t = u64; 88 | pub type __int_least8_t = root::__int8_t; 89 | pub type __uint_least8_t = root::__uint8_t; 90 | pub type __int_least16_t = root::__int16_t; 91 | pub type __uint_least16_t = root::__uint16_t; 92 | pub type __int_least32_t = root::__int32_t; 93 | pub type __uint_least32_t = root::__uint32_t; 94 | pub type __int_least64_t = root::__int64_t; 95 | pub type __uint_least64_t = root::__uint64_t; 96 | pub type __quad_t = i64; 97 | pub type __u_quad_t = u64; 98 | pub type __intmax_t = i64; 99 | pub type __uintmax_t = u64; 100 | pub type __dev_t = u64; 101 | pub type __uid_t = u32; 102 | pub type __gid_t = u32; 103 | pub type __ino_t = u64; 104 | pub type __ino64_t = u64; 105 | pub type __mode_t = u32; 106 | pub type __nlink_t = u64; 107 | pub type __off_t = i64; 108 | pub type __off64_t = i64; 109 | pub type __pid_t = i32; 110 | #[repr(C)] 111 | #[derive(Debug, Copy, Clone)] 112 | pub struct __fsid_t { 113 | pub __val: [i32; 2usize], 114 | } 115 | 116 | pub type __clock_t = i64; 117 | pub type __rlim_t = u64; 118 | pub type __rlim64_t = u64; 119 | pub type __id_t = u32; 120 | pub type __time_t = i64; 121 | pub type __useconds_t = u32; 122 | pub type __suseconds_t = i64; 123 | pub type __daddr_t = i32; 124 | pub type __key_t = i32; 125 | pub type __clockid_t = i32; 126 | pub type __timer_t = *mut u8; 127 | pub type __blksize_t = i64; 128 | pub type __blkcnt_t = i64; 129 | pub type __blkcnt64_t = i64; 130 | pub type __fsblkcnt_t = u64; 131 | pub type __fsblkcnt64_t = u64; 132 | pub type __fsfilcnt_t = u64; 133 | pub type __fsfilcnt64_t = u64; 134 | pub type __fsword_t = i64; 135 | pub type __ssize_t = i64; 136 | pub type __syscall_slong_t = i64; 137 | pub type __syscall_ulong_t = u64; 138 | pub type __loff_t = root::__off64_t; 139 | pub type __caddr_t = *mut u8; 140 | pub type __intptr_t = i64; 141 | pub type __socklen_t = u32; 142 | pub type __sig_atomic_t = i32; 143 | pub type int_least8_t = root::__int_least8_t; 144 | pub type int_least16_t = root::__int_least16_t; 145 | pub type int_least32_t = root::__int_least32_t; 146 | pub type int_least64_t = root::__int_least64_t; 147 | pub type uint_least8_t = root::__uint_least8_t; 148 | pub type uint_least16_t = root::__uint_least16_t; 149 | pub type uint_least32_t = root::__uint_least32_t; 150 | pub type uint_least64_t = root::__uint_least64_t; 151 | pub type int_fast8_t = i8; 152 | pub type int_fast16_t = i64; 153 | pub type int_fast32_t = i64; 154 | pub type int_fast64_t = i64; 155 | pub type uint_fast8_t = u8; 156 | pub type uint_fast16_t = u64; 157 | pub type uint_fast32_t = u64; 158 | pub type uint_fast64_t = u64; 159 | pub type intmax_t = root::__intmax_t; 160 | pub type uintmax_t = root::__uintmax_t; 161 | pub type size_t = u64; 162 | #[repr(C)] 163 | #[repr(align(16))] 164 | #[derive(Debug, Copy, Clone)] 165 | pub struct max_align_t { 166 | pub __clang_max_align_nonce1: i64, 167 | pub __bindgen_padding_0: u64, 168 | pub __clang_max_align_nonce2: u128, 169 | } 170 | 171 | #[repr(C)] 172 | #[derive(Debug, Copy, Clone)] 173 | pub struct imaxdiv_t { 174 | pub quot: i64, 175 | pub rem: i64, 176 | } 177 | 178 | extern "C" { 179 | pub fn imaxabs(__n: root::intmax_t) -> root::intmax_t; 180 | } 181 | extern "C" { 182 | pub fn imaxdiv(__numer: root::intmax_t, __denom: root::intmax_t) -> root::imaxdiv_t; 183 | } 184 | extern "C" { 185 | pub fn strtoimax( 186 | __nptr: *const u8, 187 | __endptr: *mut *mut u8, 188 | __base: i32, 189 | ) -> root::intmax_t; 190 | } 191 | extern "C" { 192 | pub fn strtoumax( 193 | __nptr: *const u8, 194 | __endptr: *mut *mut u8, 195 | __base: i32, 196 | ) -> root::uintmax_t; 197 | } 198 | extern "C" { 199 | pub fn wcstoimax( 200 | __nptr: *const u32, 201 | __endptr: *mut *mut u32, 202 | __base: i32, 203 | ) -> root::intmax_t; 204 | } 205 | extern "C" { 206 | pub fn wcstoumax( 207 | __nptr: *const u32, 208 | __endptr: *mut *mut u32, 209 | __base: i32, 210 | ) -> root::uintmax_t; 211 | } 212 | extern "C" { 213 | #[link_name = "\u{1}__cxa_demangle"] 214 | pub fn cxa_demangle( 215 | symbol_name: *const u8, 216 | unk1: *const u8, 217 | unk2: *const u8, 218 | result: *mut u32, 219 | ) -> *mut u8; 220 | } 221 | pub type s8 = i8; 222 | pub type s16 = i16; 223 | pub type s32 = i32; 224 | pub type s64 = i64; 225 | pub type s128 = root::__int128_t; 226 | pub type uchar = u8; 227 | pub type ulong = u64; 228 | pub type uint = u32; 229 | pub type Result = u32; 230 | pub type Handle = u32; 231 | pub type ThreadFunc = ::core::option::Option; 232 | pub const Module_Kernel: root::_bindgen_ty_1 = 1; 233 | pub const Module_Libnx: root::_bindgen_ty_1 = 345; 234 | pub const Module_HomebrewAbi: root::_bindgen_ty_1 = 346; 235 | pub const Module_HomebrewLoader: root::_bindgen_ty_1 = 347; 236 | pub const Module_LibnxNvidia: root::_bindgen_ty_1 = 348; 237 | pub const Module_LibnxBinder: root::_bindgen_ty_1 = 349; 238 | #[doc = " Module values"] 239 | pub type _bindgen_ty_1 = u32; 240 | pub const KernelError_OutOfSessions: root::_bindgen_ty_2 = 7; 241 | pub const KernelError_InvalidCapabilityDescriptor: root::_bindgen_ty_2 = 14; 242 | pub const KernelError_NotImplemented: root::_bindgen_ty_2 = 33; 243 | pub const KernelError_ThreadTerminating: root::_bindgen_ty_2 = 59; 244 | pub const KernelError_OutOfDebugEvents: root::_bindgen_ty_2 = 70; 245 | pub const KernelError_InvalidSize: root::_bindgen_ty_2 = 101; 246 | pub const KernelError_InvalidAddress: root::_bindgen_ty_2 = 102; 247 | pub const KernelError_ResourceExhausted: root::_bindgen_ty_2 = 103; 248 | pub const KernelError_OutOfMemory: root::_bindgen_ty_2 = 104; 249 | pub const KernelError_OutOfHandles: root::_bindgen_ty_2 = 105; 250 | pub const KernelError_InvalidMemoryState: root::_bindgen_ty_2 = 106; 251 | pub const KernelError_InvalidMemoryPermissions: root::_bindgen_ty_2 = 108; 252 | pub const KernelError_InvalidMemoryRange: root::_bindgen_ty_2 = 110; 253 | pub const KernelError_InvalidPriority: root::_bindgen_ty_2 = 112; 254 | pub const KernelError_InvalidCoreId: root::_bindgen_ty_2 = 113; 255 | pub const KernelError_InvalidHandle: root::_bindgen_ty_2 = 114; 256 | pub const KernelError_InvalidUserBuffer: root::_bindgen_ty_2 = 115; 257 | pub const KernelError_InvalidCombination: root::_bindgen_ty_2 = 116; 258 | pub const KernelError_TimedOut: root::_bindgen_ty_2 = 117; 259 | pub const KernelError_Cancelled: root::_bindgen_ty_2 = 118; 260 | pub const KernelError_OutOfRange: root::_bindgen_ty_2 = 119; 261 | pub const KernelError_InvalidEnumValue: root::_bindgen_ty_2 = 120; 262 | pub const KernelError_NotFound: root::_bindgen_ty_2 = 121; 263 | pub const KernelError_AlreadyExists: root::_bindgen_ty_2 = 122; 264 | pub const KernelError_ConnectionClosed: root::_bindgen_ty_2 = 123; 265 | pub const KernelError_UnhandledUserInterrupt: root::_bindgen_ty_2 = 124; 266 | pub const KernelError_InvalidState: root::_bindgen_ty_2 = 125; 267 | pub const KernelError_ReservedValue: root::_bindgen_ty_2 = 126; 268 | pub const KernelError_InvalidHwBreakpoint: root::_bindgen_ty_2 = 127; 269 | pub const KernelError_FatalUserException: root::_bindgen_ty_2 = 128; 270 | pub const KernelError_OwnedByAnotherProcess: root::_bindgen_ty_2 = 129; 271 | pub const KernelError_ConnectionRefused: root::_bindgen_ty_2 = 131; 272 | pub const KernelError_OutOfResource: root::_bindgen_ty_2 = 132; 273 | pub const KernelError_IpcMapFailed: root::_bindgen_ty_2 = 259; 274 | pub const KernelError_IpcCmdbufTooSmall: root::_bindgen_ty_2 = 260; 275 | pub const KernelError_NotDebugged: root::_bindgen_ty_2 = 520; 276 | #[doc = " Kernel error codes"] 277 | pub type _bindgen_ty_2 = u32; 278 | pub const LibnxError_BadReloc: root::_bindgen_ty_3 = 1; 279 | pub const LibnxError_OutOfMemory: root::_bindgen_ty_3 = 2; 280 | pub const LibnxError_AlreadyMapped: root::_bindgen_ty_3 = 3; 281 | pub const LibnxError_BadGetInfo_Stack: root::_bindgen_ty_3 = 4; 282 | pub const LibnxError_BadGetInfo_Heap: root::_bindgen_ty_3 = 5; 283 | pub const LibnxError_BadQueryMemory: root::_bindgen_ty_3 = 6; 284 | pub const LibnxError_AlreadyInitialized: root::_bindgen_ty_3 = 7; 285 | pub const LibnxError_NotInitialized: root::_bindgen_ty_3 = 8; 286 | pub const LibnxError_NotFound: root::_bindgen_ty_3 = 9; 287 | pub const LibnxError_IoError: root::_bindgen_ty_3 = 10; 288 | pub const LibnxError_BadInput: root::_bindgen_ty_3 = 11; 289 | pub const LibnxError_BadReent: root::_bindgen_ty_3 = 12; 290 | pub const LibnxError_BufferProducerError: root::_bindgen_ty_3 = 13; 291 | pub const LibnxError_HandleTooEarly: root::_bindgen_ty_3 = 14; 292 | pub const LibnxError_HeapAllocFailed: root::_bindgen_ty_3 = 15; 293 | pub const LibnxError_TooManyOverrides: root::_bindgen_ty_3 = 16; 294 | pub const LibnxError_ParcelError: root::_bindgen_ty_3 = 17; 295 | pub const LibnxError_BadGfxInit: root::_bindgen_ty_3 = 18; 296 | pub const LibnxError_BadGfxEventWait: root::_bindgen_ty_3 = 19; 297 | pub const LibnxError_BadGfxQueueBuffer: root::_bindgen_ty_3 = 20; 298 | pub const LibnxError_BadGfxDequeueBuffer: root::_bindgen_ty_3 = 21; 299 | pub const LibnxError_AppletCmdidNotFound: root::_bindgen_ty_3 = 22; 300 | pub const LibnxError_BadAppletReceiveMessage: root::_bindgen_ty_3 = 23; 301 | pub const LibnxError_BadAppletNotifyRunning: root::_bindgen_ty_3 = 24; 302 | pub const LibnxError_BadAppletGetCurrentFocusState: root::_bindgen_ty_3 = 25; 303 | pub const LibnxError_BadAppletGetOperationMode: root::_bindgen_ty_3 = 26; 304 | pub const LibnxError_BadAppletGetPerformanceMode: root::_bindgen_ty_3 = 27; 305 | pub const LibnxError_BadUsbCommsRead: root::_bindgen_ty_3 = 28; 306 | pub const LibnxError_BadUsbCommsWrite: root::_bindgen_ty_3 = 29; 307 | pub const LibnxError_InitFail_SM: root::_bindgen_ty_3 = 30; 308 | pub const LibnxError_InitFail_AM: root::_bindgen_ty_3 = 31; 309 | pub const LibnxError_InitFail_HID: root::_bindgen_ty_3 = 32; 310 | pub const LibnxError_InitFail_FS: root::_bindgen_ty_3 = 33; 311 | pub const LibnxError_BadGetInfo_Rng: root::_bindgen_ty_3 = 34; 312 | pub const LibnxError_JitUnavailable: root::_bindgen_ty_3 = 35; 313 | pub const LibnxError_WeirdKernel: root::_bindgen_ty_3 = 36; 314 | pub const LibnxError_IncompatSysVer: root::_bindgen_ty_3 = 37; 315 | pub const LibnxError_InitFail_Time: root::_bindgen_ty_3 = 38; 316 | pub const LibnxError_TooManyDevOpTabs: root::_bindgen_ty_3 = 39; 317 | pub const LibnxError_DomainMessageUnknownType: root::_bindgen_ty_3 = 40; 318 | pub const LibnxError_DomainMessageTooManyObjectIds: root::_bindgen_ty_3 = 41; 319 | pub const LibnxError_AppletFailedToInitialize: root::_bindgen_ty_3 = 42; 320 | pub const LibnxError_ApmFailedToInitialize: root::_bindgen_ty_3 = 43; 321 | pub const LibnxError_NvinfoFailedToInitialize: root::_bindgen_ty_3 = 44; 322 | pub const LibnxError_NvbufFailedToInitialize: root::_bindgen_ty_3 = 45; 323 | pub const LibnxError_LibAppletBadExit: root::_bindgen_ty_3 = 46; 324 | pub const LibnxError_InvalidCmifOutHeader: root::_bindgen_ty_3 = 47; 325 | pub const LibnxError_ShouldNotHappen: root::_bindgen_ty_3 = 48; 326 | #[doc = " libnx error codes"] 327 | pub type _bindgen_ty_3 = u32; 328 | pub const LibnxBinderError_Unknown: root::_bindgen_ty_4 = 1; 329 | pub const LibnxBinderError_NoMemory: root::_bindgen_ty_4 = 2; 330 | pub const LibnxBinderError_InvalidOperation: root::_bindgen_ty_4 = 3; 331 | pub const LibnxBinderError_BadValue: root::_bindgen_ty_4 = 4; 332 | pub const LibnxBinderError_BadType: root::_bindgen_ty_4 = 5; 333 | pub const LibnxBinderError_NameNotFound: root::_bindgen_ty_4 = 6; 334 | pub const LibnxBinderError_PermissionDenied: root::_bindgen_ty_4 = 7; 335 | pub const LibnxBinderError_NoInit: root::_bindgen_ty_4 = 8; 336 | pub const LibnxBinderError_AlreadyExists: root::_bindgen_ty_4 = 9; 337 | pub const LibnxBinderError_DeadObject: root::_bindgen_ty_4 = 10; 338 | pub const LibnxBinderError_FailedTransaction: root::_bindgen_ty_4 = 11; 339 | pub const LibnxBinderError_BadIndex: root::_bindgen_ty_4 = 12; 340 | pub const LibnxBinderError_NotEnoughData: root::_bindgen_ty_4 = 13; 341 | pub const LibnxBinderError_WouldBlock: root::_bindgen_ty_4 = 14; 342 | pub const LibnxBinderError_TimedOut: root::_bindgen_ty_4 = 15; 343 | pub const LibnxBinderError_UnknownTransaction: root::_bindgen_ty_4 = 16; 344 | pub const LibnxBinderError_FdsNotAllowed: root::_bindgen_ty_4 = 17; 345 | #[doc = " libnx binder error codes"] 346 | pub type _bindgen_ty_4 = u32; 347 | pub const LibnxNvidiaError_Unknown: root::_bindgen_ty_5 = 1; 348 | #[doc = "< Maps to Nvidia: 1"] 349 | pub const LibnxNvidiaError_NotImplemented: root::_bindgen_ty_5 = 2; 350 | #[doc = "< Maps to Nvidia: 2"] 351 | pub const LibnxNvidiaError_NotSupported: root::_bindgen_ty_5 = 3; 352 | #[doc = "< Maps to Nvidia: 3"] 353 | pub const LibnxNvidiaError_NotInitialized: root::_bindgen_ty_5 = 4; 354 | #[doc = "< Maps to Nvidia: 4"] 355 | pub const LibnxNvidiaError_BadParameter: root::_bindgen_ty_5 = 5; 356 | #[doc = "< Maps to Nvidia: 5"] 357 | pub const LibnxNvidiaError_Timeout: root::_bindgen_ty_5 = 6; 358 | #[doc = "< Maps to Nvidia: 6"] 359 | pub const LibnxNvidiaError_InsufficientMemory: root::_bindgen_ty_5 = 7; 360 | #[doc = "< Maps to Nvidia: 7"] 361 | pub const LibnxNvidiaError_ReadOnlyAttribute: root::_bindgen_ty_5 = 8; 362 | #[doc = "< Maps to Nvidia: 8"] 363 | pub const LibnxNvidiaError_InvalidState: root::_bindgen_ty_5 = 9; 364 | #[doc = "< Maps to Nvidia: 9"] 365 | pub const LibnxNvidiaError_InvalidAddress: root::_bindgen_ty_5 = 10; 366 | #[doc = "< Maps to Nvidia: 10"] 367 | pub const LibnxNvidiaError_InvalidSize: root::_bindgen_ty_5 = 11; 368 | #[doc = "< Maps to Nvidia: 11"] 369 | pub const LibnxNvidiaError_BadValue: root::_bindgen_ty_5 = 12; 370 | #[doc = "< Maps to Nvidia: 13"] 371 | pub const LibnxNvidiaError_AlreadyAllocated: root::_bindgen_ty_5 = 13; 372 | #[doc = "< Maps to Nvidia: 14"] 373 | pub const LibnxNvidiaError_Busy: root::_bindgen_ty_5 = 14; 374 | #[doc = "< Maps to Nvidia: 15"] 375 | pub const LibnxNvidiaError_ResourceError: root::_bindgen_ty_5 = 15; 376 | #[doc = "< Maps to Nvidia: 16"] 377 | pub const LibnxNvidiaError_CountMismatch: root::_bindgen_ty_5 = 16; 378 | #[doc = "< Maps to Nvidia: 0x1000"] 379 | pub const LibnxNvidiaError_SharedMemoryTooSmall: root::_bindgen_ty_5 = 17; 380 | #[doc = "< Maps to Nvidia: 0x30003"] 381 | pub const LibnxNvidiaError_FileOperationFailed: root::_bindgen_ty_5 = 18; 382 | #[doc = "< Maps to Nvidia: 0x3000F"] 383 | pub const LibnxNvidiaError_IoctlFailed: root::_bindgen_ty_5 = 19; 384 | #[doc = " libnx nvidia error codes"] 385 | pub type _bindgen_ty_5 = u32; 386 | 387 | #[repr(C)] 388 | pub struct nnosMutexType { 389 | pub curState: u8, 390 | pub isRecursiveMutex: bool, 391 | pub lockLevel: root::s32, 392 | pub _6: [u8; 18usize], 393 | } 394 | 395 | pub type Elf32_Half = u16; 396 | pub type Elf64_Half = u16; 397 | pub type Elf32_Word = u32; 398 | pub type Elf32_Sword = i32; 399 | pub type Elf64_Word = u32; 400 | pub type Elf64_Sword = i32; 401 | pub type Elf32_Xword = u64; 402 | pub type Elf32_Sxword = i64; 403 | pub type Elf64_Xword = u64; 404 | pub type Elf64_Sxword = i64; 405 | pub type Elf32_Addr = u32; 406 | pub type Elf64_Addr = u64; 407 | pub type Elf32_Off = u32; 408 | pub type Elf64_Off = u64; 409 | pub type Elf32_Section = u16; 410 | pub type Elf64_Section = u16; 411 | pub type Elf32_Versym = root::Elf32_Half; 412 | pub type Elf64_Versym = root::Elf64_Half; 413 | #[repr(C)] 414 | #[derive(Debug, Copy, Clone)] 415 | pub struct Elf32_Ehdr { 416 | pub e_ident: [u8; 16usize], 417 | pub e_type: root::Elf32_Half, 418 | pub e_machine: root::Elf32_Half, 419 | pub e_version: root::Elf32_Word, 420 | pub e_entry: root::Elf32_Addr, 421 | pub e_phoff: root::Elf32_Off, 422 | pub e_shoff: root::Elf32_Off, 423 | pub e_flags: root::Elf32_Word, 424 | pub e_ehsize: root::Elf32_Half, 425 | pub e_phentsize: root::Elf32_Half, 426 | pub e_phnum: root::Elf32_Half, 427 | pub e_shentsize: root::Elf32_Half, 428 | pub e_shnum: root::Elf32_Half, 429 | pub e_shstrndx: root::Elf32_Half, 430 | } 431 | #[repr(C)] 432 | #[derive(Debug, Copy, Clone)] 433 | pub struct Elf64_Ehdr { 434 | pub e_ident: [u8; 16usize], 435 | pub e_type: root::Elf64_Half, 436 | pub e_machine: root::Elf64_Half, 437 | pub e_version: root::Elf64_Word, 438 | pub e_entry: root::Elf64_Addr, 439 | pub e_phoff: root::Elf64_Off, 440 | pub e_shoff: root::Elf64_Off, 441 | pub e_flags: root::Elf64_Word, 442 | pub e_ehsize: root::Elf64_Half, 443 | pub e_phentsize: root::Elf64_Half, 444 | pub e_phnum: root::Elf64_Half, 445 | pub e_shentsize: root::Elf64_Half, 446 | pub e_shnum: root::Elf64_Half, 447 | pub e_shstrndx: root::Elf64_Half, 448 | } 449 | 450 | #[repr(C)] 451 | #[derive(Debug, Copy, Clone)] 452 | pub struct Elf32_Shdr { 453 | pub sh_name: root::Elf32_Word, 454 | pub sh_type: root::Elf32_Word, 455 | pub sh_flags: root::Elf32_Word, 456 | pub sh_addr: root::Elf32_Addr, 457 | pub sh_offset: root::Elf32_Off, 458 | pub sh_size: root::Elf32_Word, 459 | pub sh_link: root::Elf32_Word, 460 | pub sh_info: root::Elf32_Word, 461 | pub sh_addralign: root::Elf32_Word, 462 | pub sh_entsize: root::Elf32_Word, 463 | } 464 | 465 | #[repr(C)] 466 | #[derive(Debug, Copy, Clone)] 467 | pub struct Elf64_Shdr { 468 | pub sh_name: root::Elf64_Word, 469 | pub sh_type: root::Elf64_Word, 470 | pub sh_flags: root::Elf64_Xword, 471 | pub sh_addr: root::Elf64_Addr, 472 | pub sh_offset: root::Elf64_Off, 473 | pub sh_size: root::Elf64_Xword, 474 | pub sh_link: root::Elf64_Word, 475 | pub sh_info: root::Elf64_Word, 476 | pub sh_addralign: root::Elf64_Xword, 477 | pub sh_entsize: root::Elf64_Xword, 478 | } 479 | 480 | #[repr(C)] 481 | #[derive(Debug, Copy, Clone)] 482 | pub struct Elf32_Chdr { 483 | pub ch_type: root::Elf32_Word, 484 | pub ch_size: root::Elf32_Word, 485 | pub ch_addralign: root::Elf32_Word, 486 | } 487 | #[repr(C)] 488 | #[derive(Debug, Copy, Clone)] 489 | pub struct Elf64_Chdr { 490 | pub ch_type: root::Elf64_Word, 491 | pub ch_reserved: root::Elf64_Word, 492 | pub ch_size: root::Elf64_Xword, 493 | pub ch_addralign: root::Elf64_Xword, 494 | } 495 | #[repr(C)] 496 | #[derive(Debug, Copy, Clone)] 497 | pub struct Elf32_Sym { 498 | pub st_name: root::Elf32_Word, 499 | pub st_value: root::Elf32_Addr, 500 | pub st_size: root::Elf32_Word, 501 | pub st_info: u8, 502 | pub st_other: u8, 503 | pub st_shndx: root::Elf32_Section, 504 | } 505 | #[repr(C)] 506 | #[derive(Debug, Copy, Clone)] 507 | pub struct Elf64_Sym { 508 | pub st_name: root::Elf64_Word, 509 | pub st_info: u8, 510 | pub st_other: u8, 511 | pub st_shndx: root::Elf64_Section, 512 | pub st_value: root::Elf64_Addr, 513 | pub st_size: root::Elf64_Xword, 514 | } 515 | 516 | #[repr(C)] 517 | #[derive(Debug, Copy, Clone)] 518 | pub struct Elf32_Syminfo { 519 | pub si_boundto: root::Elf32_Half, 520 | pub si_flags: root::Elf32_Half, 521 | } 522 | 523 | #[repr(C)] 524 | #[derive(Debug, Copy, Clone)] 525 | pub struct Elf64_Syminfo { 526 | pub si_boundto: root::Elf64_Half, 527 | pub si_flags: root::Elf64_Half, 528 | } 529 | 530 | #[repr(C)] 531 | #[derive(Debug, Copy, Clone)] 532 | pub struct Elf32_Rel { 533 | pub r_offset: root::Elf32_Addr, 534 | pub r_info: root::Elf32_Word, 535 | } 536 | #[repr(C)] 537 | #[derive(Debug, Copy, Clone)] 538 | pub struct Elf64_Rel { 539 | pub r_offset: root::Elf64_Addr, 540 | pub r_info: root::Elf64_Xword, 541 | } 542 | 543 | #[repr(C)] 544 | #[derive(Debug, Copy, Clone)] 545 | pub struct Elf32_Rela { 546 | pub r_offset: root::Elf32_Addr, 547 | pub r_info: root::Elf32_Word, 548 | pub r_addend: root::Elf32_Sword, 549 | } 550 | 551 | #[repr(C)] 552 | #[derive(Debug, Copy, Clone)] 553 | pub struct Elf64_Rela { 554 | pub r_offset: root::Elf64_Addr, 555 | pub r_info: root::Elf64_Xword, 556 | pub r_addend: root::Elf64_Sxword, 557 | } 558 | #[repr(C)] 559 | #[derive(Debug, Copy, Clone)] 560 | pub struct Elf32_Phdr { 561 | pub p_type: root::Elf32_Word, 562 | pub p_offset: root::Elf32_Off, 563 | pub p_vaddr: root::Elf32_Addr, 564 | pub p_paddr: root::Elf32_Addr, 565 | pub p_filesz: root::Elf32_Word, 566 | pub p_memsz: root::Elf32_Word, 567 | pub p_flags: root::Elf32_Word, 568 | pub p_align: root::Elf32_Word, 569 | } 570 | 571 | pub struct Elf64_Phdr { 572 | pub p_type: root::Elf64_Word, 573 | pub p_flags: root::Elf64_Word, 574 | pub p_offset: root::Elf64_Off, 575 | pub p_vaddr: root::Elf64_Addr, 576 | pub p_paddr: root::Elf64_Addr, 577 | pub p_filesz: root::Elf64_Xword, 578 | pub p_memsz: root::Elf64_Xword, 579 | pub p_align: root::Elf64_Xword, 580 | } 581 | 582 | #[repr(C)] 583 | #[derive(Copy, Clone)] 584 | pub struct Elf32_Dyn { 585 | pub d_tag: root::Elf32_Sword, 586 | pub d_un: root::Elf32_Dyn__bindgen_ty_1, 587 | } 588 | #[repr(C)] 589 | #[derive(Copy, Clone)] 590 | pub union Elf32_Dyn__bindgen_ty_1 { 591 | pub d_val: root::Elf32_Word, 592 | pub d_ptr: root::Elf32_Addr, 593 | _bindgen_union_align: u32, 594 | } 595 | 596 | #[repr(C)] 597 | #[derive(Copy, Clone)] 598 | pub struct Elf64_Dyn { 599 | pub d_tag: root::Elf64_Sxword, 600 | pub d_un: root::Elf64_Dyn__bindgen_ty_1, 601 | } 602 | #[repr(C)] 603 | #[derive(Copy, Clone)] 604 | pub union Elf64_Dyn__bindgen_ty_1 { 605 | pub d_val: root::Elf64_Xword, 606 | pub d_ptr: root::Elf64_Addr, 607 | _bindgen_union_align: u64, 608 | } 609 | 610 | #[repr(C)] 611 | #[derive(Debug, Copy, Clone)] 612 | pub struct Elf32_Verdef { 613 | pub vd_version: root::Elf32_Half, 614 | pub vd_flags: root::Elf32_Half, 615 | pub vd_ndx: root::Elf32_Half, 616 | pub vd_cnt: root::Elf32_Half, 617 | pub vd_hash: root::Elf32_Word, 618 | pub vd_aux: root::Elf32_Word, 619 | pub vd_next: root::Elf32_Word, 620 | } 621 | 622 | #[repr(C)] 623 | #[derive(Debug, Copy, Clone)] 624 | pub struct Elf64_Verdef { 625 | pub vd_version: root::Elf64_Half, 626 | pub vd_flags: root::Elf64_Half, 627 | pub vd_ndx: root::Elf64_Half, 628 | pub vd_cnt: root::Elf64_Half, 629 | pub vd_hash: root::Elf64_Word, 630 | pub vd_aux: root::Elf64_Word, 631 | pub vd_next: root::Elf64_Word, 632 | } 633 | #[repr(C)] 634 | #[derive(Debug, Copy, Clone)] 635 | pub struct Elf32_Verdaux { 636 | pub vda_name: root::Elf32_Word, 637 | pub vda_next: root::Elf32_Word, 638 | } 639 | 640 | #[repr(C)] 641 | #[derive(Debug, Copy, Clone)] 642 | pub struct Elf64_Verdaux { 643 | pub vda_name: root::Elf64_Word, 644 | pub vda_next: root::Elf64_Word, 645 | } 646 | 647 | #[repr(C)] 648 | #[derive(Debug, Copy, Clone)] 649 | pub struct Elf32_Verneed { 650 | pub vn_version: root::Elf32_Half, 651 | pub vn_cnt: root::Elf32_Half, 652 | pub vn_file: root::Elf32_Word, 653 | pub vn_aux: root::Elf32_Word, 654 | pub vn_next: root::Elf32_Word, 655 | } 656 | #[repr(C)] 657 | #[derive(Debug, Copy, Clone)] 658 | pub struct Elf64_Verneed { 659 | pub vn_version: root::Elf64_Half, 660 | pub vn_cnt: root::Elf64_Half, 661 | pub vn_file: root::Elf64_Word, 662 | pub vn_aux: root::Elf64_Word, 663 | pub vn_next: root::Elf64_Word, 664 | } 665 | #[repr(C)] 666 | #[derive(Debug, Copy, Clone)] 667 | pub struct Elf32_Vernaux { 668 | pub vna_hash: root::Elf32_Word, 669 | pub vna_flags: root::Elf32_Half, 670 | pub vna_other: root::Elf32_Half, 671 | pub vna_name: root::Elf32_Word, 672 | pub vna_next: root::Elf32_Word, 673 | } 674 | #[repr(C)] 675 | #[derive(Debug, Copy, Clone)] 676 | pub struct Elf64_Vernaux { 677 | pub vna_hash: root::Elf64_Word, 678 | pub vna_flags: root::Elf64_Half, 679 | pub vna_other: root::Elf64_Half, 680 | pub vna_name: root::Elf64_Word, 681 | pub vna_next: root::Elf64_Word, 682 | } 683 | #[repr(C)] 684 | #[derive(Copy, Clone)] 685 | pub struct Elf32_auxv_t { 686 | pub a_type: u32, 687 | pub a_un: root::Elf32_auxv_t__bindgen_ty_1, 688 | } 689 | #[repr(C)] 690 | #[derive(Copy, Clone)] 691 | pub union Elf32_auxv_t__bindgen_ty_1 { 692 | pub a_val: u32, 693 | _bindgen_union_align: u32, 694 | } 695 | 696 | #[repr(C)] 697 | #[derive(Copy, Clone)] 698 | pub struct Elf64_auxv_t { 699 | pub a_type: u64, 700 | pub a_un: root::Elf64_auxv_t__bindgen_ty_1, 701 | } 702 | #[repr(C)] 703 | #[derive(Copy, Clone)] 704 | pub union Elf64_auxv_t__bindgen_ty_1 { 705 | pub a_val: u64, 706 | _bindgen_union_align: u64, 707 | } 708 | 709 | #[repr(C)] 710 | #[derive(Debug, Copy, Clone)] 711 | pub struct Elf32_Nhdr { 712 | pub n_namesz: root::Elf32_Word, 713 | pub n_descsz: root::Elf32_Word, 714 | pub n_type: root::Elf32_Word, 715 | } 716 | #[repr(C)] 717 | #[derive(Debug, Copy, Clone)] 718 | pub struct Elf64_Nhdr { 719 | pub n_namesz: root::Elf64_Word, 720 | pub n_descsz: root::Elf64_Word, 721 | pub n_type: root::Elf64_Word, 722 | } 723 | 724 | #[repr(C)] 725 | #[derive(Debug, Copy, Clone)] 726 | pub struct Elf32_Move { 727 | pub m_value: root::Elf32_Xword, 728 | pub m_info: root::Elf32_Word, 729 | pub m_poffset: root::Elf32_Word, 730 | pub m_repeat: root::Elf32_Half, 731 | pub m_stride: root::Elf32_Half, 732 | } 733 | #[repr(C)] 734 | #[derive(Debug, Copy, Clone)] 735 | pub struct Elf64_Move { 736 | pub m_value: root::Elf64_Xword, 737 | pub m_info: root::Elf64_Xword, 738 | pub m_poffset: root::Elf64_Xword, 739 | pub m_repeat: root::Elf64_Half, 740 | pub m_stride: root::Elf64_Half, 741 | } 742 | #[repr(C)] 743 | #[derive(Copy, Clone)] 744 | pub union Elf32_gptab { 745 | pub gt_header: root::Elf32_gptab__bindgen_ty_1, 746 | pub gt_entry: root::Elf32_gptab__bindgen_ty_2, 747 | _bindgen_union_align: [u32; 2usize], 748 | } 749 | #[repr(C)] 750 | #[derive(Debug, Copy, Clone)] 751 | pub struct Elf32_gptab__bindgen_ty_1 { 752 | pub gt_current_g_value: root::Elf32_Word, 753 | pub gt_unused: root::Elf32_Word, 754 | } 755 | #[repr(C)] 756 | #[derive(Debug, Copy, Clone)] 757 | pub struct Elf32_gptab__bindgen_ty_2 { 758 | pub gt_g_value: root::Elf32_Word, 759 | pub gt_bytes: root::Elf32_Word, 760 | } 761 | #[repr(C)] 762 | #[derive(Debug, Copy, Clone)] 763 | pub struct Elf32_RegInfo { 764 | pub ri_gprmask: root::Elf32_Word, 765 | pub ri_cprmask: [root::Elf32_Word; 4usize], 766 | pub ri_gp_value: root::Elf32_Sword, 767 | } 768 | #[repr(C)] 769 | #[derive(Debug, Copy, Clone)] 770 | pub struct Elf_Options { 771 | pub kind: u8, 772 | pub size: u8, 773 | pub section: root::Elf32_Section, 774 | pub info: root::Elf32_Word, 775 | } 776 | #[repr(C)] 777 | #[derive(Debug, Copy, Clone)] 778 | pub struct Elf_Options_Hw { 779 | pub hwp_flags1: root::Elf32_Word, 780 | pub hwp_flags2: root::Elf32_Word, 781 | } 782 | #[repr(C)] 783 | #[derive(Debug, Copy, Clone)] 784 | pub struct Elf32_Lib { 785 | pub l_name: root::Elf32_Word, 786 | pub l_time_stamp: root::Elf32_Word, 787 | pub l_checksum: root::Elf32_Word, 788 | pub l_version: root::Elf32_Word, 789 | pub l_flags: root::Elf32_Word, 790 | } 791 | #[repr(C)] 792 | #[derive(Debug, Copy, Clone)] 793 | pub struct Elf64_Lib { 794 | pub l_name: root::Elf64_Word, 795 | pub l_time_stamp: root::Elf64_Word, 796 | pub l_checksum: root::Elf64_Word, 797 | pub l_version: root::Elf64_Word, 798 | pub l_flags: root::Elf64_Word, 799 | } 800 | pub type Elf32_Conflict = root::Elf32_Addr; 801 | #[repr(C)] 802 | #[derive(Debug, Copy, Clone)] 803 | pub struct Elf_MIPS_ABIFlags_v0 { 804 | pub version: root::Elf32_Half, 805 | pub isa_level: u8, 806 | pub isa_rev: u8, 807 | pub gpr_size: u8, 808 | pub cpr1_size: u8, 809 | pub cpr2_size: u8, 810 | pub fp_abi: u8, 811 | pub isa_ext: root::Elf32_Word, 812 | pub ases: root::Elf32_Word, 813 | pub flags1: root::Elf32_Word, 814 | pub flags2: root::Elf32_Word, 815 | } 816 | pub const Val_GNU_MIPS_ABI_FP_ANY: root::_bindgen_ty_6 = 0; 817 | pub const Val_GNU_MIPS_ABI_FP_DOUBLE: root::_bindgen_ty_6 = 1; 818 | pub const Val_GNU_MIPS_ABI_FP_SINGLE: root::_bindgen_ty_6 = 2; 819 | pub const Val_GNU_MIPS_ABI_FP_SOFT: root::_bindgen_ty_6 = 3; 820 | pub const Val_GNU_MIPS_ABI_FP_OLD_64: root::_bindgen_ty_6 = 4; 821 | pub const Val_GNU_MIPS_ABI_FP_XX: root::_bindgen_ty_6 = 5; 822 | pub const Val_GNU_MIPS_ABI_FP_64: root::_bindgen_ty_6 = 6; 823 | pub const Val_GNU_MIPS_ABI_FP_64A: root::_bindgen_ty_6 = 7; 824 | pub const Val_GNU_MIPS_ABI_FP_MAX: root::_bindgen_ty_6 = 7; 825 | pub type _bindgen_ty_6 = u32; 826 | 827 | #[repr(C)] 828 | #[derive(Debug, Copy, Clone)] 829 | pub struct iovec { 830 | pub iov_base: *mut u8, 831 | pub iov_len: root::size_t, 832 | } 833 | pub type u_char = root::__u_char; 834 | pub type u_short = root::__u_short; 835 | pub type u_int = root::__u_int; 836 | pub type u_long = root::__u_long; 837 | pub type quad_t = root::__quad_t; 838 | pub type u_quad_t = root::__u_quad_t; 839 | pub type fsid_t = root::__fsid_t; 840 | pub type loff_t = root::__loff_t; 841 | pub type ino_t = root::__ino_t; 842 | pub type ino64_t = root::__ino64_t; 843 | pub type dev_t = root::__dev_t; 844 | pub type gid_t = root::__gid_t; 845 | pub type mode_t = root::__mode_t; 846 | pub type nlink_t = root::__nlink_t; 847 | pub type uid_t = root::__uid_t; 848 | pub type off_t = root::__off_t; 849 | pub type off64_t = root::__off64_t; 850 | pub type pid_t = root::__pid_t; 851 | pub type id_t = root::__id_t; 852 | pub type ssize_t = root::__ssize_t; 853 | pub type daddr_t = root::__daddr_t; 854 | pub type caddr_t = root::__caddr_t; 855 | pub type key_t = root::__key_t; 856 | pub type clock_t = root::__clock_t; 857 | pub type clockid_t = root::__clockid_t; 858 | pub type time_t = root::__time_t; 859 | pub type timer_t = root::__timer_t; 860 | pub type useconds_t = root::__useconds_t; 861 | pub type suseconds_t = root::__suseconds_t; 862 | pub type ushort = u16; 863 | pub type u_int8_t = root::__uint8_t; 864 | pub type u_int16_t = root::__uint16_t; 865 | pub type u_int32_t = root::__uint32_t; 866 | pub type u_int64_t = root::__uint64_t; 867 | pub type register_t = i64; 868 | #[repr(C)] 869 | #[derive(Debug, Copy, Clone)] 870 | pub struct __sigset_t { 871 | pub __val: [u64; 16usize], 872 | } 873 | pub type sigset_t = root::__sigset_t; 874 | #[repr(C)] 875 | #[derive(Debug, Copy, Clone)] 876 | pub struct timeval { 877 | pub tv_sec: root::__time_t, 878 | pub tv_usec: root::__suseconds_t, 879 | } 880 | #[repr(C)] 881 | #[derive(Debug, Copy, Clone)] 882 | pub struct timespec { 883 | pub tv_sec: root::__time_t, 884 | pub tv_nsec: root::__syscall_slong_t, 885 | } 886 | pub type __fd_mask = i64; 887 | #[repr(C)] 888 | #[derive(Debug, Copy, Clone)] 889 | pub struct fd_set { 890 | pub fds_bits: [root::__fd_mask; 16usize], 891 | } 892 | pub type fd_mask = root::__fd_mask; 893 | pub type blksize_t = root::__blksize_t; 894 | pub type blkcnt_t = root::__blkcnt_t; 895 | pub type fsblkcnt_t = root::__fsblkcnt_t; 896 | pub type fsfilcnt_t = root::__fsfilcnt_t; 897 | pub type blkcnt64_t = root::__blkcnt64_t; 898 | pub type fsblkcnt64_t = root::__fsblkcnt64_t; 899 | pub type fsfilcnt64_t = root::__fsfilcnt64_t; 900 | #[repr(C)] 901 | #[derive(Debug, Copy, Clone)] 902 | pub struct __pthread_rwlock_arch_t { 903 | pub __readers: u32, 904 | pub __writers: u32, 905 | pub __wrphase_futex: u32, 906 | pub __writers_futex: u32, 907 | pub __pad3: u32, 908 | pub __pad4: u32, 909 | pub __cur_writer: i32, 910 | pub __shared: i32, 911 | pub __rwelision: i8, 912 | pub __pad1: [u8; 7usize], 913 | pub __pad2: u64, 914 | pub __flags: u32, 915 | } 916 | #[repr(C)] 917 | #[derive(Debug, Copy, Clone)] 918 | pub struct __pthread_internal_list { 919 | pub __prev: *mut root::__pthread_internal_list, 920 | pub __next: *mut root::__pthread_internal_list, 921 | } 922 | pub type __pthread_list_t = root::__pthread_internal_list; 923 | #[repr(C)] 924 | #[derive(Debug, Copy, Clone)] 925 | pub struct __pthread_mutex_s { 926 | pub __lock: i32, 927 | pub __count: u32, 928 | pub __owner: i32, 929 | pub __nusers: u32, 930 | pub __kind: i32, 931 | pub __spins: i16, 932 | pub __elision: i16, 933 | pub __list: root::__pthread_list_t, 934 | } 935 | #[repr(C)] 936 | #[derive(Copy, Clone)] 937 | pub struct __pthread_cond_s { 938 | pub __bindgen_anon_1: root::__pthread_cond_s__bindgen_ty_1, 939 | pub __bindgen_anon_2: root::__pthread_cond_s__bindgen_ty_2, 940 | pub __g_refs: [u32; 2usize], 941 | pub __g_size: [u32; 2usize], 942 | pub __g1_orig_size: u32, 943 | pub __wrefs: u32, 944 | pub __g_signals: [u32; 2usize], 945 | } 946 | #[repr(C)] 947 | #[derive(Copy, Clone)] 948 | pub union __pthread_cond_s__bindgen_ty_1 { 949 | pub __wseq: u64, 950 | pub __wseq32: root::__pthread_cond_s__bindgen_ty_1__bindgen_ty_1, 951 | _bindgen_union_align: u64, 952 | } 953 | #[repr(C)] 954 | #[derive(Debug, Copy, Clone)] 955 | pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { 956 | pub __low: u32, 957 | pub __high: u32, 958 | } 959 | #[repr(C)] 960 | #[derive(Copy, Clone)] 961 | pub union __pthread_cond_s__bindgen_ty_2 { 962 | pub __g1_start: u64, 963 | pub __g1_start32: root::__pthread_cond_s__bindgen_ty_2__bindgen_ty_1, 964 | _bindgen_union_align: u64, 965 | } 966 | #[repr(C)] 967 | #[derive(Debug, Copy, Clone)] 968 | pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { 969 | pub __low: u32, 970 | pub __high: u32, 971 | } 972 | pub type pthread_t = u64; 973 | #[repr(C)] 974 | #[derive(Copy, Clone)] 975 | pub union pthread_mutexattr_t { 976 | pub __size: [u8; 4usize], 977 | pub __align: i32, 978 | _bindgen_union_align: u32, 979 | } 980 | #[repr(C)] 981 | #[derive(Copy, Clone)] 982 | pub union pthread_condattr_t { 983 | pub __size: [u8; 4usize], 984 | pub __align: i32, 985 | _bindgen_union_align: u32, 986 | } 987 | pub type pthread_key_t = u32; 988 | pub type pthread_once_t = i32; 989 | #[repr(C)] 990 | #[derive(Copy, Clone)] 991 | pub union pthread_attr_t { 992 | pub __size: [u8; 56usize], 993 | pub __align: i64, 994 | _bindgen_union_align: [u64; 7usize], 995 | } 996 | #[repr(C)] 997 | #[derive(Copy, Clone)] 998 | pub union pthread_mutex_t { 999 | pub __data: root::__pthread_mutex_s, 1000 | pub __size: [u8; 40usize], 1001 | pub __align: i64, 1002 | _bindgen_union_align: [u64; 5usize], 1003 | } 1004 | #[repr(C)] 1005 | #[derive(Copy, Clone)] 1006 | pub union pthread_cond_t { 1007 | pub __data: root::__pthread_cond_s, 1008 | pub __size: [u8; 48usize], 1009 | pub __align: i64, 1010 | _bindgen_union_align: [u64; 6usize], 1011 | } 1012 | #[repr(C)] 1013 | #[derive(Copy, Clone)] 1014 | pub union pthread_rwlock_t { 1015 | pub __data: root::__pthread_rwlock_arch_t, 1016 | pub __size: [u8; 56usize], 1017 | pub __align: i64, 1018 | _bindgen_union_align: [u64; 7usize], 1019 | } 1020 | 1021 | #[repr(C)] 1022 | #[derive(Copy, Clone)] 1023 | pub union pthread_rwlockattr_t { 1024 | pub __size: [u8; 8usize], 1025 | pub __align: i64, 1026 | _bindgen_union_align: u64, 1027 | } 1028 | pub type pthread_spinlock_t = i32; 1029 | #[repr(C)] 1030 | #[derive(Copy, Clone)] 1031 | pub union pthread_barrier_t { 1032 | pub __size: [u8; 32usize], 1033 | pub __align: i64, 1034 | _bindgen_union_align: [u64; 4usize], 1035 | } 1036 | #[repr(C)] 1037 | #[derive(Copy, Clone)] 1038 | pub union pthread_barrierattr_t { 1039 | pub __size: [u8; 4usize], 1040 | pub __align: i32, 1041 | _bindgen_union_align: u32, 1042 | } 1043 | pub type socklen_t = root::__socklen_t; 1044 | pub const __socket_type_SOCK_STREAM: root::__socket_type = 1; 1045 | pub const __socket_type_SOCK_DGRAM: root::__socket_type = 2; 1046 | pub const __socket_type_SOCK_RAW: root::__socket_type = 3; 1047 | pub const __socket_type_SOCK_RDM: root::__socket_type = 4; 1048 | pub const __socket_type_SOCK_SEQPACKET: root::__socket_type = 5; 1049 | pub const __socket_type_SOCK_DCCP: root::__socket_type = 6; 1050 | pub const __socket_type_SOCK_PACKET: root::__socket_type = 10; 1051 | pub const __socket_type_SOCK_CLOEXEC: root::__socket_type = 524288; 1052 | pub const __socket_type_SOCK_NONBLOCK: root::__socket_type = 2048; 1053 | pub type __socket_type = u32; 1054 | pub type sa_family_t = u16; 1055 | #[repr(C)] 1056 | #[derive(Debug, Copy, Clone)] 1057 | pub struct sockaddr { 1058 | pub sa_family: root::sa_family_t, 1059 | pub sa_data: [u8; 14usize], 1060 | } 1061 | #[repr(C)] 1062 | #[derive(Copy, Clone)] 1063 | pub struct sockaddr_storage { 1064 | pub ss_family: root::sa_family_t, 1065 | pub __ss_padding: [u8; 118usize], 1066 | pub __ss_align: u64, 1067 | } 1068 | pub const MSG_OOB: root::_bindgen_ty_7 = 1; 1069 | pub const MSG_PEEK: root::_bindgen_ty_7 = 2; 1070 | pub const MSG_DONTROUTE: root::_bindgen_ty_7 = 4; 1071 | pub const MSG_TRYHARD: root::_bindgen_ty_7 = 4; 1072 | pub const MSG_CTRUNC: root::_bindgen_ty_7 = 8; 1073 | pub const MSG_PROXY: root::_bindgen_ty_7 = 16; 1074 | pub const MSG_TRUNC: root::_bindgen_ty_7 = 32; 1075 | pub const MSG_DONTWAIT: root::_bindgen_ty_7 = 64; 1076 | pub const MSG_EOR: root::_bindgen_ty_7 = 128; 1077 | pub const MSG_WAITALL: root::_bindgen_ty_7 = 256; 1078 | pub const MSG_FIN: root::_bindgen_ty_7 = 512; 1079 | pub const MSG_SYN: root::_bindgen_ty_7 = 1024; 1080 | pub const MSG_CONFIRM: root::_bindgen_ty_7 = 2048; 1081 | pub const MSG_RST: root::_bindgen_ty_7 = 4096; 1082 | pub const MSG_ERRQUEUE: root::_bindgen_ty_7 = 8192; 1083 | pub const MSG_NOSIGNAL: root::_bindgen_ty_7 = 16384; 1084 | pub const MSG_MORE: root::_bindgen_ty_7 = 32768; 1085 | pub const MSG_WAITFORONE: root::_bindgen_ty_7 = 65536; 1086 | pub const MSG_BATCH: root::_bindgen_ty_7 = 262144; 1087 | pub const MSG_ZEROCOPY: root::_bindgen_ty_7 = 67108864; 1088 | pub const MSG_FASTOPEN: root::_bindgen_ty_7 = 536870912; 1089 | pub const MSG_CMSG_CLOEXEC: root::_bindgen_ty_7 = 1073741824; 1090 | pub type _bindgen_ty_7 = u32; 1091 | #[repr(C)] 1092 | #[derive(Debug, Copy, Clone)] 1093 | pub struct msghdr { 1094 | pub msg_name: *mut u8, 1095 | pub msg_namelen: root::socklen_t, 1096 | pub msg_iov: *mut root::iovec, 1097 | pub msg_iovlen: root::size_t, 1098 | pub msg_control: *mut u8, 1099 | pub msg_controllen: root::size_t, 1100 | pub msg_flags: i32, 1101 | } 1102 | #[repr(C)] 1103 | #[derive(Debug)] 1104 | pub struct cmsghdr { 1105 | pub cmsg_len: root::size_t, 1106 | pub cmsg_level: i32, 1107 | pub cmsg_type: i32, 1108 | pub __cmsg_data: root::__IncompleteArrayField, 1109 | } 1110 | pub const SCM_RIGHTS: root::_bindgen_ty_8 = 1; 1111 | pub const SCM_CREDENTIALS: root::_bindgen_ty_8 = 2; 1112 | pub type _bindgen_ty_8 = u32; 1113 | #[repr(C)] 1114 | #[derive(Debug, Copy, Clone)] 1115 | pub struct ucred { 1116 | pub pid: root::pid_t, 1117 | pub uid: root::uid_t, 1118 | pub gid: root::gid_t, 1119 | } 1120 | #[repr(C)] 1121 | #[derive(Debug, Copy, Clone)] 1122 | pub struct __kernel_fd_set { 1123 | pub fds_bits: [u64; 16usize], 1124 | } 1125 | pub type __kernel_sighandler_t = 1126 | ::core::option::Option; 1127 | pub type __kernel_key_t = i32; 1128 | pub type __kernel_mqd_t = i32; 1129 | pub type __kernel_old_uid_t = u16; 1130 | pub type __kernel_old_gid_t = u16; 1131 | pub type __kernel_old_dev_t = u64; 1132 | pub type __kernel_long_t = i64; 1133 | pub type __kernel_ulong_t = u64; 1134 | pub type __kernel_ino_t = root::__kernel_ulong_t; 1135 | pub type __kernel_mode_t = u32; 1136 | pub type __kernel_pid_t = i32; 1137 | pub type __kernel_ipc_pid_t = i32; 1138 | pub type __kernel_uid_t = u32; 1139 | pub type __kernel_gid_t = u32; 1140 | pub type __kernel_suseconds_t = root::__kernel_long_t; 1141 | pub type __kernel_daddr_t = i32; 1142 | pub type __kernel_uid32_t = u32; 1143 | pub type __kernel_gid32_t = u32; 1144 | pub type __kernel_size_t = root::__kernel_ulong_t; 1145 | pub type __kernel_ssize_t = root::__kernel_long_t; 1146 | pub type __kernel_ptrdiff_t = root::__kernel_long_t; 1147 | #[repr(C)] 1148 | #[derive(Debug, Copy, Clone)] 1149 | pub struct __kernel_fsid_t { 1150 | pub val: [i32; 2usize], 1151 | } 1152 | pub type __kernel_off_t = root::__kernel_long_t; 1153 | pub type __kernel_loff_t = i64; 1154 | pub type __kernel_time_t = root::__kernel_long_t; 1155 | pub type __kernel_time64_t = i64; 1156 | pub type __kernel_clock_t = root::__kernel_long_t; 1157 | pub type __kernel_timer_t = i32; 1158 | pub type __kernel_clockid_t = i32; 1159 | pub type __kernel_caddr_t = *mut u8; 1160 | pub type __kernel_uid16_t = u16; 1161 | pub type __kernel_gid16_t = u16; 1162 | #[repr(C)] 1163 | #[derive(Debug, Copy, Clone)] 1164 | pub struct linger { 1165 | pub l_onoff: i32, 1166 | pub l_linger: i32, 1167 | } 1168 | #[repr(C)] 1169 | #[derive(Debug, Copy, Clone)] 1170 | pub struct osockaddr { 1171 | pub sa_family: u16, 1172 | pub sa_data: [u8; 14usize], 1173 | } 1174 | pub const SHUT_RD: root::_bindgen_ty_9 = 0; 1175 | pub const SHUT_WR: root::_bindgen_ty_9 = 1; 1176 | pub const SHUT_RDWR: root::_bindgen_ty_9 = 2; 1177 | pub type _bindgen_ty_9 = u32; 1178 | #[repr(C)] 1179 | #[derive(Debug, Copy, Clone)] 1180 | pub struct mmsghdr { 1181 | pub msg_hdr: root::msghdr, 1182 | pub msg_len: u32, 1183 | } 1184 | pub type __int128_t = i128; 1185 | pub type __uint128_t = u128; -------------------------------------------------------------------------------- /src/extensions.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | 3 | impl TimeSpan { 4 | pub fn nano(nanoseconds: u64) -> Self { 5 | TimeSpan { 6 | nanoseconds 7 | } 8 | } 9 | 10 | pub fn milli(milliseconds: u64) -> Self { 11 | TimeSpan { 12 | nanoseconds: milliseconds * 1000000 13 | } 14 | } 15 | 16 | pub fn secs(seconds: u64) -> Self { 17 | TimeSpan { 18 | nanoseconds: seconds * 1000000000u64 19 | } 20 | } 21 | 22 | pub fn minutes(minutes: u64) -> Self { 23 | TimeSpan::secs(minutes * 60) 24 | } 25 | 26 | pub fn hours(hours: u64) -> Self { 27 | TimeSpan::minutes(hours * 60) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![feature(repr_simd)] 3 | #![feature(new_uninit)] 4 | #![feature(new_zeroed_alloc)] 5 | 6 | #[cfg(not(feature = "rustc-dep-of-std"))] 7 | extern crate alloc; 8 | 9 | pub mod extensions; 10 | pub mod common_types; 11 | pub mod nn; 12 | pub mod rtld; 13 | 14 | #[doc(inline)] 15 | pub use root::nn::*; 16 | 17 | #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] 18 | #[doc(hidden)] 19 | pub mod root { 20 | pub use crate::common_types::*; 21 | #[allow(unused_imports)] 22 | pub use super::nn; 23 | pub use super::rtld; 24 | use self::super::root; 25 | 26 | extern "C" { 27 | pub fn main(argc: i32, argv: *mut *mut u8) -> i32; 28 | } 29 | extern "C" { 30 | pub fn nninitStartup(); 31 | } 32 | extern "C" { 33 | pub fn _init(); 34 | } 35 | extern "C" { 36 | pub fn _fini(); 37 | } 38 | extern "C" { 39 | pub fn __nnDetailNintendoSdkRuntimeObjectFileRefer(); 40 | } 41 | extern "C" { 42 | pub fn __nnDetailNintendoSdkRuntimeObjectFile(); 43 | } 44 | extern "C" { 45 | pub fn __nnDetailNintendoSdkNsoFileRefer(); 46 | } 47 | extern "C" { 48 | pub fn __nnmusl_init_dso_0(); 49 | } 50 | extern "C" { 51 | pub fn __nnmusl_fini_dso_0(); 52 | } 53 | extern "C" { 54 | pub fn __nnDetailNintendoSdkNsoFile_0(); 55 | } 56 | extern "C" { 57 | pub fn nnosInitializeMutex(arg1: *mut root::nnosMutexType, arg2: bool, arg3: root::s32); 58 | } 59 | extern "C" { 60 | pub fn nnosFinalizeMutex(arg1: *mut root::nnosMutexType); 61 | } 62 | extern "C" { 63 | pub fn nnosLockMutex(arg1: *mut root::nnosMutexType); 64 | } 65 | extern "C" { 66 | pub fn nnosTryLockMutex(arg1: *mut root::nnosMutexType) -> bool; 67 | } 68 | extern "C" { 69 | pub fn nnosUnlockMutex(arg1: *mut root::nnosMutexType); 70 | } 71 | extern "C" { 72 | pub fn llabs(n: i64) -> i64; 73 | } 74 | extern "C" { 75 | pub fn __assert_fail( 76 | __assertion: *const u8, 77 | __file: *const u8, 78 | __line: u32, 79 | __function: *const u8, 80 | ); 81 | } 82 | extern "C" { 83 | pub fn __assert_perror_fail( 84 | __errnum: i32, 85 | __file: *const u8, 86 | __line: u32, 87 | __function: *const u8, 88 | ); 89 | } 90 | extern "C" { 91 | pub fn __assert( 92 | __assertion: *const u8, 93 | __file: *const u8, 94 | __line: i32, 95 | ); 96 | } 97 | 98 | extern "C" { 99 | pub fn select( 100 | __nfds: i32, 101 | __readfds: *mut root::fd_set, 102 | __writefds: *mut root::fd_set, 103 | __exceptfds: *mut root::fd_set, 104 | __timeout: *mut root::timeval, 105 | ) -> i32; 106 | } 107 | extern "C" { 108 | pub fn pselect( 109 | __nfds: i32, 110 | __readfds: *mut root::fd_set, 111 | __writefds: *mut root::fd_set, 112 | __exceptfds: *mut root::fd_set, 113 | __timeout: *const root::timespec, 114 | __sigmask: *const root::__sigset_t, 115 | ) -> i32; 116 | } 117 | extern "C" { 118 | pub fn __cmsg_nxthdr( 119 | __mhdr: *mut root::msghdr, 120 | __cmsg: *mut root::cmsghdr, 121 | ) -> *mut root::cmsghdr; 122 | } 123 | 124 | extern "C" { 125 | pub fn socket( 126 | __domain: i32, 127 | __type: i32, 128 | __protocol: i32, 129 | ) -> i32; 130 | } 131 | extern "C" { 132 | pub fn socketpair( 133 | __domain: i32, 134 | __type: i32, 135 | __protocol: i32, 136 | __fds: *mut i32, 137 | ) -> i32; 138 | } 139 | extern "C" { 140 | pub fn bind( 141 | __fd: i32, 142 | __addr: *const root::sockaddr, 143 | __len: root::socklen_t, 144 | ) -> i32; 145 | } 146 | extern "C" { 147 | pub fn getsockname( 148 | __fd: i32, 149 | __addr: *mut root::sockaddr, 150 | __len: *mut root::socklen_t, 151 | ) -> i32; 152 | } 153 | extern "C" { 154 | pub fn connect( 155 | __fd: i32, 156 | __addr: *const root::sockaddr, 157 | __len: root::socklen_t, 158 | ) -> i32; 159 | } 160 | extern "C" { 161 | pub fn getpeername( 162 | __fd: i32, 163 | __addr: *mut root::sockaddr, 164 | __len: *mut root::socklen_t, 165 | ) -> i32; 166 | } 167 | extern "C" { 168 | pub fn send( 169 | __fd: i32, 170 | __buf: *const u8, 171 | __n: root::size_t, 172 | __flags: i32, 173 | ) -> root::ssize_t; 174 | } 175 | extern "C" { 176 | pub fn recv( 177 | __fd: i32, 178 | __buf: *mut u8, 179 | __n: root::size_t, 180 | __flags: i32, 181 | ) -> root::ssize_t; 182 | } 183 | extern "C" { 184 | pub fn sendto( 185 | __fd: i32, 186 | __buf: *const u8, 187 | __n: root::size_t, 188 | __flags: i32, 189 | __addr: *const root::sockaddr, 190 | __addr_len: root::socklen_t, 191 | ) -> root::ssize_t; 192 | } 193 | extern "C" { 194 | pub fn recvfrom( 195 | __fd: i32, 196 | __buf: *mut u8, 197 | __n: root::size_t, 198 | __flags: i32, 199 | __addr: *mut root::sockaddr, 200 | __addr_len: *mut root::socklen_t, 201 | ) -> root::ssize_t; 202 | } 203 | extern "C" { 204 | pub fn sendmsg( 205 | __fd: i32, 206 | __message: *const root::msghdr, 207 | __flags: i32, 208 | ) -> root::ssize_t; 209 | } 210 | extern "C" { 211 | pub fn sendmmsg( 212 | __fd: i32, 213 | __vmessages: *mut root::mmsghdr, 214 | __vlen: u32, 215 | __flags: i32, 216 | ) -> i32; 217 | } 218 | extern "C" { 219 | pub fn recvmsg( 220 | __fd: i32, 221 | __message: *mut root::msghdr, 222 | __flags: i32, 223 | ) -> root::ssize_t; 224 | } 225 | extern "C" { 226 | pub fn recvmmsg( 227 | __fd: i32, 228 | __vmessages: *mut root::mmsghdr, 229 | __vlen: u32, 230 | __flags: i32, 231 | __tmo: *mut root::timespec, 232 | ) -> i32; 233 | } 234 | extern "C" { 235 | pub fn getsockopt( 236 | __fd: i32, 237 | __level: i32, 238 | __optname: i32, 239 | __optval: *mut u8, 240 | __optlen: *mut root::socklen_t, 241 | ) -> i32; 242 | } 243 | extern "C" { 244 | pub fn setsockopt( 245 | __fd: i32, 246 | __level: i32, 247 | __optname: i32, 248 | __optval: *const u8, 249 | __optlen: root::socklen_t, 250 | ) -> i32; 251 | } 252 | extern "C" { 253 | pub fn listen(__fd: i32, __n: i32) -> i32; 254 | } 255 | extern "C" { 256 | pub fn accept( 257 | __fd: i32, 258 | __addr: *mut root::sockaddr, 259 | __addr_len: *mut root::socklen_t, 260 | ) -> i32; 261 | } 262 | extern "C" { 263 | pub fn accept4( 264 | __fd: i32, 265 | __addr: *mut root::sockaddr, 266 | __addr_len: *mut root::socklen_t, 267 | __flags: i32, 268 | ) -> i32; 269 | } 270 | extern "C" { 271 | pub fn shutdown(__fd: i32, __how: i32) -> i32; 272 | } 273 | extern "C" { 274 | pub fn sockatmark(__fd: i32) -> i32; 275 | } 276 | extern "C" { 277 | pub fn isfdtype(__fd: i32, __fdtype: i32) -> i32; 278 | } 279 | 280 | } 281 | -------------------------------------------------------------------------------- /src/nn/account.rs: -------------------------------------------------------------------------------- 1 | use alloc::{vec::Vec,vec, string::String}; 2 | 3 | #[allow(unused_imports)] 4 | use self::super::root; 5 | 6 | pub mod detail; 7 | //pub type Nickname = [u8; 33usize]; 8 | #[repr(transparent)] 9 | pub struct Nickname(pub [u8; 33usize]); 10 | 11 | impl Nickname { 12 | pub fn new() -> Self { 13 | Self([0; 33]) 14 | } 15 | } 16 | 17 | #[cfg(not(feature = "rustc-dep-of-std"))] 18 | impl core::fmt::Display for Nickname { 19 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 20 | let mut i = 0; 21 | while self.0[i] != 0 { 22 | i += 1; 23 | } 24 | 25 | write!(f, "{}", unsafe { 26 | alloc::str::from_utf8_unchecked(&self.0[..i]) 27 | }) 28 | } 29 | } 30 | 31 | pub type NetworkServiceAccountId = u64; 32 | 33 | #[repr(C)] 34 | #[derive(Debug, Copy, Clone)] 35 | pub struct Uid { 36 | pub id: [u64; 2usize], 37 | } 38 | 39 | impl Uid { 40 | pub fn new() -> Self { 41 | Self { id: [0, 0] } 42 | } 43 | } 44 | 45 | #[repr(C)] 46 | #[derive(Debug, Clone)] 47 | pub struct UserHandle { 48 | pub id: [u64; 3usize], 49 | } 50 | 51 | impl UserHandle { 52 | pub fn new() -> Self { 53 | Self { id: [0u64; 3] } 54 | } 55 | } 56 | 57 | extern "C" { 58 | #[link_name = "\u{1}_ZN2nn7account10InitializeEv"] 59 | pub fn Initialize(); 60 | 61 | #[link_name = "_ZN2nn7account8FinalizeEv"] 62 | pub fn Finalize(); 63 | 64 | #[link_name = "\u{1}_ZN2nn7account15ShowUserCreatorEv"] 65 | pub fn ShowUserCreator(); 66 | 67 | #[link_name = "\u{1}_ZN2nn7account12ListAllUsersEPiPNS0_3UidEi"] 68 | pub fn ListAllUsers( 69 | out_len: *mut root::s32, 70 | out_uids: *mut Uid, 71 | num_users: root::s32, 72 | ) -> root::Result; 73 | 74 | #[link_name = "_ZN2nn7account12GetUserCountEPi"] 75 | pub fn GetUserCount(count: *mut i32); 76 | 77 | #[link_name = "\u{1}_ZN2nn7account8OpenUserEPNS0_10UserHandleERKNS0_3UidE"] 78 | pub fn OpenUser( 79 | handle: *mut UserHandle, 80 | uid: *const Uid, 81 | ) -> root::Result; 82 | 83 | #[link_name = "\u{1}_ZN2nn7account19OpenPreselectedUserEPNS0_10UserHandleE"] 84 | pub fn OpenPreselectedUser( 85 | handle: *mut UserHandle 86 | ) -> root::Result; 87 | 88 | #[link_name = "\u{1}_ZN2nn7account22TryOpenPreselectedUserEPNS0_10UserHandleE"] 89 | pub fn TryOpenPreselectedUser( 90 | handle: *mut UserHandle 91 | ) -> bool; 92 | 93 | #[link_name = "\u{1}_ZN2nn7account9GetUserIdEPNS0_3UidERKNS0_10UserHandleE"] 94 | pub fn GetUserId( 95 | out_user_id: *mut Uid, 96 | handle: *const UserHandle 97 | ) -> root::Result; 98 | 99 | #[link_name = "\u{1}_ZN2nn7account32IsNetworkServiceAccountAvailableEPbRKNS0_10UserHandleE"] 100 | pub fn IsNetworkServiceAccountAvailable( 101 | out: *mut bool, 102 | arg1: *const UserHandle, 103 | ) -> root::Result; 104 | 105 | #[link_name = "\u{1}_ZN2nn7account9CloseUserERKNS0_10UserHandleE"] 106 | pub fn CloseUser(handle: *const UserHandle); 107 | 108 | #[link_name = "\u{1}_ZN2nn7account36EnsureNetworkServiceAccountAvailableERKNS0_10UserHandleE"] 109 | pub fn EnsureNetworkServiceAccountAvailable( 110 | handle: *const UserHandle, 111 | ) -> root::Result; 112 | 113 | #[link_name = "\u{1}_ZN2nn7account44EnsureNetworkServiceAccountIdTokenCacheAsyncEPNS0_12AsyncContextERKNS0_10UserHandleE"] 114 | pub fn EnsureNetworkServiceAccountIdTokenCacheAsync( 115 | context: *mut AsyncContext, 116 | handle: *const UserHandle, 117 | ) -> root::Result; 118 | 119 | #[link_name = "\u{1}_ZN2nn7account37LoadNetworkServiceAccountIdTokenCacheEPmPcmRKNS0_10UserHandleE"] 120 | pub fn LoadNetworkServiceAccountIdTokenCache( 121 | arg1: *mut u64, 122 | arg2: *mut u8, 123 | arg3: u64, 124 | arg4: *const UserHandle, 125 | ) -> root::Result; 126 | 127 | #[link_name = "\u{1}_ZN2nn7account17GetLastOpenedUserEPNS0_3UidE"] 128 | pub fn GetLastOpenedUser(arg1: *mut Uid) -> root::Result; 129 | 130 | #[link_name = "\u{1}_ZN2nn7account11GetNicknameEPNS0_8NicknameERKNS0_3UidE"] 131 | pub fn GetNickname( 132 | nickname: *mut Nickname, 133 | userID: *const Uid, 134 | ) -> root::Result; 135 | } 136 | 137 | pub fn initialize() { 138 | unsafe { Initialize() }; 139 | } 140 | 141 | pub fn finalize() { 142 | unsafe { Finalize() }; 143 | } 144 | 145 | pub fn show_user_creator() { 146 | unsafe { ShowUserCreator() }; 147 | } 148 | 149 | pub fn list_all_users() -> Vec { 150 | let num_users = get_user_count(); 151 | 152 | let mut out_len = 0; 153 | let mut out_uids: Vec = vec![Uid::new(); num_users as usize]; 154 | 155 | unsafe { 156 | ListAllUsers(&mut out_len, out_uids.as_mut_ptr(), num_users); 157 | } 158 | 159 | return out_uids; 160 | } 161 | 162 | pub fn get_user_count() -> i32 { 163 | let mut count = 0; 164 | 165 | unsafe { 166 | GetUserCount(&mut count); 167 | } 168 | 169 | return count 170 | } 171 | 172 | pub fn open_user(uid: &Uid) -> UserHandle { 173 | let mut handle = UserHandle::new(); 174 | 175 | unsafe { 176 | OpenUser(&mut handle, uid); 177 | } 178 | return handle; 179 | } 180 | 181 | pub fn open_preselected_user() -> UserHandle { 182 | let mut handle = UserHandle::new(); 183 | unsafe { 184 | OpenPreselectedUser(&mut handle); 185 | } 186 | return handle; 187 | } 188 | 189 | pub fn try_open_preselected_user() -> Option { 190 | let mut handle = UserHandle::new(); 191 | 192 | unsafe { 193 | TryOpenPreselectedUser(&mut handle).then(|| handle) 194 | } 195 | } 196 | 197 | pub fn get_user_id(user_handle: &UserHandle) -> Result { 198 | let mut uid = Uid::new(); 199 | 200 | unsafe { 201 | let result = GetUserId(&mut uid, user_handle); 202 | 203 | if result != 0 { 204 | Err(result) 205 | } else { 206 | Ok(uid) 207 | } 208 | } 209 | } 210 | 211 | pub fn is_network_service_account_available(handle: &UserHandle) -> bool { 212 | let mut result = true; 213 | 214 | unsafe { 215 | IsNetworkServiceAccountAvailable(&mut result, handle); 216 | } 217 | 218 | return result; 219 | } 220 | 221 | pub fn close_user(user_handle: UserHandle) { 222 | unsafe { CloseUser(&user_handle) } 223 | } 224 | 225 | pub fn ensure_network_service_account_available(handle: &UserHandle) { 226 | unsafe { 227 | EnsureNetworkServiceAccountAvailable(handle); 228 | } 229 | } 230 | 231 | pub fn ensure_network_service_account_id_token_cache_async(context: &mut AsyncContext, handle: &UserHandle) { 232 | unsafe { 233 | EnsureNetworkServiceAccountIdTokenCacheAsync(context, handle); 234 | } 235 | } 236 | 237 | pub fn get_last_opened_user() -> Uid { 238 | let mut uid = Uid::new(); 239 | 240 | unsafe { 241 | GetLastOpenedUser(&mut uid); 242 | } 243 | 244 | return uid; 245 | } 246 | 247 | pub fn get_nickname(uid: &Uid) -> String { 248 | let mut nickname = Nickname::new(); 249 | 250 | unsafe { 251 | GetNickname(&mut nickname, uid); 252 | } 253 | 254 | let result = String::from_utf8(nickname.0.to_vec()).unwrap(); 255 | 256 | return result.replace("\0", ""); 257 | } 258 | 259 | #[repr(C)] 260 | #[derive(Debug, Copy, Clone)] 261 | pub struct AsyncContext { 262 | pub _address: u8, 263 | } 264 | 265 | extern "C" { 266 | #[link_name = "\u{1}_ZN2nn7account12AsyncContext7HasDoneEPb"] 267 | pub fn AsyncContext_HasDone( 268 | this: *mut AsyncContext, 269 | arg1: *mut bool, 270 | ) -> root::Result; 271 | } 272 | extern "C" { 273 | #[link_name = "\u{1}_ZN2nn7account12AsyncContext9GetResultEv"] 274 | pub fn AsyncContext_GetResult( 275 | this: *mut AsyncContext, 276 | ) -> root::Result; 277 | } 278 | extern "C" { 279 | #[link_name = "\u{1}_ZN2nn7account12AsyncContext6CancelEv"] 280 | pub fn AsyncContext_Cancel( 281 | this: *mut AsyncContext, 282 | ) -> root::Result; 283 | } 284 | extern "C" { 285 | #[link_name = "\u{1}_ZN2nn7account12AsyncContext14GetSystemEventEPNS_2os11SystemEventE"] 286 | pub fn AsyncContext_GetSystemEvent( 287 | this: *mut AsyncContext, 288 | out_event: *mut root::nn::os::SystemEvent, 289 | ) -> root::Result; 290 | } 291 | 292 | extern "C" { 293 | #[link_name = "\u{1}_ZN2nn7account12AsyncContextC1Ev"] 294 | pub fn AsyncContext_AsyncContext(this: *mut AsyncContext); 295 | } 296 | 297 | impl AsyncContext { 298 | #[inline] 299 | pub fn has_done(&mut self) -> bool { 300 | let mut result = false; 301 | unsafe { 302 | AsyncContext_HasDone(self, &mut result); 303 | } 304 | return result 305 | } 306 | 307 | #[inline] 308 | pub fn get_result(&mut self) -> root::Result { 309 | unsafe { 310 | return AsyncContext_GetResult(self); 311 | } 312 | } 313 | #[inline] 314 | pub fn cancel(&mut self) { 315 | unsafe { 316 | AsyncContext_Cancel(self); 317 | } 318 | } 319 | 320 | #[inline] 321 | pub fn get_system_event( 322 | &mut self, 323 | ) -> root::nn::os::SystemEvent { 324 | let mut event = root::nn::os::SystemEvent { _unused: [0; 0x28] } ; 325 | unsafe { 326 | AsyncContext_GetSystemEvent(self, &mut event); 327 | } 328 | return event; 329 | } 330 | 331 | #[inline] 332 | pub fn new() -> Self { 333 | let mut async_context = AsyncContext { _address: 0 }; 334 | 335 | unsafe { 336 | AsyncContext_AsyncContext( &mut async_context ); 337 | } 338 | return async_context; 339 | } 340 | } -------------------------------------------------------------------------------- /src/nn/account/detail.rs: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | #[link_name = "\u{1}_ZN2nn7account6detail13IsInitializedEv"] 3 | pub fn IsInitialized() -> bool; 4 | } 5 | 6 | pub fn is_initialized() -> bool { 7 | let result = unsafe { IsInitialized() }; 8 | return result; 9 | } -------------------------------------------------------------------------------- /src/nn/aoc.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use alloc::{vec, vec::Vec}; 3 | 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn3aoc17CountAddOnContentEv"] 6 | fn CountAddOnContent() -> usize; 7 | 8 | #[link_name = "\u{1}_ZN2nn3aoc16ListAddOnContentEPiii"] 9 | fn ListAddOnContent(out_indices: *mut i32, offset: i32, count: usize); 10 | } 11 | 12 | pub fn count_add_on_content() -> usize{ 13 | unsafe { 14 | return CountAddOnContent(); 15 | } 16 | } 17 | 18 | pub fn list_add_on_content(offset: i32) -> Vec { 19 | let count = count_add_on_content(); 20 | let mut out = vec![0; count]; 21 | unsafe { 22 | ListAddOnContent(out.as_mut_ptr(), offset, count) 23 | } 24 | return out 25 | } -------------------------------------------------------------------------------- /src/nn/audio.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | #[derive(Debug, Copy, Clone)] 6 | pub struct AudioRendererConfig { 7 | pub _0: *mut u64, 8 | pub _8: *mut u64, 9 | pub _10: *mut u64, 10 | pub _18: *mut u64, 11 | pub _20: *mut u64, 12 | pub _28: *mut u64, 13 | pub _30: *mut u64, 14 | pub _38: *mut u64, 15 | pub _40: *mut u64, 16 | pub _48: *mut u64, 17 | pub _50: *mut u64, 18 | } 19 | 20 | #[repr(C)] 21 | #[derive(Debug, Copy, Clone)] 22 | pub struct DelayType { 23 | pub _0: *mut u64, 24 | } 25 | 26 | #[repr(C)] 27 | #[derive(Debug, Copy, Clone)] 28 | pub struct FinalMixType { 29 | pub _0: *mut u64, 30 | } 31 | 32 | #[repr(C)] 33 | #[derive(Debug, Copy, Clone)] 34 | pub struct SubMixType { 35 | pub _0: *mut u64, 36 | } 37 | 38 | extern "C" { 39 | #[link_name = "\u{1}_ZN2nn5audio19SetDelayInputOutputEPNS0_9DelayTypeEPKaS4_i"] 40 | pub fn SetDelayInputOutput( 41 | arg1: *mut root::nn::audio::DelayType, 42 | arg2: *const root::s8, 43 | arg3: *const root::s8, 44 | arg4: root::s32, 45 | ); 46 | } 47 | extern "C" { 48 | #[link_name = "\u{1}_ZN2nn5audio11RemoveDelayEPNS0_19AudioRendererConfigEPNS0_9DelayTypeEPNS0_12FinalMixTypeE"] 49 | pub fn RemoveDelay( 50 | arg1: *mut root::nn::audio::AudioRendererConfig, 51 | arg2: *mut root::nn::audio::DelayType, 52 | arg3: *mut root::nn::audio::FinalMixType, 53 | ) -> *mut u8; 54 | } 55 | extern "C" { 56 | #[link_name = "\u{1}_ZN2nn5audio11RemoveDelayEPNS0_19AudioRendererConfigEPNS0_9DelayTypeEPNS0_10SubMixTypeE"] 57 | pub fn RemoveDelay1( 58 | arg1: *mut root::nn::audio::AudioRendererConfig, 59 | arg2: *mut root::nn::audio::DelayType, 60 | arg3: *mut root::nn::audio::SubMixType, 61 | ) -> *mut u8; 62 | } 63 | extern "C" { 64 | #[link_name = "\u{1}_ZN2nn5audio17IsDelayRemoveableEPNS0_9DelayTypeE"] 65 | pub fn IsDelayRemoveable(arg1: *mut root::nn::audio::DelayType) -> bool; 66 | } -------------------------------------------------------------------------------- /src/nn/crypto.rs: -------------------------------------------------------------------------------- 1 | use alloc::{vec, vec::Vec}; 2 | 3 | #[allow(unused_imports)] 4 | use self::super::root; 5 | pub mod detail; 6 | #[repr(C)] 7 | #[derive(Debug, Copy, Clone)] 8 | pub struct Sha256Context { 9 | _unused: [u8; 0], 10 | } 11 | 12 | extern "C" { 13 | #[link_name = "\u{1}_ZN2nn6crypto18GenerateSha256HashEPvmPKvm"] 14 | pub fn GenerateSha256Hash( 15 | out_hash: *mut u8, 16 | out_len: root::ulong, 17 | data: *const u8, 18 | data_len: root::ulong, 19 | ); 20 | } 21 | 22 | pub fn generate_sha256_hash(data: &mut [u8]) -> Vec { 23 | let out_len = 32; 24 | let mut out_hash = vec![0; out_len]; 25 | unsafe { 26 | GenerateSha256Hash(out_hash.as_mut_ptr(), out_len as u64, data.as_mut_ptr(), data.len() as u64); 27 | } 28 | return out_hash; 29 | } 30 | 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn6crypto16DecryptAes128CbcEPvmPKvmS3_mS3_m"] 33 | pub fn DecryptAes128Cbc( 34 | out_data: *mut u8, 35 | out_len: u64, 36 | key: *const u8, 37 | key_len: u64, 38 | iv: *const u8, 39 | iv_len: u64, 40 | encrypted_data: *const u8, 41 | encrypted_data_len: u64, 42 | ); 43 | } 44 | 45 | 46 | extern "C" { 47 | #[link_name = "\u{1}_ZN2nn6crypto16EncryptAes128CbcEPvmPKvmS3_mS3_m"] 48 | pub fn EncryptAes128Cbc( 49 | out_data: *mut u8, 50 | out_len: u64, 51 | key: *const u8, 52 | key_len: u64, 53 | iv: *const u8, 54 | iv_len: u64, 55 | decrypted_data: *const u8, 56 | decrypted_data_len: u64, 57 | ); 58 | } 59 | 60 | 61 | extern "C" { 62 | #[link_name = "\u{1}_ZN2nn6crypto16DecryptAes128CcmEPvmS1_mPKvmS3_mS3_mS3_mm"] 63 | pub fn DecryptAes128Ccm( 64 | arg1: *mut u8, 65 | arg2: u64, 66 | arg3: *mut u8, 67 | arg4: u64, 68 | arg5: *const u8, 69 | arg6: u64, 70 | arg7: *const u8, 71 | arg8: u64, 72 | arg9: *const u8, 73 | arg10: u64, 74 | arg11: *const u8, 75 | arg12: u64, 76 | arg13: u64, 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/nn/crypto/detail.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | pub struct Md5Impl { 5 | pub _x0: u32, 6 | pub _x4: u32, 7 | pub _x8: u32, 8 | pub _xC: u32, 9 | pub _x10: [u8; 64usize], 10 | pub _x50: u64, 11 | pub _x58: u32, 12 | } 13 | 14 | extern "C" { 15 | #[link_name = "\u{1}_ZN2nn6crypto6detail7Md5Impl10InitializeEv"] 16 | pub fn Md5Impl_Initialize(this: *mut Md5Impl); 17 | } 18 | extern "C" { 19 | #[link_name = "\u{1}_ZN2nn6crypto6detail7Md5Impl6UpdateEPKvm"] 20 | pub fn Md5Impl_Update( 21 | this: *mut Md5Impl, 22 | arg1: *const u8, 23 | dataSize: u64, 24 | ); 25 | } 26 | extern "C" { 27 | #[link_name = "\u{1}_ZN2nn6crypto6detail7Md5Impl12ProcessBlockEv"] 28 | pub fn Md5Impl_ProcessBlock(this: *mut Md5Impl); 29 | } 30 | extern "C" { 31 | #[link_name = "\u{1}_ZN2nn6crypto6detail7Md5Impl7GetHashEPvm"] 32 | pub fn Md5Impl_GetHash( 33 | this: *mut Md5Impl, 34 | arg1: *mut u8, 35 | hashSize: u64, 36 | ); 37 | } 38 | extern "C" { 39 | #[link_name = "\u{1}_ZN2nn6crypto6detail7Md5Impl16ProcessLastBlockEv"] 40 | pub fn Md5Impl_ProcessLastBlock(this: *mut Md5Impl); 41 | } 42 | impl Md5Impl { 43 | #[inline] 44 | pub unsafe fn Initialize(&mut self) { 45 | Md5Impl_Initialize(self) 46 | } 47 | #[inline] 48 | pub unsafe fn Update(&mut self, arg1: *const u8, dataSize: u64) { 49 | Md5Impl_Update(self, arg1, dataSize) 50 | } 51 | #[inline] 52 | pub unsafe fn ProcessBlock(&mut self) { 53 | Md5Impl_ProcessBlock(self) 54 | } 55 | #[inline] 56 | pub unsafe fn GetHash(&mut self, arg1: *mut u8, hashSize: u64) { 57 | Md5Impl_GetHash(self, arg1, hashSize) 58 | } 59 | #[inline] 60 | pub unsafe fn ProcessLastBlock(&mut self) { 61 | Md5Impl_ProcessLastBlock(self) 62 | } 63 | } 64 | #[repr(C)] 65 | #[repr(align(16))] 66 | pub struct Sha1Impl { 67 | pub _x0: u64, 68 | pub _x8: u64, 69 | pub _x10: u32, 70 | pub __bindgen_padding_0: u64, 71 | pub _x14: u128, 72 | pub _x24: u128, 73 | pub _x34: u128, 74 | pub _x44: u32, 75 | pub _x48: u64, 76 | pub _x50: u64, 77 | pub _x58: u64, 78 | pub _x60: u64, 79 | } 80 | 81 | extern "C" { 82 | #[link_name = "\u{1}_ZN2nn6crypto6detail8Sha1Impl10InitializeEv"] 83 | #[allow(improper_ctypes)] 84 | pub fn Sha1Impl_Initialize(this: *mut Sha1Impl); 85 | } 86 | extern "C" { 87 | #[link_name = "\u{1}_ZN2nn6crypto6detail8Sha1Impl6UpdateEPKvm"] 88 | #[allow(improper_ctypes)] 89 | pub fn Sha1Impl_Update( 90 | this: *mut Sha1Impl, 91 | arg1: *const u8, 92 | arg2: u64, 93 | ); 94 | } 95 | extern "C" { 96 | #[link_name = "\u{1}_ZN2nn6crypto6detail8Sha1Impl12ProcessBlockEPKv"] 97 | #[allow(improper_ctypes)] 98 | pub fn Sha1Impl_ProcessBlock( 99 | this: *mut Sha1Impl, 100 | arg1: *const u8, 101 | ); 102 | } 103 | extern "C" { 104 | #[link_name = "\u{1}_ZN2nn6crypto6detail8Sha1Impl7GetHashEPvm"] 105 | #[allow(improper_ctypes)] 106 | pub fn Sha1Impl_GetHash( 107 | this: *mut Sha1Impl, 108 | destHash: *mut u8, 109 | arg1: u64, 110 | ); 111 | } 112 | extern "C" { 113 | #[link_name = "\u{1}_ZN2nn6crypto6detail8Sha1Impl16ProcessLastBlockEv"] 114 | #[allow(improper_ctypes)] 115 | pub fn Sha1Impl_ProcessLastBlock(this: *mut Sha1Impl); 116 | } 117 | impl Sha1Impl { 118 | #[inline] 119 | pub unsafe fn Initialize(&mut self) { 120 | Sha1Impl_Initialize(self) 121 | } 122 | #[inline] 123 | pub unsafe fn Update(&mut self, arg1: *const u8, arg2: u64) { 124 | Sha1Impl_Update(self, arg1, arg2) 125 | } 126 | #[inline] 127 | pub unsafe fn ProcessBlock(&mut self, arg1: *const u8) { 128 | Sha1Impl_ProcessBlock(self, arg1) 129 | } 130 | #[inline] 131 | pub unsafe fn GetHash(&mut self, destHash: *mut u8, arg1: u64) { 132 | Sha1Impl_GetHash(self, destHash, arg1) 133 | } 134 | #[inline] 135 | pub unsafe fn ProcessLastBlock(&mut self) { 136 | Sha1Impl_ProcessLastBlock(self) 137 | } 138 | } 139 | #[repr(C)] 140 | #[repr(align(16))] 141 | pub struct Sha256Impl { 142 | pub _x0: u64, 143 | pub _x8: u64, 144 | pub _x10: u32, 145 | pub __bindgen_padding_0: u64, 146 | pub _x14: u128, 147 | pub _x24: u128, 148 | pub _x34: u128, 149 | pub _x44: u32, 150 | pub _x48: u64, 151 | pub _x50: u64, 152 | pub _x58: u64, 153 | pub _x60: u64, 154 | pub _x68: u64, 155 | pub _x70: u32, 156 | } 157 | 158 | extern "C" { 159 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl10InitializeEv"] 160 | #[allow(improper_ctypes)] 161 | pub fn Sha256Impl_Initialize(this: *mut Sha256Impl); 162 | } 163 | extern "C" { 164 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl6UpdateEPKvm"] 165 | #[allow(improper_ctypes)] 166 | pub fn Sha256Impl_Update( 167 | this: *mut Sha256Impl, 168 | arg1: *const u8, 169 | arg2: u64, 170 | ); 171 | } 172 | extern "C" { 173 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl13ProcessBlocksEPKhm"] 174 | #[allow(improper_ctypes)] 175 | pub fn Sha256Impl_ProcessBlocks( 176 | this: *mut Sha256Impl, 177 | arg1: *const u8, 178 | arg2: u64, 179 | ); 180 | } 181 | extern "C" { 182 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl7GetHashEPvm"] 183 | #[allow(improper_ctypes)] 184 | pub fn Sha256Impl_GetHash( 185 | this: *mut Sha256Impl, 186 | destHash: *mut u8, 187 | arg1: u64, 188 | ); 189 | } 190 | extern "C" { 191 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl16ProcessLastBlockEv"] 192 | #[allow(improper_ctypes)] 193 | pub fn Sha256Impl_ProcessLastBlock( 194 | this: *mut Sha256Impl, 195 | ); 196 | } 197 | extern "C" { 198 | #[link_name = "\u{1}_ZN2nn6crypto6detail10Sha256Impl21InitializeWithContextEPKNS0_13Sha256ContextE"] 199 | #[allow(improper_ctypes)] 200 | pub fn Sha256Impl_InitializeWithContext( 201 | this: *mut Sha256Impl, 202 | arg1: *const root::nn::crypto::Sha256Context, 203 | ); 204 | } 205 | extern "C" { 206 | #[link_name = "\u{1}_ZNK2nn6crypto6detail10Sha256Impl10GetContextEPNS0_13Sha256ContextE"] 207 | #[allow(improper_ctypes)] 208 | pub fn Sha256Impl_GetContext( 209 | this: *const Sha256Impl, 210 | arg1: *mut root::nn::crypto::Sha256Context, 211 | ); 212 | } 213 | impl Sha256Impl { 214 | #[inline] 215 | pub unsafe fn Initialize(&mut self) { 216 | Sha256Impl_Initialize(self) 217 | } 218 | #[inline] 219 | pub unsafe fn Update(&mut self, arg1: *const u8, arg2: u64) { 220 | Sha256Impl_Update(self, arg1, arg2) 221 | } 222 | #[inline] 223 | pub unsafe fn ProcessBlocks(&mut self, arg1: *const u8, arg2: u64) { 224 | Sha256Impl_ProcessBlocks(self, arg1, arg2) 225 | } 226 | #[inline] 227 | pub unsafe fn GetHash(&mut self, destHash: *mut u8, arg1: u64) { 228 | Sha256Impl_GetHash(self, destHash, arg1) 229 | } 230 | #[inline] 231 | pub unsafe fn ProcessLastBlock(&mut self) { 232 | Sha256Impl_ProcessLastBlock(self) 233 | } 234 | #[inline] 235 | pub unsafe fn InitializeWithContext( 236 | &mut self, 237 | arg1: *const root::nn::crypto::Sha256Context, 238 | ) { 239 | Sha256Impl_InitializeWithContext(self, arg1) 240 | } 241 | #[inline] 242 | pub unsafe fn GetContext(&self, arg1: *mut root::nn::crypto::Sha256Context) { 243 | Sha256Impl_GetContext(self, arg1) 244 | } 245 | } -------------------------------------------------------------------------------- /src/nn/diag.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub mod detail; 4 | 5 | #[repr(C)] 6 | #[derive(Debug, Copy, Clone)] 7 | pub struct LogMetaData { 8 | _unused: [u8; 0], 9 | } 10 | #[repr(C)] 11 | pub struct ModuleInfo { 12 | pub mPath: *mut u8, 13 | pub mBaseAddr: u64, 14 | pub mSize: u64, 15 | } 16 | 17 | extern "C" { 18 | #[link_name = "\u{1}_ZN2nn4diag12GetBacktraceEPmi"] 19 | pub fn GetBacktrace(out_array: *mut *const u8, array_len: i32) -> usize; 20 | } 21 | extern "C" { 22 | #[link_name = "\u{1}_ZN2nn4diag12GetBacktraceEPmimmm"] 23 | pub fn GetBacktrace1( 24 | out_array: *mut *const u8, 25 | array_len: i32, 26 | fp: *const u64, 27 | sp: *const u64, 28 | pc: *const u64, 29 | ) -> usize; 30 | } 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn4diag13GetSymbolNameEPcmm"] 33 | pub fn GetSymbolName(name: *mut u8, nameSize: u64, addr: u64) 34 | -> *mut u32; 35 | } 36 | extern "C" { 37 | #[link_name = "\u{1}_ZN2nn4diag40GetRequiredBufferSizeForGetAllModuleInfoEv"] 38 | pub fn GetRequiredBufferSizeForGetAllModuleInfo() -> u64; 39 | } 40 | extern "C" { 41 | #[link_name = "\u{1}_ZN2nn4diag16GetAllModuleInfoEPPNS0_10ModuleInfoEPvm"] 42 | pub fn GetAllModuleInfo( 43 | out: *mut *mut root::nn::diag::ModuleInfo, 44 | buffer: *mut u8, 45 | bufferSize: u64, 46 | ) -> root::s32; 47 | } 48 | extern "C" { 49 | #[link_name = "\u{1}_ZN2nn4diag13GetSymbolSizeEm"] 50 | pub fn GetSymbolSize(addr: u64) -> u64; 51 | } -------------------------------------------------------------------------------- /src/nn/diag/detail.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | extern "C" { 4 | #[link_name = "\u{1}_ZN2nn4diag6detail7LogImplERKNS0_11LogMetaDataEPKcz"] 5 | pub fn LogImpl( 6 | arg1: *const root::nn::diag::LogMetaData, 7 | arg2: *const u8, 8 | ... 9 | ); 10 | } 11 | extern "C" { 12 | #[link_name = "\u{1}_ZN2nn4diag6detail9AbortImplEPKcS3_S3_i"] 13 | pub fn AbortImpl( 14 | arg1: *const u8, 15 | arg2: *const u8, 16 | arg3: *const u8, 17 | arg4: root::s32, 18 | ); 19 | } 20 | extern "C" { 21 | #[link_name = "\u{1}_ZN2nn4diag6detail9AbortImplEPKcS3_S3_ij"] 22 | pub fn AbortImpl1( 23 | arg1: *const u8, 24 | arg2: *const u8, 25 | arg3: *const u8, 26 | arg4: i32, 27 | arg5: root::Result, 28 | ); 29 | } -------------------------------------------------------------------------------- /src/nn/err.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | type ErrorCodeCategoryType = u32; 4 | 5 | #[repr(C)] 6 | pub struct ApplicationErrorArg { 7 | unk: u64, 8 | error_code: u32, 9 | language_code: *const root::nn::settings::LanguageCode, 10 | dialog_message: [u8; 2048usize], 11 | fullscreen_message: [u8; 2048usize], 12 | } 13 | extern "C" { 14 | #[link_name = "\u{1}_ZN2nn3err19ApplicationErrorArg29SetApplicationErrorCodeNumberEj"] 15 | pub fn ApplicationErrorArg_SetApplicationErrorCodeNumber( 16 | this: *mut ApplicationErrorArg, 17 | error_code: u32, 18 | ); 19 | } 20 | extern "C" { 21 | #[link_name = "\u{1}_ZN2nn3err19ApplicationErrorArg16SetDialogMessageEPKc"] 22 | pub fn ApplicationErrorArg_SetDialogMessage( 23 | this: *mut ApplicationErrorArg, 24 | message: *const u8, 25 | ); 26 | } 27 | extern "C" { 28 | #[link_name = "\u{1}_ZN2nn3err19ApplicationErrorArg20SetFullScreenMessageEPKc"] 29 | pub fn ApplicationErrorArg_SetFullScreenMessage( 30 | this: *mut ApplicationErrorArg, 31 | message: *const u8, 32 | ); 33 | } 34 | extern "C" { 35 | #[link_name = "\u{1}_ZN2nn3err19ApplicationErrorArgC1Ev"] 36 | pub fn ApplicationErrorArg_ApplicationErrorArg( 37 | this: *mut ApplicationErrorArg, 38 | ); 39 | } 40 | extern "C" { 41 | #[link_name = "\u{1}_ZN2nn3err19ApplicationErrorArgC2EjPKcS3_RKNS_8settings12LanguageCodeE"] 42 | pub fn ApplicationErrorArg_ApplicationErrorArg1( 43 | this: *mut ApplicationErrorArg, 44 | error_code: u32, 45 | dialog_message: *const u8, 46 | fullscreen_message: *const u8, 47 | languageCode: *const root::nn::settings::LanguageCode, 48 | ); 49 | } 50 | impl ApplicationErrorArg { 51 | #[inline] 52 | pub unsafe fn SetApplicationErrorCodeNumber(&mut self, error_code: u32) { 53 | ApplicationErrorArg_SetApplicationErrorCodeNumber(self, error_code) 54 | } 55 | #[inline] 56 | pub unsafe fn SetDialogMessage(&mut self, message: *const u8) { 57 | ApplicationErrorArg_SetDialogMessage(self, message) 58 | } 59 | #[inline] 60 | pub unsafe fn SetFullScreenMessage(&mut self, message: *const u8) { 61 | ApplicationErrorArg_SetFullScreenMessage(self, message) 62 | } 63 | #[inline] 64 | pub unsafe fn new() -> Self { 65 | let mut temp = ::core::mem::MaybeUninit::uninit(); 66 | ApplicationErrorArg_ApplicationErrorArg(temp.as_mut_ptr()); 67 | temp.assume_init() 68 | } 69 | #[inline] 70 | pub unsafe fn new_with_messages( 71 | error_code: u32, 72 | dialog_message: *const u8, 73 | fullscreen_message: *const u8, 74 | languageCode: *const root::nn::settings::LanguageCode, 75 | ) -> Self { 76 | let mut temp = ::core::mem::MaybeUninit::uninit(); 77 | ApplicationErrorArg_ApplicationErrorArg1( 78 | temp.as_mut_ptr(), 79 | error_code, 80 | dialog_message, 81 | fullscreen_message, 82 | languageCode, 83 | ); 84 | temp.assume_init() 85 | } 86 | } 87 | extern "C" { 88 | #[link_name = "\u{1}_ZN2nn3err13MakeErrorCodeENS0_21ErrorCodeCategoryTypeEj"] 89 | pub fn MakeErrorCode( 90 | err_category_type: ErrorCodeCategoryType, 91 | errorCodeNumber: u32, 92 | ) -> u32; 93 | } 94 | extern "C" { 95 | #[link_name = "\u{1}_ZN2nn3err20ShowApplicationErrorERKNS0_19ApplicationErrorArgE"] 96 | pub fn ShowApplicationError(arg: *const root::nn::err::ApplicationErrorArg); 97 | } -------------------------------------------------------------------------------- /src/nn/friends.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub type Url = [u8; 160usize]; 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn7friends10InitializeEv"] 6 | pub fn Initialize(); 7 | } 8 | extern "C" { 9 | #[link_name = "\u{1}_ZN2nn7friends14GetProfileListEPNS0_12AsyncContextEPNS0_7ProfileERKNS_7account3UidEPKmi"] 10 | pub fn GetProfileList( 11 | context: *mut AsyncContext, 12 | profiles: *mut Profile, 13 | userID: *const root::nn::account::Uid, 14 | accountIDs: *const root::nn::account::NetworkServiceAccountId, 15 | numAccounts: root::s32, 16 | ) -> root::Result; 17 | } 18 | #[repr(C)] 19 | #[derive(Debug, Copy, Clone)] 20 | pub struct Profile { 21 | pub _address: u8, 22 | } 23 | 24 | extern "C" { 25 | #[link_name = "\u{1}_ZNK2nn7friends7Profile12GetAccountIdEv"] 26 | pub fn Profile_GetAccountId( 27 | this: *const Profile, 28 | ) -> root::nn::account::NetworkServiceAccountId; 29 | } 30 | extern "C" { 31 | #[link_name = "\u{1}_ZNK2nn7friends7Profile11GetNicknameEv"] 32 | pub fn Profile_GetNickname( 33 | this: *const Profile, 34 | ) -> *mut root::nn::account::Nickname; 35 | } 36 | extern "C" { 37 | #[link_name = "\u{1}_ZNK2nn7friends7Profile7IsValidEv"] 38 | pub fn Profile_IsValid(this: *const Profile) -> bool; 39 | } 40 | extern "C" { 41 | #[link_name = "\u{1}_ZN2nn7friends7Profile18GetProfileImageUrlEPA160_ci"] 42 | pub fn Profile_GetProfileImageUrl( 43 | this: *mut Profile, 44 | arg1: *mut Url, 45 | arg2: root::s32, 46 | ) -> root::Result; 47 | } 48 | extern "C" { 49 | #[link_name = "\u{1}_ZN2nn7friends7ProfileC1Ev"] 50 | pub fn Profile_Profile(this: *mut Profile); 51 | } 52 | impl Profile { 53 | #[inline] 54 | pub unsafe fn GetAccountId(&self) -> root::nn::account::NetworkServiceAccountId { 55 | Profile_GetAccountId(self) 56 | } 57 | #[inline] 58 | pub unsafe fn GetNickname(&self) -> *mut root::nn::account::Nickname { 59 | Profile_GetNickname(self) 60 | } 61 | #[inline] 62 | pub unsafe fn IsValid(&self) -> bool { 63 | Profile_IsValid(self) 64 | } 65 | #[inline] 66 | pub unsafe fn GetProfileImageUrl( 67 | &mut self, 68 | arg1: *mut Url, 69 | arg2: root::s32, 70 | ) -> root::Result { 71 | Profile_GetProfileImageUrl(self, arg1, arg2) 72 | } 73 | #[inline] 74 | pub unsafe fn new() -> Self { 75 | let mut __bindgen_tmp = ::core::mem::MaybeUninit::uninit(); 76 | Profile_Profile(__bindgen_tmp.as_mut_ptr()); 77 | __bindgen_tmp.assume_init() 78 | } 79 | } 80 | #[repr(C)] 81 | #[derive(Debug)] 82 | pub struct AsyncContext { 83 | pub _address: u8, 84 | } 85 | 86 | extern "C" { 87 | #[link_name = "\u{1}_ZN2nn7friends12AsyncContext14GetSystemEventEPNS_2os11SystemEventE"] 88 | pub fn AsyncContext_GetSystemEvent( 89 | this: *mut AsyncContext, 90 | arg1: *mut root::nn::os::SystemEvent, 91 | ) -> root::Result; 92 | } 93 | extern "C" { 94 | #[link_name = "\u{1}_ZNK2nn7friends12AsyncContext9GetResultEv"] 95 | pub fn AsyncContext_GetResult( 96 | this: *const AsyncContext, 97 | ) -> root::Result; 98 | } 99 | extern "C" { 100 | #[link_name = "\u{1}_ZN2nn7friends12AsyncContextC1Ev"] 101 | pub fn AsyncContext_AsyncContext(this: *mut AsyncContext); 102 | } 103 | extern "C" { 104 | #[link_name = "\u{1}_ZN2nn7friends12AsyncContextD1Ev"] 105 | pub fn AsyncContext_AsyncContext_destructor( 106 | this: *mut AsyncContext, 107 | ); 108 | } 109 | impl AsyncContext { 110 | #[inline] 111 | pub unsafe fn GetSystemEvent( 112 | &mut self, 113 | arg1: *mut root::nn::os::SystemEvent, 114 | ) -> root::Result { 115 | AsyncContext_GetSystemEvent(self, arg1) 116 | } 117 | #[inline] 118 | pub unsafe fn GetResult(&self) -> root::Result { 119 | AsyncContext_GetResult(self) 120 | } 121 | #[inline] 122 | pub unsafe fn new() -> Self { 123 | let mut __bindgen_tmp = ::core::mem::MaybeUninit::uninit(); 124 | AsyncContext_AsyncContext(__bindgen_tmp.as_mut_ptr()); 125 | __bindgen_tmp.assume_init() 126 | } 127 | #[inline] 128 | pub unsafe fn destruct(&mut self) { 129 | AsyncContext_AsyncContext_destructor(self) 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/nn/fs.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | pub struct DirectoryEntry { 6 | pub name: [u8; 769usize], 7 | pub _x302: [u8; 3usize], 8 | pub type_: u8, 9 | pub _x304: u8, 10 | pub fileSize: root::s64, 11 | } 12 | 13 | #[repr(C)] 14 | #[derive(Debug, Copy, Clone)] 15 | pub struct FileHandle { 16 | pub handle: u64, 17 | } 18 | 19 | #[repr(C)] 20 | #[derive(Debug, Copy, Clone)] 21 | pub struct DirectoryHandle { 22 | pub handle: u64, 23 | } 24 | 25 | pub const DirectoryEntryType_DirectoryEntryType_Directory: 26 | root::nn::fs::DirectoryEntryType = 0; 27 | pub const DirectoryEntryType_DirectoryEntryType_File: root::nn::fs::DirectoryEntryType = 28 | 1; 29 | pub type DirectoryEntryType = u32; 30 | pub const OpenMode_OpenMode_Read: root::nn::fs::OpenMode = 1; 31 | pub const OpenMode_OpenMode_Write: root::nn::fs::OpenMode = 2; 32 | pub const OpenMode_OpenMode_Append: root::nn::fs::OpenMode = 4; 33 | pub const OpenMode_OpenMode_ReadWrite: root::nn::fs::OpenMode = 3; 34 | pub type OpenMode = u32; 35 | pub const OpenDirectoryMode_OpenDirectoryMode_Directory: 36 | root::nn::fs::OpenDirectoryMode = 1; 37 | pub const OpenDirectoryMode_OpenDirectoryMode_File: root::nn::fs::OpenDirectoryMode = 2; 38 | pub const OpenDirectoryMode_OpenDirectoryMode_All: root::nn::fs::OpenDirectoryMode = 3; 39 | pub type OpenDirectoryMode = u32; 40 | pub const WriteOptionFlag_WriteOptionFlag_Flush: root::nn::fs::WriteOptionFlag = 1; 41 | pub type WriteOptionFlag = u32; 42 | #[repr(C)] 43 | #[derive(Debug, Copy, Clone)] 44 | pub struct WriteOption { 45 | pub flags: i32, 46 | } 47 | 48 | #[repr(C)] 49 | #[derive(Debug, Default, Copy, Clone)] 50 | pub struct FileTimeStamp { 51 | pub create: root::nn::time::PosixTime, 52 | pub modify: root::nn::time::PosixTime, 53 | pub access: root::nn::time::PosixTime, 54 | pub local_time: bool, 55 | pub padding: [u8; 7], 56 | } 57 | 58 | impl FileTimeStamp { 59 | pub fn new() -> Self { 60 | Self::default() 61 | } 62 | } 63 | 64 | extern "C" { 65 | #[link_name = "\u{1}_ZN2nn2fs22QueryMountRomCacheSizeEPm"] 66 | pub fn QueryMountRomCacheSize(size: *mut u64) -> root::Result; 67 | } 68 | extern "C" { 69 | #[link_name = "\u{1}_ZN2nn2fs22QueryMountRomCacheSizeEPmm"] 70 | pub fn QueryMountRomCacheSize1( 71 | size: *mut u64, 72 | arg1: root::nn::ApplicationId, 73 | ) -> root::Result; 74 | } 75 | extern "C" { 76 | #[link_name = "\u{1}_ZN2nn2fs8MountRomEPKcPvm"] 77 | pub fn MountRom( 78 | name: *const u8, 79 | buffer: *mut u8, 80 | bufferSize: root::ulong, 81 | ) -> root::Result; 82 | } 83 | extern "C" { 84 | #[link_name = "\u{1}_ZN2nn2fs19CanMountRomForDebugEv"] 85 | pub fn CanMountRomForDebug() -> root::Result; 86 | } 87 | extern "C" { 88 | #[link_name = "\u{1}_ZN2nn2fs11CanMountRomEm"] 89 | pub fn CanMountRom(arg1: root::nn::ApplicationId) -> root::Result; 90 | } 91 | extern "C" { 92 | #[link_name = "\u{1}_ZN2nn2fs28QueryMountRomOnFileCacheSizeEPmNS0_10FileHandleE"] 93 | pub fn QueryMountRomOnFileCacheSize( 94 | arg1: *mut u64, 95 | arg2: root::nn::fs::FileHandle, 96 | ) -> root::Result; 97 | } 98 | extern "C" { 99 | #[link_name = "\u{1}_ZN2nn2fs14MountRomOnFileEPKcNS0_10FileHandleEPvm"] 100 | pub fn MountRomOnFile( 101 | arg1: *const u8, 102 | arg2: root::nn::fs::FileHandle, 103 | arg3: *mut u8, 104 | arg4: u64, 105 | ) -> root::Result; 106 | } 107 | extern "C" { 108 | #[link_name = "\u{1}_ZN2nn2fs14EnsureSaveDataERKNS_7account3UidE"] 109 | pub fn EnsureSaveData(arg1: *const root::nn::account::Uid) -> root::Result; 110 | } 111 | extern "C" { 112 | #[link_name = "\u{1}_ZN2nn2fs6CommitEPKc"] 113 | pub fn Commit(mount_point: *const u8) -> root::Result; 114 | } 115 | extern "C" { 116 | #[link_name = "\u{1}_ZN2nn2fs13MountSaveDataEPKcRKNS_7account3UidE"] 117 | pub fn MountSaveData( 118 | mount_point: *const u8, 119 | user_id: *const root::nn::account::Uid, 120 | ) -> root::Result; 121 | } 122 | extern "C" { 123 | #[link_name = "\u{1}_ZN2nn2fs21MountSaveDataForDebugEPKc"] 124 | pub fn MountSaveDataForDebug( 125 | mount_point: *const u8 126 | ) -> root::Result; 127 | } 128 | extern "C" { 129 | #[link_name = "\u{1}_ZN2nn2fs12GetEntryTypeEPNS0_18DirectoryEntryTypeEPKc"] 130 | pub fn GetEntryType( 131 | type_: *mut root::nn::fs::DirectoryEntryType, 132 | path: *const u8, 133 | ) -> root::Result; 134 | } 135 | extern "C" { 136 | #[link_name = "\u{1}_ZN2nn2fs10CreateFileEPKcl"] 137 | pub fn CreateFile(filepath: *const u8, size: root::s64) -> root::Result; 138 | } 139 | extern "C" { 140 | #[link_name = "\u{1}_ZN2nn2fs8OpenFileEPNS0_10FileHandleEPKci"] 141 | pub fn OpenFile( 142 | arg1: *mut root::nn::fs::FileHandle, 143 | path: *const u8, 144 | arg2: root::s32, 145 | ) -> root::Result; 146 | } 147 | extern "C" { 148 | #[link_name = "\u{1}_ZN2nn2fs11SetFileSizeENS0_10FileHandleEl"] 149 | pub fn SetFileSize( 150 | fileHandle: root::nn::fs::FileHandle, 151 | filesize: root::s64, 152 | ) -> root::Result; 153 | } 154 | extern "C" { 155 | #[link_name = "\u{1}_ZN2nn2fs9CloseFileENS0_10FileHandleE"] 156 | pub fn CloseFile(fileHandle: root::nn::fs::FileHandle); 157 | } 158 | extern "C" { 159 | #[link_name = "\u{1}_ZN2nn2fs9FlushFileENS0_10FileHandleE"] 160 | pub fn FlushFile(fileHandle: root::nn::fs::FileHandle) -> root::Result; 161 | } 162 | extern "C" { 163 | #[link_name = "\u{1}_ZN2nn2fs10DeleteFileEPKc"] 164 | pub fn DeleteFile(filepath: *const u8) -> root::Result; 165 | } 166 | extern "C" { 167 | #[link_name = "\u{1}_ZN2nn2fs15DeleteDirectoryEPKc"] 168 | pub fn DeleteDirectory(path: *const u8) -> root::Result; 169 | } 170 | extern "C" { 171 | #[link_name = "\u{1}_ZN2nn2fs26DeleteDirectoryRecursivelyEPKc"] 172 | pub fn DeleteDirectoryRecursively(path: *const u8) -> root::Result; 173 | } 174 | extern "C" { 175 | #[link_name = "\u{1}_ZN2nn2fs10RenameFileEPKcS2_"] 176 | pub fn RenameFile( 177 | old: *const u8, 178 | new: *const u8, 179 | ) -> root::Result; 180 | } 181 | extern "C" { 182 | #[link_name = "\u{1}_ZN2nn2fs15RenameDirectoryEPKcS2_"] 183 | pub fn RenameDirectory( 184 | old: *const u8, 185 | new: *const u8, 186 | ) -> root::Result; 187 | } 188 | extern "C" { 189 | #[link_name = "\u{1}_ZN2nn2fs8ReadFileEPmNS0_10FileHandleElPvmRKi"] 190 | pub fn ReadFile( 191 | outSize: *mut u64, 192 | handle: root::nn::fs::FileHandle, 193 | offset: root::s64, 194 | buffer: *mut u8, 195 | bufferSize: u64, 196 | arg1: *const root::s32, 197 | ) -> root::Result; 198 | } 199 | extern "C" { 200 | #[link_name = "\u{1}_ZN2nn2fs8ReadFileEPmNS0_10FileHandleElPvm"] 201 | pub fn ReadFile1( 202 | outSize: *mut u64, 203 | handle: root::nn::fs::FileHandle, 204 | offset: root::s64, 205 | buffer: *mut u8, 206 | bufferSize: u64, 207 | ) -> root::Result; 208 | } 209 | extern "C" { 210 | #[link_name = "\u{1}_ZN2nn2fs8ReadFileENS0_10FileHandleElPvm"] 211 | pub fn ReadFile2( 212 | handle: root::nn::fs::FileHandle, 213 | offset: root::s64, 214 | buffer: *mut u8, 215 | bufferSize: u64, 216 | ) -> root::Result; 217 | } 218 | extern "C" { 219 | #[link_name = "\u{1}_ZN2nn2fs9WriteFileENS0_10FileHandleElPKvmRKNS0_11WriteOptionE"] 220 | pub fn WriteFile( 221 | handle: root::nn::fs::FileHandle, 222 | fileOffset: root::s64, 223 | buff: *const u8, 224 | size: u64, 225 | option: *const root::nn::fs::WriteOption, 226 | ) -> root::Result; 227 | } 228 | extern "C" { 229 | #[link_name = "\u{1}_ZN2nn2fs11GetFileSizeEPlNS0_10FileHandleE"] 230 | pub fn GetFileSize( 231 | size: *mut root::s64, 232 | fileHandle: root::nn::fs::FileHandle, 233 | ) -> root::Result; 234 | } 235 | extern "C" { 236 | #[link_name = "\u{1}_ZN2nn2fs13OpenDirectoryEPNS0_15DirectoryHandleEPKci"] 237 | pub fn OpenDirectory( 238 | handle: *mut root::nn::fs::DirectoryHandle, 239 | path: *const u8, 240 | openMode: root::s32, 241 | ) -> root::Result; 242 | } 243 | extern "C" { 244 | #[link_name = "\u{1}_ZN2nn2fs14CloseDirectoryENS0_15DirectoryHandleE"] 245 | pub fn CloseDirectory(directoryHandle: root::nn::fs::DirectoryHandle); 246 | } 247 | extern "C" { 248 | #[link_name = "\u{1}_ZN2nn2fs13ReadDirectoryEPlPNS0_14DirectoryEntryENS0_15DirectoryHandleEl"] 249 | pub fn ReadDirectory( 250 | arg1: *mut root::s64, 251 | arg2: *mut root::nn::fs::DirectoryEntry, 252 | directoryHandle: root::nn::fs::DirectoryHandle, 253 | arg3: root::s64, 254 | ) -> root::Result; 255 | } 256 | extern "C" { 257 | #[link_name = "\u{1}_ZN2nn2fs15CreateDirectoryEPKc"] 258 | pub fn CreateDirectory(directorypath: *const u8) -> root::Result; 259 | } 260 | extern "C" { 261 | #[link_name = "\u{1}_ZN2nn2fs22GetDirectoryEntryCountEPlNS0_15DirectoryHandleE"] 262 | pub fn GetDirectoryEntryCount( 263 | arg1: *mut root::s64, 264 | arg2: root::nn::fs::DirectoryHandle, 265 | ) -> root::Result; 266 | } 267 | extern "C" { 268 | #[link_name = "\u{1}_ZN2nn2fs11MountSdCardEPKc"] 269 | pub fn MountSdCard(arg1: *const u8) -> root::Result; 270 | } 271 | extern "C" { 272 | #[link_name = "\u{1}_ZN2nn2fs19MountSdCardForDebugEPKc"] 273 | pub fn MountSdCardForDebug(arg1: *const u8) -> root::Result; 274 | } 275 | extern "C" { 276 | #[link_name = "_ZN2nn2fs7UnmountEPKc"] 277 | pub fn Unmount(name: *const u8); 278 | } 279 | extern "C" { 280 | #[link_name = "\u{1}_ZN2nn2fs16IsSdCardInsertedEv"] 281 | pub fn IsSdCardInserted() -> bool; 282 | } 283 | extern "C" { 284 | #[link_name = "\u{1}_ZN2nn2fs12FormatSdCardEv"] 285 | pub fn FormatSdCard() -> root::Result; 286 | } 287 | extern "C" { 288 | #[link_name = "\u{1}_ZN2nn2fs18FormatSdCardDryRunEv"] 289 | pub fn FormatSdCardDryRun() -> root::Result; 290 | } 291 | extern "C" { 292 | #[link_name = "\u{1}_ZN2nn2fs16IsExFatSupportedEv"] 293 | pub fn IsExFatSupported() -> bool; 294 | } 295 | 296 | extern "C" { 297 | #[link_name = "\u{1}_ZN2nn2fs24GetFileTimeStampForDebugEPNS0_13FileTimeStampEPKc"] 298 | pub fn GetFileTimeStampForDebug( 299 | out_timestamp: *mut FileTimeStamp, 300 | filepath: *const u8, 301 | ) -> root::Result; 302 | } 303 | extern "C" { 304 | #[link_name = "_ZN2nn2fs17MountCacheStorageEPKc"] 305 | pub fn MountCacheStorage(mount_point: *const u8) -> root::Result; 306 | } 307 | pub fn mount_cache_storage>(mount_point: S) -> root::Result { 308 | unsafe { 309 | MountCacheStorage([mount_point.as_ref(), "\0"].concat().as_ptr()) 310 | } 311 | } 312 | -------------------------------------------------------------------------------- /src/nn/hid.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | #[derive(Debug, Copy, Clone, Default)] 6 | pub struct NpadHandheldState { 7 | pub updateCount: i64, 8 | pub Buttons: u64, 9 | pub LStickX: i32, 10 | pub LStickY: i32, 11 | pub RStickX: i32, 12 | pub RStickY: i32, 13 | pub Flags: u32, 14 | } 15 | #[repr(C)] 16 | #[derive(Debug, Copy, Clone, Default)] 17 | pub struct NpadGcState { 18 | pub updateCount: i64, 19 | pub Buttons: u64, 20 | pub LStickX: i32, 21 | pub LStickY: i32, 22 | pub RStickX: i32, 23 | pub RStickY: i32, 24 | pub Flags: u32, 25 | pub LTrigger: u32, 26 | pub RTrigger: u32, 27 | } 28 | #[repr(C)] 29 | #[derive(Debug, Copy, Clone)] 30 | pub struct NpadStyleTag { 31 | _unused: [u8; 0], 32 | } 33 | 34 | #[repr(C)] 35 | #[derive(Debug, Copy, Clone)] 36 | pub struct NpadStyleSet { 37 | pub flags: u32, 38 | } 39 | 40 | // pub u32 NpadStyleFullKey = 0x1; 41 | // pub u32 NpadStyleHandheld = 0x2; 42 | // pub u32 NpadStyleJoyDual = 0x4; 43 | // pub u32 NpadStyleJoyLeft = 0x8; 44 | // pub u32 NpadStyleJoyRight = 0x10; 45 | 46 | #[repr(C)] 47 | pub struct ControllerSupportArg { 48 | pub mMinPlayerCount: u8, 49 | pub mMaxPlayerCount: u8, 50 | pub mTakeOverConnection: u8, 51 | pub mLeftJustify: bool, 52 | pub mPermitJoyconDual: bool, 53 | pub mSingleMode: bool, 54 | pub mUseColors: bool, 55 | pub mColors: [root::nn::util::Color4u8; 4usize], 56 | pub mUsingControllerNames: u8, 57 | pub mControllerNames: [[u8; 129usize]; 4usize], 58 | } 59 | 60 | #[repr(C)] 61 | #[derive(Debug, Copy, Clone)] 62 | pub struct ControllerSupportResultInfo { 63 | pub mPlayerCount: i32, 64 | pub mSelectedId: i32, 65 | } 66 | 67 | extern "C" { 68 | #[link_name = "\u{1}_ZN2nn3hid14InitializeNpadEv"] 69 | pub fn InitializeNpad(); 70 | } 71 | extern "C" { 72 | #[link_name = "\u{1}_ZN2nn3hid22SetSupportedNpadIdTypeEPKjm"] 73 | pub fn SetSupportedNpadIdType(arg1: *const u32, arg2: u64); 74 | } 75 | extern "C" { 76 | #[link_name = "\u{1}_ZN2nn3hid24SetSupportedNpadStyleSetENS_4util10BitFlagSetILi32ENS0_12NpadStyleTagEEE"] 77 | pub fn SetSupportedNpadStyleSet(arg1: u8); 78 | } 79 | extern "C" { 80 | #[link_name = "\u{1}_ZN2nn3hid15GetNpadStyleSetERKj"] 81 | pub fn GetNpadStyleSet(arg1: *const u32) -> NpadStyleSet; 82 | } 83 | extern "C" { 84 | #[link_name = "\u{1}_ZN2nn3hid19GetPlayerLedPatternERKj"] 85 | pub fn GetPlayerLedPattern(arg1: *const u32); 86 | } 87 | extern "C" { 88 | #[link_name = "\u{1}_ZN2nn3hid13GetNpadStatesEPNS0_17NpadHandheldStateEiRKj"] 89 | pub fn GetNpadStates( 90 | arg1: *mut root::nn::hid::NpadHandheldState, 91 | arg2: root::s32, 92 | arg3: *const u32, 93 | ); 94 | } 95 | 96 | extern "C" { 97 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_17NpadHandheldStateERKj"] 98 | pub fn GetNpadHandheldState( 99 | arg1: *mut root::nn::hid::NpadHandheldState, 100 | arg2: *const u32, 101 | ); 102 | 103 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_16NpadFullKeyStateERKj"] 104 | pub fn GetNpadFullKeyState( 105 | arg1: *mut root::nn::hid::NpadHandheldState, 106 | arg2: *const u32, 107 | ); 108 | 109 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_11NpadGcStateERKj"] 110 | pub fn GetNpadGcState( 111 | arg1: *mut root::nn::hid::NpadGcState, 112 | arg2: *const u32, 113 | ); 114 | 115 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_16NpadJoyDualStateERKj"] 116 | pub fn GetNpadJoyDualState( 117 | arg1: *mut root::nn::hid::NpadHandheldState, 118 | arg2: *const u32, 119 | ); 120 | 121 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_16NpadJoyLeftStateERKj"] 122 | pub fn GetNpadJoyLeftState( 123 | arg1: *mut root::nn::hid::NpadHandheldState, 124 | arg2: *const u32, 125 | ); 126 | 127 | #[link_name = "\u{1}_ZN2nn3hid12GetNpadStateEPNS0_17NpadJoyRightStateERKj"] 128 | pub fn GetNpadJoyRightState( 129 | arg1: *mut root::nn::hid::NpadHandheldState, 130 | arg2: *const u32, 131 | ); 132 | } -------------------------------------------------------------------------------- /src/nn/image.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub const JpegStatus_OK: JpegStatus = 0; 4 | pub const JpegStatus_INVALID_FORMAT: JpegStatus = -32; 5 | pub const JpegStatus_UNSUPPORTED_FORMAT: JpegStatus = -33; 6 | pub const JpegStatus_OUT_OF_MEMORY: JpegStatus = -64; 7 | pub type JpegStatus = i32; 8 | pub const PixelFormat_RGBA32: PixelFormat = 0; 9 | pub const PixelFormat_RGB24: PixelFormat = 1; 10 | pub type PixelFormat = u32; 11 | pub const ProcessStage_UNREGISTERED: ProcessStage = 0; 12 | pub const ProcessStage_REGISTERED: ProcessStage = 1; 13 | pub const ProcessStage_ANALYZED: ProcessStage = 2; 14 | pub type ProcessStage = u32; 15 | #[repr(C)] 16 | pub struct Dimension { 17 | pub width: f32, 18 | pub height: f32, 19 | } 20 | 21 | #[repr(C)] 22 | pub struct JpegDecoder__bindgen_vtable(libc::c_void); 23 | #[repr(C)] 24 | pub struct JpegDecoder { 25 | pub vtable_: *const JpegDecoder__bindgen_vtable, 26 | pub mProcessStage: ProcessStage, 27 | pub mData: *mut u8, 28 | pub mSize: root::s64, 29 | pub _18: root::s32, 30 | pub mFormat: PixelFormat, 31 | pub mImgDimensions: Dimension, 32 | pub _28: root::s64, 33 | } 34 | 35 | extern "C" { 36 | #[link_name = "\u{1}_ZN2nn5image11JpegDecoder12SetImageDataEPKvm"] 37 | pub fn JpegDecoder_SetImageData( 38 | this: *mut JpegDecoder, 39 | source: *const u8, 40 | size: u64, 41 | ); 42 | } 43 | extern "C" { 44 | #[link_name = "\u{1}_ZN2nn5image11JpegDecoder7AnalyzeEv"] 45 | pub fn JpegDecoder_Analyze( 46 | this: *mut JpegDecoder, 47 | ) -> JpegStatus; 48 | } 49 | extern "C" { 50 | #[link_name = "\u{1}_ZNK2nn5image11JpegDecoder20GetAnalyzedDimensionEv"] 51 | pub fn JpegDecoder_GetAnalyzedDimension( 52 | this: *const JpegDecoder, 53 | ) -> Dimension; 54 | } 55 | extern "C" { 56 | #[link_name = "\u{1}_ZNK2nn5image11JpegDecoder25GetAnalyzedWorkBufferSizeEv"] 57 | pub fn JpegDecoder_GetAnalyzedWorkBufferSize( 58 | this: *const JpegDecoder, 59 | ) -> root::s64; 60 | } 61 | extern "C" { 62 | #[link_name = "\u{1}_ZN2nn5image11JpegDecoder6DecodeEPvliS2_l"] 63 | pub fn JpegDecoder_Decode( 64 | this: *mut JpegDecoder, 65 | out: *mut u8, 66 | arg1: root::s64, 67 | alignment: root::s32, 68 | arg2: *mut u8, 69 | arg3: root::s64, 70 | ) -> JpegStatus; 71 | } 72 | extern "C" { 73 | #[link_name = "\u{1}_ZN2nn5image11JpegDecoderC1Ev"] 74 | pub fn JpegDecoder_JpegDecoder(this: *mut JpegDecoder); 75 | } 76 | impl JpegDecoder { 77 | #[inline] 78 | pub unsafe fn SetImageData(&mut self, source: *const u8, size: u64) { 79 | JpegDecoder_SetImageData(self, source, size) 80 | } 81 | #[inline] 82 | pub unsafe fn Analyze(&mut self) -> JpegStatus { 83 | JpegDecoder_Analyze(self) 84 | } 85 | #[inline] 86 | pub unsafe fn GetAnalyzedDimension(&self) -> Dimension { 87 | JpegDecoder_GetAnalyzedDimension(self) 88 | } 89 | #[inline] 90 | pub unsafe fn GetAnalyzedWorkBufferSize(&self) -> root::s64 { 91 | JpegDecoder_GetAnalyzedWorkBufferSize(self) 92 | } 93 | #[inline] 94 | pub unsafe fn Decode( 95 | &mut self, 96 | out: *mut u8, 97 | arg1: root::s64, 98 | alignment: root::s32, 99 | arg2: *mut u8, 100 | arg3: root::s64, 101 | ) -> JpegStatus { 102 | JpegDecoder_Decode(self, out, arg1, alignment, arg2, arg3) 103 | } 104 | #[inline] 105 | pub unsafe fn new() -> Self { 106 | let mut __bindgen_tmp = ::core::mem::MaybeUninit::uninit(); 107 | JpegDecoder_JpegDecoder(__bindgen_tmp.as_mut_ptr()); 108 | __bindgen_tmp.assume_init() 109 | } 110 | } 111 | extern "C" { 112 | #[link_name = "\u{1}_ZN2nn5image11JpegDecoderD1Ev"] 113 | pub fn JpegDecoder_JpegDecoder_destructor(this: *mut JpegDecoder); 114 | } -------------------------------------------------------------------------------- /src/nn/init.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub mod detail; 4 | 5 | extern "C" { 6 | #[link_name = "\u{1}_ZN2nn4init19InitializeAllocatorEPvm"] 7 | pub fn InitializeAllocator(addr: *mut u8, size: u64); 8 | } 9 | extern "C" { 10 | #[link_name = "\u{1}_ZN2nn4init12GetAllocatorEv"] 11 | pub fn GetAllocator() -> *mut root::nn::mem::StandardAllocator; 12 | } -------------------------------------------------------------------------------- /src/nn/init/detail.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn4init6detail30DefaultAllocatorForThreadLocalEmm"] 6 | pub fn DefaultAllocatorForThreadLocal( 7 | arg1: u64, 8 | arg2: u64, 9 | ) -> *mut u8; 10 | } 11 | extern "C" { 12 | #[link_name = "\u{1}_ZN2nn4init6detail32DefaultDeallocatorForThreadLocalEPvm"] 13 | pub fn DefaultDeallocatorForThreadLocal( 14 | arg1: *mut u8, 15 | arg2: u64, 16 | ) -> *mut u8; 17 | } -------------------------------------------------------------------------------- /src/nn/ldn.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn3ldn10InitializeEv"] 6 | pub fn Initialize() -> root::Result; 7 | } 8 | extern "C" { 9 | #[link_name = "\u{1}_ZN2nn3ldn8FinalizeEv"] 10 | pub fn Finalize() -> root::Result; 11 | } -------------------------------------------------------------------------------- /src/nn/mem.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | pub struct StandardAllocator { 5 | pub mIsInitialized: bool, 6 | pub mIsEnabledThreadCache: bool, 7 | pub _2: u16, 8 | pub mAllocAddr: *mut u64, 9 | } 10 | 11 | extern "C" { 12 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator10InitializeEPvm"] 13 | pub fn StandardAllocator_Initialize( 14 | this: *mut StandardAllocator, 15 | address: *mut u8, 16 | size: u64, 17 | ); 18 | } 19 | extern "C" { 20 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator8FinalizeEv"] 21 | pub fn StandardAllocator_Finalize(this: *mut StandardAllocator); 22 | } 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator10ReallocateEPvm"] 25 | pub fn StandardAllocator_Reallocate( 26 | this: *mut StandardAllocator, 27 | address: *mut u8, 28 | newSize: u64, 29 | ) -> *mut u8; 30 | } 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator8AllocateEm"] 33 | pub fn StandardAllocator_Allocate( 34 | this: *mut StandardAllocator, 35 | size: u64, 36 | ) -> *mut u8; 37 | } 38 | extern "C" { 39 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator4FreeEPv"] 40 | pub fn StandardAllocator_Free( 41 | this: *mut StandardAllocator, 42 | address: *mut u8, 43 | ); 44 | } 45 | extern "C" { 46 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocator4DumpEv"] 47 | pub fn StandardAllocator_Dump(this: *mut StandardAllocator); 48 | } 49 | extern "C" { 50 | #[link_name = "\u{1}_ZN2nn3mem17StandardAllocatorC1Ev"] 51 | pub fn StandardAllocator_StandardAllocator( 52 | this: *mut StandardAllocator, 53 | ); 54 | } 55 | impl StandardAllocator { 56 | #[inline] 57 | pub unsafe fn Initialize(&mut self, address: *mut u8, size: u64) { 58 | StandardAllocator_Initialize(self, address, size) 59 | } 60 | #[inline] 61 | pub unsafe fn Finalize(&mut self) { 62 | StandardAllocator_Finalize(self) 63 | } 64 | #[inline] 65 | pub unsafe fn Reallocate( 66 | &mut self, 67 | address: *mut u8, 68 | newSize: u64, 69 | ) -> *mut u8 { 70 | StandardAllocator_Reallocate(self, address, newSize) 71 | } 72 | #[inline] 73 | pub unsafe fn Allocate(&mut self, size: u64) -> *mut u8 { 74 | StandardAllocator_Allocate(self, size) 75 | } 76 | #[inline] 77 | pub unsafe fn Free(&mut self, address: *mut u8) { 78 | StandardAllocator_Free(self, address) 79 | } 80 | #[inline] 81 | pub unsafe fn Dump(&mut self) { 82 | StandardAllocator_Dump(self) 83 | } 84 | #[inline] 85 | pub unsafe fn new() -> Self { 86 | let mut __bindgen_tmp = ::core::mem::MaybeUninit::uninit(); 87 | StandardAllocator_StandardAllocator(__bindgen_tmp.as_mut_ptr()); 88 | __bindgen_tmp.assume_init() 89 | } 90 | } -------------------------------------------------------------------------------- /src/nn/mod.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub type ApplicationId = u64; 4 | 5 | pub mod time; 6 | pub mod err; 7 | pub mod os; 8 | pub mod settings; 9 | pub mod oe; 10 | pub mod account; 11 | pub mod fs; 12 | pub mod ro; 13 | pub mod crypto; 14 | pub mod prepo; 15 | pub mod vi; 16 | pub mod web; 17 | pub mod image; 18 | pub mod friends; 19 | pub mod diag; 20 | pub mod ssl; 21 | pub mod mem; 22 | pub mod init; 23 | pub mod util; 24 | pub mod ui2d; 25 | pub mod hid; 26 | pub mod audio; 27 | pub mod svc; 28 | pub mod nifm; 29 | pub mod ldn; 30 | pub mod swkbd; 31 | pub mod socket; 32 | pub mod aoc; 33 | 34 | #[repr(C)] 35 | pub struct TimeSpan { 36 | pub nanoseconds: u64, 37 | } 38 | 39 | extern "C" { 40 | #[link_name = "\u{1}_ZN2nn11ReferSymbolEPKv"] 41 | pub fn ReferSymbol(arg1: *const u8); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/nn/nifm.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn4nifm10InitializeEv"] 6 | pub fn Initialize() -> root::Result; 7 | } 8 | extern "C" { 9 | #[link_name = "\u{1}_ZN2nn4nifm19SetLocalNetworkModeEb"] 10 | pub fn SetLocalNetworkMode(arg1: bool); 11 | } 12 | extern "C" { 13 | #[link_name = "\u{1}_ZN2nn4nifm27SubmitNetworkRequestAndWaitEv"] 14 | pub fn SubmitNetworkRequestAndWait(); 15 | } 16 | extern "C" { 17 | #[link_name = "\u{1}_ZN2nn4nifm18IsNetworkAvailableEv"] 18 | pub fn IsNetworkAvailable() -> bool; 19 | } 20 | extern "C" { 21 | #[link_name = "\u{1}_ZN2nn4nifm26HandleNetworkRequestResultEv"] 22 | pub fn HandleNetworkRequestResult() -> root::Result; 23 | } 24 | extern "C" { 25 | #[link_name = "\u{1}_ZN2nn4nifm20SubmitNetworkRequestEv"] 26 | pub fn SubmitNetworkRequest(); 27 | } 28 | extern "C" { 29 | #[link_name = "\u{1}_ZN2nn4nifm22IsNetworkRequestOnHoldEv"] 30 | pub fn IsNetworkRequestOnHold() -> bool; 31 | } 32 | extern "C" { 33 | #[link_name = "\u{1}_ZN2nn4nifm26GetCurrentPrimaryIpAddressEPm"] 34 | pub fn GetCurrentPrimaryIpAddress(inAddr: *mut u64) -> root::Result; 35 | } -------------------------------------------------------------------------------- /src/nn/oe.rs: -------------------------------------------------------------------------------- 1 | use core::ffi::CStr; 2 | 3 | use alloc::string::{String, ToString}; 4 | 5 | #[allow(unused_imports)] 6 | use self::super::root; 7 | pub type FocusHandlingMode = i32; 8 | pub type PerformanceMode = u32; 9 | #[repr(C)] 10 | #[derive(Debug, Copy, Clone)] 11 | pub struct DisplayVersion { 12 | pub name: [u8; 16usize], 13 | } 14 | 15 | extern "C" { 16 | #[link_name = "\u{1}_ZN2nn2oe10InitializeEv"] 17 | pub fn Initialize(); 18 | } 19 | extern "C" { 20 | #[link_name = "\u{1}_ZN2nn2oe27SetPerformanceConfigurationENS0_15PerformanceModeEi"] 21 | pub fn SetPerformanceConfiguration(arg1: root::nn::oe::PerformanceMode, arg2: u32); 22 | } 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn2oe27GetPerformanceConfigurationENS0_15PerformanceModeE"] 25 | pub fn GetPerformanceConfiguration(arg1: root::nn::oe::PerformanceMode) -> u32; 26 | } 27 | extern "C" { 28 | #[link_name = "\u{1}_ZN2nn2oe16GetOperationModeEv"] 29 | pub fn GetOperationMode() -> root::s32; 30 | } 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn2oe18GetPerformanceModeEv"] 33 | pub fn GetPerformanceMode() -> PerformanceMode; 34 | } 35 | extern "C" { 36 | #[link_name = "\u{1}_ZN2nn2oe28SetResumeNotificationEnabledEb"] 37 | pub fn SetResumeNotificationEnabled(arg1: bool); 38 | } 39 | extern "C" { 40 | #[link_name = "\u{1}_ZN2nn2oe42SetOperationModeChangedNotificationEnabledEb"] 41 | pub fn SetOperationModeChangedNotificationEnabled(arg1: bool); 42 | } 43 | extern "C" { 44 | #[link_name = "\u{1}_ZN2nn2oe44SetPerformanceModeChangedNotificationEnabledEb"] 45 | pub fn SetPerformanceModeChangedNotificationEnabled(arg1: bool); 46 | } 47 | extern "C" { 48 | #[link_name = "\u{1}_ZN2nn2oe20SetFocusHandlingModeEi"] 49 | pub fn SetFocusHandlingMode(arg1: root::nn::oe::FocusHandlingMode); 50 | } 51 | extern "C" { 52 | #[link_name = "\u{1}_ZN2nn2oe25TryPopNotificationMessageEPj"] 53 | pub fn TryPopNotificationMessage(arg1: *mut u32) -> bool; 54 | } 55 | extern "C" { 56 | #[link_name = "\u{1}_ZN2nn2oe20GetCurrentFocusStateEv"] 57 | pub fn GetCurrentFocusState() -> root::s32; 58 | } 59 | extern "C" { 60 | #[link_name = "\u{1}_ZN2nn2oe23EnableGamePlayRecordingEPvm"] 61 | pub fn EnableGamePlayRecording(arg1: *mut u8, arg2: u64); 62 | } 63 | extern "C" { 64 | #[link_name = "\u{1}_ZN2nn2oe37IsUserInactivityDetectionTimeExtendedEv"] 65 | pub fn IsUserInactivityDetectionTimeExtended() -> bool; 66 | } 67 | 68 | pub fn is_user_inactivity_detection_time_extended() -> bool { 69 | let result = unsafe { IsUserInactivityDetectionTimeExtended() }; 70 | 71 | result 72 | } 73 | extern "C" { 74 | #[link_name = "\u{1}_ZN2nn2oe38SetUserInactivityDetectionTimeExtendedEb"] 75 | pub fn SetUserInactivityDetectionTimeExtended(arg1: bool); 76 | } 77 | 78 | pub fn set_user_inactivity_detection_time_extended(do_extend: bool) { 79 | unsafe { SetUserInactivityDetectionTimeExtended(do_extend); } 80 | } 81 | 82 | extern "C" { 83 | #[link_name = "\u{1}_ZN2nn2oe17FinishStartupLogoEv"] 84 | pub fn FinishStartupLogo(); 85 | } 86 | 87 | pub fn finish_startup_logo() { 88 | unsafe { FinishStartupLogo(); } 89 | } 90 | extern "C" { 91 | #[link_name = "\u{1}_ZN2nn2oe18ReportUserIsActiveEv"] 92 | pub fn ReportUserIsActive(); 93 | } 94 | extern "C" { 95 | #[link_name = "\u{1}_ZN2nn2oe18GetDesiredLanguageEv"] 96 | pub fn GetDesiredLanguage() -> root::nn::settings::LanguageCode; 97 | } 98 | 99 | pub fn get_desired_language() -> String { 100 | let mut result = ""; 101 | 102 | let lang_code = unsafe { GetDesiredLanguage() }; 103 | 104 | result = core::str::from_utf8(&lang_code.code).unwrap(); 105 | 106 | return result.to_string(); 107 | } 108 | 109 | extern "C" { 110 | #[link_name = "\u{1}_ZN2nn2oe17GetDisplayVersionEPNS0_14DisplayVersionE"] 111 | pub fn GetDisplayVersion(arg1: *mut root::nn::oe::DisplayVersion); 112 | } 113 | extern "C" { 114 | #[link_name = "\u{1}_ZN2nn2oe21IsCpuOverclockEnabledEv"] 115 | pub fn IsCpuOverclockEnabled() -> bool; 116 | } 117 | extern "C" { 118 | #[link_name = "\u{1}_ZN2nn2oe22SetCpuOverclockEnabledEb"] 119 | pub fn SetCpuOverclockEnabled(enabled: bool); 120 | } 121 | 122 | pub fn get_display_version() -> String { 123 | let mut ver = DisplayVersion { name: [0; 16] }; 124 | 125 | unsafe { 126 | GetDisplayVersion(&mut ver); 127 | } 128 | let string = CStr::from_bytes_until_nul(&ver.name).unwrap(); 129 | 130 | return string.to_str().unwrap().to_string(); 131 | } 132 | 133 | #[repr(C)] 134 | #[derive(Debug, Copy, Clone)] 135 | pub enum CpuBoostMode { 136 | Disabled = 0, 137 | Boost = 1, 138 | } 139 | extern "C" { 140 | #[link_name = "\u{1}_ZN2nn2oe15SetCpuBoostModeENS0_12CpuBoostModeE"] 141 | pub fn SetCpuBoostMode(mode: CpuBoostMode); 142 | } 143 | 144 | pub fn set_cpu_boost_mode(mode: CpuBoostMode) { 145 | unsafe { 146 | SetCpuBoostMode(mode); 147 | } 148 | } 149 | 150 | extern "C" { 151 | #[link_name = "_ZN2nn2oe14RestartProgramEPKvm"] 152 | pub fn RestartProgram(argv: *const u8, argc: u32) -> !; 153 | } 154 | 155 | #[deprecated = "This will be removed in the next major release, please switch to restart_program_no_args()"] 156 | pub fn RestartProgramNoArgs() -> ! { 157 | unsafe { RestartProgram("".as_ptr() as _, 0) } 158 | } 159 | 160 | pub fn restart_program_no_args() -> ! { 161 | unsafe { RestartProgram("".as_ptr() as _, 0) } 162 | } 163 | extern "C" { 164 | #[link_name = "\u{1}_ZN2nn2oe28RequestToRelaunchApplicationEv"] 165 | pub fn RequestToRelaunchApplication() -> !; 166 | } 167 | 168 | pub fn request_to_relaunch_application() -> ! { 169 | unsafe { RequestToRelaunchApplication(); } 170 | } 171 | extern "C" { 172 | #[link_name = "\u{1}_ZN2nn2oe15ExitApplicationEv"] 173 | pub fn ExitApplication() -> !; 174 | } 175 | pub fn exit_application() -> ! { 176 | unsafe { ExitApplication(); } 177 | } 178 | -------------------------------------------------------------------------------- /src/nn/os.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | use self::detail::*; 4 | pub mod detail; 5 | 6 | pub type Tick = u64; 7 | pub type LightEventType = u64; 8 | 9 | #[repr(C)] 10 | pub struct SemaphoreType { 11 | _multiWaitObjectList: MultiWaitObjectList, 12 | _state: u8, 13 | _count: i32, 14 | _maxCount: i32, 15 | _csSemaphore: InternalCriticalSection, 16 | _cvNotZero: InternalConditionVariable, 17 | } 18 | 19 | #[repr(C)] 20 | pub struct EventType { 21 | pub _x0: *mut root::nn::os::EventType, 22 | pub _x8: *mut root::nn::os::EventType, 23 | pub isSignaled: bool, 24 | pub initiallySignaled: bool, 25 | pub shouldAutoClear: bool, 26 | pub isInit: bool, 27 | pub signalCounter: u32, 28 | pub signalCounter2: u32, 29 | pub crit: root::nn::os::detail::InternalCriticalSection, 30 | pub condvar: root::nn::os::detail::InternalConditionVariable, 31 | } 32 | 33 | pub type Event = root::nn::os::EventType; 34 | pub const EventClearMode_EventClearMode_ManualClear: root::nn::os::EventClearMode = 0; 35 | pub const EventClearMode_EventClearMode_AutoClear: root::nn::os::EventClearMode = 1; 36 | pub type EventClearMode = u32; 37 | 38 | pub struct MessageQueueType { 39 | pub _x0: u64, 40 | pub _x8: u64, 41 | pub _x10: u64, 42 | pub _x18: u64, 43 | pub Buffer: *mut u8, 44 | pub MaxCount: u32, 45 | pub Count: u32, 46 | pub Offset: u32, 47 | pub Initialized: bool, 48 | pub _x38: root::nn::os::detail::InternalCriticalSection, 49 | pub _x3C: root::nn::os::detail::InternalConditionVariable, 50 | pub _x40: root::nn::os::detail::InternalConditionVariable, 51 | } 52 | 53 | 54 | #[repr(C)] 55 | #[derive(Debug, Copy, Clone)] 56 | pub struct ConditionVariableType { 57 | pub _address: u8, 58 | } 59 | #[repr(C)] 60 | #[derive(Debug, Copy, Clone)] 61 | pub struct SystemEvent { 62 | pub _unused: [u8; 0x28], 63 | } 64 | #[repr(C)] 65 | #[derive(Debug, Copy, Clone)] 66 | pub struct SystemEventType { 67 | pub _unused: [u8; 0x29], 68 | } 69 | impl SystemEventType { 70 | pub fn new(clear_mode: SystemEventClearMode) -> Self { 71 | let x = Self { _unused: [0; 0x29] }; 72 | unsafe { CreateSystemEvent(&x, clear_mode, false) }; 73 | x 74 | } 75 | } 76 | #[repr(C)] 77 | #[derive(Debug, Copy, Clone)] 78 | pub enum SystemEventClearMode { 79 | Manual = 0, 80 | Auto = 1, 81 | } 82 | extern "C" { 83 | #[link_name = "\u{1}_ZN2nn2os11SetHostArgcEi"] 84 | pub fn SetHostArgc(arg1: root::s32); 85 | } 86 | extern "C" { 87 | #[link_name = "\u{1}_ZN2nn2os11GetHostArgcEv"] 88 | pub fn GetHostArgc() -> root::s32; 89 | } 90 | extern "C" { 91 | #[link_name = "\u{1}_ZN2nn2os11SetHostArgvEPPc"] 92 | pub fn SetHostArgv(arg1: *mut *mut u8); 93 | } 94 | extern "C" { 95 | #[link_name = "\u{1}_ZN2nn2os11GetHostArgvEv"] 96 | pub fn GetHostArgv() -> *mut *mut u8; 97 | } 98 | extern "C" { 99 | #[link_name = "\u{1}_ZN2nn2os30InitializeVirtualAddressMemoryEv"] 100 | pub fn InitializeVirtualAddressMemory(); 101 | } 102 | extern "C" { 103 | #[link_name = "\u{1}_ZN2nn2os21AllocateAddressRegionEPmm"] 104 | pub fn AllocateAddressRegion(arg1: *mut u64, arg2: u64) -> root::Result; 105 | } 106 | extern "C" { 107 | #[link_name = "\u{1}_ZN2nn2os14AllocateMemoryEPmm"] 108 | pub fn AllocateMemory(arg1: *mut u64, arg2: u64) -> root::Result; 109 | } 110 | extern "C" { 111 | #[link_name = "\u{1}_ZN2nn2os19AllocateMemoryPagesEmm"] 112 | pub fn AllocateMemoryPages(arg1: u64, arg2: u64) -> root::Result; 113 | } 114 | extern "C" { 115 | #[link_name = "\u{1}_ZN2nn2os19AllocateMemoryBlockEPmm"] 116 | pub fn AllocateMemoryBlock(arg1: *mut u64, arg2: u64); 117 | } 118 | extern "C" { 119 | #[link_name = "\u{1}_ZN2nn2os15FreeMemoryBlockEmm"] 120 | pub fn FreeMemoryBlock(arg1: u64, arg2: u64); 121 | } 122 | extern "C" { 123 | #[link_name = "\u{1}_ZN2nn2os17SetMemoryHeapSizeEm"] 124 | pub fn SetMemoryHeapSize(arg1: u64); 125 | } 126 | extern "C" { 127 | #[link_name = "\u{1}_ZN2nn2os17CreateSystemEventEPNS0_15SystemEventTypeENS0_14EventClearModeEb"] 128 | pub fn CreateSystemEvent( 129 | arg1: *const SystemEventType, 130 | clear_mode: SystemEventClearMode, 131 | skip_init: bool, 132 | ) -> root::Result; 133 | } 134 | extern "C" { 135 | #[link_name = "\u{1}_ZN2nn2os18TryWaitSystemEventEPNS0_15SystemEventTypeE"] 136 | pub fn TryWaitSystemEvent(arg1: *const SystemEventType) -> bool; 137 | } 138 | #[repr(C)] 139 | pub struct MutexType { 140 | pub impl_: root::nnosMutexType, 141 | } 142 | 143 | 144 | extern "C" { 145 | #[link_name = "\u{1}_ZN2nn2os15InitializeMutexEPNS0_9MutexTypeEbi"] 146 | pub fn InitializeMutex( 147 | arg1: *mut root::nn::os::MutexType, 148 | arg2: bool, 149 | arg3: root::s32, 150 | ); 151 | } 152 | extern "C" { 153 | #[link_name = "\u{1}_ZN2nn2os13FinalizeMutexEPNS0_9MutexTypeE"] 154 | pub fn FinalizeMutex(arg1: *mut root::nn::os::MutexType); 155 | } 156 | extern "C" { 157 | #[link_name = "\u{1}_ZN2nn2os9LockMutexEPNS0_9MutexTypeE"] 158 | pub fn LockMutex(arg1: *mut root::nn::os::MutexType); 159 | } 160 | extern "C" { 161 | #[link_name = "\u{1}_ZN2nn2os12TryLockMutexEPNS0_9MutexTypeE"] 162 | pub fn TryLockMutex(arg1: *mut root::nn::os::MutexType) -> bool; 163 | } 164 | extern "C" { 165 | #[link_name = "\u{1}_ZN2nn2os11UnlockMutexEPNS0_9MutexTypeE"] 166 | pub fn UnlockMutex(arg1: *mut root::nn::os::MutexType); 167 | } 168 | extern "C" { 169 | #[link_name = "\u{1}_ZN2nn2os28IsMutexLockedByCurrentThreadEPKNS0_9MutexTypeE"] 170 | pub fn IsMutexLockedByCurrentThread(arg1: *const root::nn::os::MutexType) -> bool; 171 | } 172 | extern "C" { 173 | #[link_name = "\u{1}_ZN2nn2os22InitializeMessageQueueEPNS0_16MessageQueueTypeEPmm"] 174 | pub fn InitializeMessageQueue( 175 | arg1: *mut root::nn::os::MessageQueueType, 176 | buf: *mut u64, 177 | queueCount: u64, 178 | ); 179 | } 180 | extern "C" { 181 | #[link_name = "\u{1}_ZN2nn2os20FinalizeMessageQueueEPNS0_16MessageQueueTypeE"] 182 | pub fn FinalizeMessageQueue(arg1: *mut root::nn::os::MessageQueueType); 183 | } 184 | extern "C" { 185 | #[link_name = "\u{1}_ZN2nn2os19TrySendMessageQueueEPNS0_16MessageQueueTypeEm"] 186 | pub fn TrySendMessageQueue( 187 | arg1: *mut root::nn::os::MessageQueueType, 188 | arg2: u64, 189 | ) -> bool; 190 | } 191 | extern "C" { 192 | #[link_name = "\u{1}_ZN2nn2os16SendMessageQueueEPNS0_16MessageQueueTypeEm"] 193 | pub fn SendMessageQueue(arg1: *mut root::nn::os::MessageQueueType, arg2: u64); 194 | } 195 | extern "C" { 196 | #[link_name = "\u{1}_ZN2nn2os21TimedSendMessageQueueEPNS0_16MessageQueueTypeEmNS_8TimeSpanE"] 197 | pub fn TimedSendMessageQueue( 198 | arg1: *mut root::nn::os::MessageQueueType, 199 | arg2: u64, 200 | arg3: root::nn::TimeSpan, 201 | ) -> bool; 202 | } 203 | extern "C" { 204 | #[link_name = "\u{1}_ZN2nn2os22TryReceiveMessageQueueEPmPNS0_16MessageQueueTypeE"] 205 | pub fn TryReceiveMessageQueue( 206 | out: *mut u64, 207 | arg1: *mut root::nn::os::MessageQueueType, 208 | ) -> bool; 209 | } 210 | extern "C" { 211 | #[link_name = "\u{1}_ZN2nn2os19ReceiveMessageQueueEPmPNS0_16MessageQueueTypeE"] 212 | pub fn ReceiveMessageQueue( 213 | out: *mut u64, 214 | arg1: *mut root::nn::os::MessageQueueType, 215 | ); 216 | } 217 | extern "C" { 218 | #[link_name = "\u{1}_ZN2nn2os24TimedReceiveMessageQueueEPmPNS0_16MessageQueueTypeENS_8TimeSpanE"] 219 | pub fn TimedReceiveMessageQueue( 220 | out: *mut u64, 221 | arg1: *mut root::nn::os::MessageQueueType, 222 | arg2: root::nn::TimeSpan, 223 | ) -> bool; 224 | } 225 | extern "C" { 226 | #[link_name = "\u{1}_ZN2nn2os19TryPeekMessageQueueEPmPKNS0_16MessageQueueTypeE"] 227 | pub fn TryPeekMessageQueue( 228 | arg1: *mut u64, 229 | arg2: *const root::nn::os::MessageQueueType, 230 | ) -> bool; 231 | } 232 | extern "C" { 233 | #[link_name = "\u{1}_ZN2nn2os16PeekMessageQueueEPmPKNS0_16MessageQueueTypeE"] 234 | pub fn PeekMessageQueue( 235 | arg1: *mut u64, 236 | arg2: *const root::nn::os::MessageQueueType, 237 | ); 238 | } 239 | extern "C" { 240 | #[link_name = "\u{1}_ZN2nn2os21TimedPeekMessageQueueEPmPKNS0_16MessageQueueTypeE"] 241 | pub fn TimedPeekMessageQueue( 242 | arg1: *mut u64, 243 | arg2: *const root::nn::os::MessageQueueType, 244 | ) -> bool; 245 | } 246 | extern "C" { 247 | #[link_name = "\u{1}_ZN2nn2os18TryJamMessageQueueEPNS0_16MessageQueueTypeEm"] 248 | pub fn TryJamMessageQueue( 249 | arg1: *mut root::nn::os::MessageQueueType, 250 | arg2: u64, 251 | ) -> bool; 252 | } 253 | extern "C" { 254 | #[link_name = "\u{1}_ZN2nn2os15JamMessageQueueEPNS0_16MessageQueueTypeEm"] 255 | pub fn JamMessageQueue(arg1: *mut root::nn::os::MessageQueueType, arg2: u64); 256 | } 257 | extern "C" { 258 | #[link_name = "\u{1}_ZN2nn2os20TimedJamMessageQueueEPNS0_16MessageQueueTypeEmNS_8TimeSpanE"] 259 | pub fn TimedJamMessageQueue( 260 | arg1: *mut root::nn::os::MessageQueueType, 261 | arg2: u64, 262 | arg3: root::nn::TimeSpan, 263 | ) -> bool; 264 | } 265 | extern "C" { 266 | #[link_name = "\u{1}_ZN2nn2os27InitializeConditionVariableEPNS0_21ConditionVariableTypeE"] 267 | pub fn InitializeConditionVariable(arg1: *mut root::nn::os::ConditionVariableType); 268 | } 269 | extern "C" { 270 | #[link_name = "\u{1}_ZN2nn2os25FinalizeConditionVariableEPNS0_21ConditionVariableTypeE"] 271 | pub fn FinalizeConditionVariable(arg1: *mut root::nn::os::ConditionVariableType); 272 | } 273 | extern "C" { 274 | #[link_name = "\u{1}_ZN2nn2os23SignalConditionVariableEPNS0_21ConditionVariableTypeE"] 275 | pub fn SignalConditionVariable(arg1: *mut root::nn::os::ConditionVariableType); 276 | } 277 | extern "C" { 278 | #[link_name = "\u{1}_ZN2nn2os26BroadcastConditionVariableEPNS0_21ConditionVariableTypeE"] 279 | pub fn BroadcastConditionVariable(arg1: *mut root::nn::os::ConditionVariableType); 280 | } 281 | extern "C" { 282 | #[link_name = "\u{1}_ZN2nn2os21WaitConditionVariableEPNS0_21ConditionVariableTypeE"] 283 | pub fn WaitConditionVariable(arg1: *mut root::nn::os::ConditionVariableType); 284 | } 285 | extern "C" { 286 | #[link_name = "\u{1}_ZN2nn2os26TimedWaitConditionVariableEPNS0_21ConditionVariableTypeEPNS0_9MutexTypeENS_8TimeSpanE"] 287 | pub fn TimedWaitConditionVariable( 288 | arg1: *mut root::nn::os::ConditionVariableType, 289 | arg2: *mut root::nn::os::MutexType, 290 | arg3: root::nn::TimeSpan, 291 | ) -> u8; 292 | } 293 | 294 | // THREADS 295 | 296 | #[repr(C)] 297 | pub struct ThreadType { 298 | inner: [u8; 0x1c0], 299 | } 300 | 301 | impl ThreadType { 302 | pub fn new() -> Self { 303 | Self { 304 | inner: [0u8;0x1c0], 305 | } 306 | } 307 | } 308 | 309 | impl Default for ThreadType { 310 | fn default() -> Self { 311 | Self::new() 312 | } 313 | } 314 | 315 | extern "C" { 316 | #[link_name = "\u{1}_ZN2nn2os12CreateThreadEPNS0_10ThreadTypeEPFvPvES3_S3_mi"] 317 | pub fn CreateThread( 318 | thread: *mut ThreadType, 319 | function: extern "C" fn(arg: *mut libc::c_void), 320 | argument: *mut u8, 321 | stack: *mut u8, 322 | stack_size: usize, 323 | priority: i32, 324 | ) -> root::Result; 325 | } 326 | extern "C" { 327 | #[link_name = "\u{1}_ZN2nn2os12CreateThreadEPNS0_10ThreadTypeEPFvPvES3_S3_mii"] 328 | pub fn CreateThread1( 329 | thread: *mut ThreadType, 330 | function: extern "C" fn(arg: *mut libc::c_void), 331 | argument: *mut u8, 332 | stack: *mut u8, 333 | stack_size: usize, 334 | priority: i32, 335 | ideal_core_id: i32, 336 | ) -> root::Result; 337 | } 338 | extern "C" { 339 | #[link_name = "\u{1}_ZN2nn2os13DestroyThreadEPNS0_10ThreadTypeE"] 340 | pub fn DestroyThread(thread: *mut ThreadType); 341 | } 342 | extern "C" { 343 | #[link_name = "\u{1}_ZN2nn2os11StartThreadEPNS0_10ThreadTypeE"] 344 | pub fn StartThread(thread: *mut ThreadType); 345 | } 346 | extern "C" { 347 | #[link_name = "\u{1}_ZN2nn2os13SetThreadNameEPNS0_10ThreadTypeEPKc"] 348 | pub fn SetThreadName( 349 | thread: *mut ThreadType, 350 | thread_name: *const u8, 351 | ); 352 | } 353 | extern "C" { 354 | #[link_name = "\u{1}_ZN2nn2os20SetThreadNamePointerEPNS0_10ThreadTypeEPKc"] 355 | pub fn SetThreadNamePointer( 356 | thread: *mut ThreadType, 357 | thread_name: *const u8, 358 | ); 359 | } 360 | extern "C" { 361 | #[link_name = "\u{1}_ZN2nn2os20GetThreadNamePointerEPKNS0_10ThreadTypeE"] 362 | pub fn GetThreadNamePointer( 363 | thread: *const ThreadType, 364 | ) -> *mut u8; 365 | } 366 | extern "C" { 367 | #[link_name = "\u{1}_ZN2nn2os16GetCurrentThreadEv"] 368 | pub fn GetCurrentThread() -> *mut ThreadType; 369 | } 370 | extern "C" { 371 | #[link_name = "\u{1}_ZN2nn2os20ChangeThreadPriorityEPNS0_10ThreadTypeEi"] 372 | pub fn ChangeThreadPriority( 373 | thread: *mut ThreadType, 374 | priority: i32, 375 | ) -> i32; 376 | } 377 | extern "C" { 378 | #[link_name = "\u{1}_ZN2nn2os17GetThreadPriorityEPKNS0_10ThreadTypeE"] 379 | pub fn GetThreadPriority(thread: *const ThreadType) -> i32; 380 | } 381 | extern "C" { 382 | #[link_name = "\u{1}_ZN2nn2os11YieldThreadEv"] 383 | pub fn YieldThread(); 384 | } 385 | extern "C" { 386 | #[link_name = "\u{1}_ZN2nn2os13SuspendThreadEPNS0_10ThreadTypeE"] 387 | pub fn SuspendThread(thread: *mut ThreadType); 388 | } 389 | extern "C" { 390 | #[link_name = "\u{1}_ZN2nn2os12ResumeThreadEPNS0_10ThreadTypeE"] 391 | pub fn ResumeThread(thread: *mut ThreadType); 392 | } 393 | extern "C" { 394 | #[link_name = "\u{1}_ZN2nn2os11SleepThreadENS_8TimeSpanE"] 395 | pub fn SleepThread(time: root::nn::TimeSpan); 396 | } 397 | extern "C" { 398 | #[link_name = "\u{1}_ZN2nn2os10WaitThreadEPNS0_10ThreadTypeE"] 399 | pub fn WaitThread(thread: *mut ThreadType); 400 | } 401 | 402 | // Events 403 | 404 | extern "C" { 405 | #[link_name = "\u{1}_ZN2nn2os15InitializeEventEPNS0_9EventTypeEbNS0_14EventClearModeE"] 406 | pub fn InitializeEvent( 407 | arg1: *mut root::nn::os::EventType, 408 | initiallySignaled: bool, 409 | clearMode: root::nn::os::EventClearMode, 410 | ); 411 | } 412 | extern "C" { 413 | #[link_name = "\u{1}_ZN2nn2os13FinalizeEventEPNS0_9EventTypeE"] 414 | pub fn FinalizeEvent(arg1: *mut root::nn::os::EventType); 415 | } 416 | extern "C" { 417 | #[link_name = "\u{1}_ZN2nn2os11SignalEventEPNS0_9EventTypeE"] 418 | pub fn SignalEvent(arg1: *mut root::nn::os::EventType); 419 | } 420 | extern "C" { 421 | #[link_name = "\u{1}_ZN2nn2os9WaitEventEPNS0_9EventTypeE"] 422 | pub fn WaitEvent(arg1: *mut root::nn::os::EventType); 423 | } 424 | extern "C" { 425 | #[link_name = "\u{1}_ZN2nn2os12TryWaitEventEPNS0_9EventTypeE"] 426 | pub fn TryWaitEvent(arg1: *mut root::nn::os::EventType) -> bool; 427 | } 428 | extern "C" { 429 | #[link_name = "\u{1}_ZN2nn2os14TimedWaitEventEPNS0_9EventTypeENS_8TimeSpanE"] 430 | pub fn TimedWaitEvent( 431 | arg1: *mut root::nn::os::EventType, 432 | arg2: root::nn::TimeSpan, 433 | ) -> bool; 434 | } 435 | extern "C" { 436 | #[link_name = "\u{1}_ZN2nn2os10ClearEventEPNS0_9EventTypeE"] 437 | pub fn ClearEvent(arg1: *mut root::nn::os::EventType); 438 | } 439 | 440 | extern "C" { 441 | #[link_name = "\u{1}_ZN2nn2os16AcquireSemaphoreEPNS0_13SemaphoreTypeE"] 442 | pub fn AcquireSemaphore( 443 | arg1: *mut root::nn::os::SemaphoreType, 444 | ); 445 | } 446 | extern "C" { 447 | #[link_name = "\u{1}_ZN2nn2os16ReleaseSemaphoreEPNS0_13SemaphoreTypeE"] 448 | pub fn ReleaseSemaphore( 449 | arg1: *mut root::nn::os::SemaphoreType, 450 | ); 451 | } 452 | extern "C" { 453 | #[link_name = "\u{1}_ZN2nn2os17FinalizeSemaphoreEPNS0_13SemaphoreTypeE"] 454 | pub fn FinalizeSemaphore(arg1: *mut root::nn::os::SemaphoreType); 455 | } 456 | extern "C" { 457 | #[link_name = "\u{1}_ZN2nn2os19InitializeSemaphoreEPNS0_13SemaphoreTypeEii"] 458 | pub fn InitializeSemaphore(arg1: *mut root::nn::os::SemaphoreType, initial_count: i32, max_count: i32); 459 | } 460 | 461 | #[repr(C)] 462 | pub struct CpuRegister { 463 | #[doc = "< 64-bit AArch64 register view."] 464 | pub x: root::__BindgenUnionField, 465 | #[doc = "< 32-bit AArch64 register view."] 466 | pub w: root::__BindgenUnionField, 467 | #[doc = "< AArch32 register view."] 468 | pub r: root::__BindgenUnionField, 469 | pub bindgen_union_field: u64, 470 | } 471 | 472 | #[doc = " Armv8 NEON register."] 473 | #[repr(C)] 474 | #[repr(align(16))] 475 | pub struct FpuRegister { 476 | #[doc = "< 128-bit vector view."] 477 | pub v: root::__BindgenUnionField, 478 | #[doc = "< 64-bit double-precision view."] 479 | pub d: root::__BindgenUnionField, 480 | #[doc = "< 32-bit single-precision view."] 481 | pub s: root::__BindgenUnionField, 482 | pub bindgen_union_field: u128, 483 | } 484 | 485 | #[repr(C)] 486 | #[repr(align(16))] 487 | pub struct UserExceptionInfo { 488 | #[doc = "< See \\ref ThreadExceptionDesc."] 489 | pub ErrorDescription: u32, 490 | pub pad: [u32; 3usize], 491 | #[doc = "< GPRs 0..28. Note: also contains AArch32 registers."] 492 | pub CpuRegisters: [root::nn::os::CpuRegister; 29usize], 493 | #[doc = "< Frame pointer."] 494 | pub FP: root::nn::os::CpuRegister, 495 | #[doc = "< Link register."] 496 | pub LR: root::nn::os::CpuRegister, 497 | #[doc = "< Stack pointer."] 498 | pub SP: root::nn::os::CpuRegister, 499 | #[doc = "< Program counter (elr_el1)."] 500 | pub PC: root::nn::os::CpuRegister, 501 | pub padding: u64, 502 | #[doc = "< 32 general-purpose NEON registers."] 503 | pub FpuRegisters: [root::nn::os::FpuRegister; 32usize], 504 | #[doc = "< pstate & 0xFF0FFE20"] 505 | pub PState: u32, 506 | pub AFSR0: u32, 507 | pub AFSR1: u32, 508 | pub ESR: u32, 509 | #[doc = "< Fault Address Register."] 510 | pub FAR: root::nn::os::CpuRegister, 511 | } 512 | 513 | extern "C" { 514 | #[link_name = "\u{1}_ZN2nn2os23SetUserExceptionHandlerEPFvPNS0_17UserExceptionInfoEEPvmS2_"] 515 | #[allow(improper_ctypes)] 516 | pub fn SetUserExceptionHandler( 517 | arg1: ::core::option::Option< 518 | unsafe extern "C" fn(arg1: *mut root::nn::os::UserExceptionInfo), 519 | >, 520 | arg2: *mut u8, 521 | arg3: root::ulong, 522 | arg4: *mut root::nn::os::UserExceptionInfo, 523 | ); 524 | } 525 | extern "C" { 526 | #[link_name = "\u{1}_ZN2nn2os19GenerateRandomBytesEPvm"] 527 | pub fn GenerateRandomBytes(arg1: *mut u8, arg2: u64); 528 | } 529 | extern "C" { 530 | #[link_name = "\u{1}_ZN2nn2os13GetSystemTickEv"] 531 | pub fn GetSystemTick() -> root::nn::os::Tick; 532 | } 533 | extern "C" { 534 | #[link_name = "\u{1}_ZN2nn2os26GetThreadAvailableCoreMaskEv"] 535 | pub fn GetThreadAvailableCoreMask() -> u64; 536 | } 537 | 538 | 539 | pub type FiberFunction = extern "C" fn(*const u8) -> *const FiberType; 540 | 541 | #[repr(C)] 542 | pub struct FiberType { 543 | pub status: u8, 544 | pub is_aligned: bool, 545 | pub function: FiberFunction, 546 | pub args: *mut libc::c_void, 547 | pub unk1: *mut libc::c_void, 548 | pub stack: *mut libc::c_void, 549 | pub stack_size: usize, 550 | pub context: [u8; 208], 551 | } 552 | 553 | extern "C" { 554 | #[link_name = "\u{1}_ZN2nn2os15InitializeFiberEPNS0_9FiberTypeEPFS2_PvES3_S3_mi"] 555 | pub fn InitializeFiber(fiber: *mut FiberType, fiber_function: FiberFunction, arguments: *mut libc::c_void, stack: *mut libc::c_void, stack_size: usize, flag: i32); 556 | 557 | #[link_name = "_ZN2nn2os13SwitchToFiberEPNS0_9FiberTypeE"] 558 | pub fn SwitchToFiber(fiber: *mut FiberType); 559 | 560 | #[link_name = "_ZN2nn2os15GetCurrentFiberEv"] 561 | pub fn GetCurrentFiber() -> *mut FiberType; 562 | 563 | #[link_name = "_ZN2nn2os13FinalizeFiberEPNS0_9FiberTypeE"] 564 | pub fn FinalizeFiber(fiber: *mut FiberType); 565 | } -------------------------------------------------------------------------------- /src/nn/os/detail.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | pub struct MultiWaitObjectList { 6 | inner: [*mut (); 2], 7 | } 8 | 9 | #[repr(C)] 10 | pub struct InternalCriticalSection { 11 | pub Image: u32, 12 | } 13 | 14 | #[repr(C)] 15 | pub struct InternalConditionVariable { 16 | pub Image: u32, 17 | } 18 | 19 | extern "C" { 20 | #[link_name = "\u{1}_ZN2nn2os6detail22g_CommandLineParameterE"] 21 | pub static mut g_CommandLineParameter: root::s32; 22 | } 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn2os6detail26g_CommandLineParameterArgvE"] 25 | pub static mut g_CommandLineParameterArgv: *mut *mut u8; 26 | } -------------------------------------------------------------------------------- /src/nn/prepo.rs: -------------------------------------------------------------------------------- 1 | use alloc::boxed::Box; 2 | use alloc::string::{ToString, String}; 3 | 4 | #[allow(unused_imports)] 5 | use self::super::root; 6 | #[repr(C)] 7 | #[derive(Debug)] 8 | pub struct PlayReport { 9 | pub event_id: [u8;32], 10 | pub buffer: *const u8, 11 | pub size: usize, 12 | pub position: usize 13 | } 14 | 15 | #[repr(C)] 16 | pub struct Any64BitId { 17 | pub id: i64 18 | } 19 | 20 | const EventIdLengthMax: usize = 31; 21 | const KeyLengthMax: usize = 63; 22 | 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport10SetEventIdEPKc"] 25 | pub fn PlayReport_SetEventId( 26 | this: *mut PlayReport, 27 | event_id: *const u8, 28 | ) -> root::Result; 29 | 30 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport9SetBufferEPvm"] 31 | pub fn PlayReport_SetBuffer(this: *mut PlayReport, buf: *const u8, size: usize); 32 | 33 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport3AddEPKcl"] 34 | pub fn PlayReport_AddLong( 35 | this: *mut PlayReport, 36 | key: *const u8, 37 | value: i64, 38 | ) -> root::Result; 39 | 40 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport3AddEPKcd"] 41 | pub fn PlayReport_AddDouble( 42 | this: *mut PlayReport, 43 | key: *const u8, 44 | value: f64, 45 | ) -> root::Result; 46 | 47 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport3AddEPKcS3_"] 48 | pub fn PlayReport_AddString( 49 | this: *mut PlayReport, 50 | key: *const u8, 51 | value: *const u8, 52 | ) -> root::Result; 53 | 54 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport3AddEPKcRKNS0_10Any64BitIdE"] 55 | pub fn PlayReport_AddAny64BitID( 56 | this: *mut PlayReport, 57 | key: *const u8, 58 | value: Any64BitId, 59 | ) -> root::Result; 60 | 61 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport4SaveEv"] 62 | pub fn PlayReport_Save(this: PlayReport) -> root::Result; 63 | 64 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReport4SaveERKNS_7account3UidE"] 65 | pub fn PlayReport_SaveWithUserId( 66 | this: PlayReport, 67 | uid: *const root::nn::account::Uid, 68 | ) -> root::Result; 69 | 70 | #[link_name = "\u{1}_ZN2nn5prepo10PlayReportC1Ev"] 71 | pub fn PlayReport_PlayReport(this: *mut PlayReport); 72 | 73 | #[link_name = "_ZN2nn5prepo10PlayReportC1EPKc"] 74 | pub fn PlayReport_PlayReportWithEventID(this: *mut PlayReport, event_id: *const u8); 75 | 76 | #[link_name = "\u{1}_ZNK2nn5prepo10PlayReport8GetCountEv"] 77 | pub fn PlayReport_GetCount(this: *mut PlayReport) -> u64; 78 | 79 | #[link_name = "_ZN2nn5prepo28RequestImmediateTransmissionEv"] 80 | pub fn RequestImmediateTransmission() -> root::Result; 81 | } 82 | impl PlayReport { 83 | #[inline] 84 | pub fn get_count(&mut self) -> u64 { 85 | unsafe { PlayReport_GetCount(self) } 86 | } 87 | #[inline] 88 | pub fn set_event_id(&mut self, event_id: &str) -> root::Result { 89 | let event_id = event_id.to_string() + "\0"; 90 | if event_id.len() > EventIdLengthMax { 91 | panic!("Event ID is too long!"); 92 | } 93 | let event_id = event_id.as_bytes().as_ptr(); 94 | unsafe { PlayReport_SetEventId(self, event_id) } 95 | } 96 | #[inline] 97 | fn set_buffer(&mut self, buf: *const u8, size: usize) { 98 | unsafe { PlayReport_SetBuffer(self, buf, size) } 99 | } 100 | #[inline] 101 | pub fn add_long( 102 | &mut self, 103 | key: &str, 104 | value: i64, 105 | ) -> root::Result { 106 | let key = key.to_string() + "\0"; 107 | if key.len() > KeyLengthMax { 108 | panic!("Key is too long!"); 109 | } 110 | let key = key.as_bytes().as_ptr(); 111 | unsafe { PlayReport_AddLong(self, key, value) } 112 | } 113 | #[inline] 114 | pub fn add_double( 115 | &mut self, 116 | key: &str, 117 | value: f64, 118 | ) -> root::Result { 119 | let key = key.to_string() + "\0"; 120 | if key.len() > KeyLengthMax { 121 | panic!("Key is too long!"); 122 | } 123 | let key = key.as_bytes().as_ptr(); 124 | unsafe { PlayReport_AddDouble(self, key, value) } 125 | } 126 | #[inline] 127 | pub fn add_string( 128 | &mut self, 129 | key: &str, 130 | value: &str, 131 | ) -> root::Result { 132 | let key = key.to_string() + "\0"; 133 | if key.len() > KeyLengthMax { 134 | panic!("Key is too long!"); 135 | } 136 | let key = key.as_bytes().as_ptr(); 137 | 138 | let value = value.to_string() + "\0"; 139 | let value = value.as_bytes().as_ptr(); 140 | unsafe { PlayReport_AddString(self, key, value) } 141 | } 142 | #[inline] 143 | pub fn add_any64bitid( 144 | &mut self, 145 | key: &str, 146 | value: Any64BitId, 147 | ) -> root::Result { 148 | let key = key.to_string() + "\0"; 149 | if key.len() > KeyLengthMax { 150 | panic!("Key is too long!"); 151 | } 152 | let key = key.as_bytes().as_ptr(); 153 | unsafe { PlayReport_AddAny64BitID(self, key, value) } 154 | } 155 | #[inline] 156 | pub fn save(self) -> root::Result { 157 | unsafe { PlayReport_Save(self) } 158 | } 159 | #[inline] 160 | pub fn save_with_user_id( 161 | self, 162 | uid: *const root::nn::account::Uid, 163 | ) -> root::Result { 164 | unsafe { PlayReport_SaveWithUserId(self, uid) } 165 | } 166 | #[inline] 167 | pub fn save_for_current_user(self) { 168 | // This provides a UserHandle and sets the User in a Open state to be used. 169 | let handle = root::nn::account::try_open_preselected_user().expect("OpenPreselectedUser should not return false"); 170 | // Obtain the UID for this user 171 | let uid = root::nn::account::get_user_id(&handle).expect("GetUserId should return a valid Uid"); 172 | self.save_with_user_id(&uid); 173 | root::nn::account::close_user(handle); 174 | } 175 | #[inline] 176 | pub fn new() -> Self { 177 | let buf = Box::new([0u8; 0x4000]); 178 | let buf = Box::leak(buf); 179 | let buf = Box::new([0u8; 0x4000]); 180 | let buf = Box::leak(buf); 181 | let mut prepo: PlayReport = PlayReport { event_id: [0;32], buffer: core::ptr::null(), size: 0, position: 0 }; 182 | unsafe { PlayReport_PlayReport(&mut prepo) }; 183 | 184 | prepo.set_buffer(buf.as_ptr(), 0x4000); 185 | prepo 186 | } 187 | #[inline] 188 | pub fn new_with_event_id(event_id: &str) -> Self { 189 | let event_id = event_id.to_string() + "\0"; 190 | if event_id.len() > EventIdLengthMax { 191 | panic!("Event ID is too long!"); 192 | } 193 | let event_id = event_id.as_bytes().as_ptr(); 194 | 195 | let buf = Box::new([0u8; 0x4000]); 196 | let buf = Box::leak(buf); 197 | let mut prepo: PlayReport = PlayReport { event_id: [0;32], buffer: core::ptr::null(), size: 0, position: 0 }; 198 | unsafe { PlayReport_PlayReportWithEventID(&mut prepo, event_id) }; 199 | 200 | prepo.set_buffer(buf.as_ptr(), 0x4000); 201 | prepo 202 | } 203 | } 204 | 205 | impl Drop for PlayReport { 206 | fn drop(&mut self) { 207 | unsafe { libc::free(self.buffer as *mut libc::c_void); } 208 | } 209 | } -------------------------------------------------------------------------------- /src/nn/ro.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | pub struct Module { 5 | pub ModuleObject: *mut root::rtld::ModuleObject, 6 | pub State: u32, 7 | pub NroPtr: *mut u8, 8 | pub BssPtr: *mut u8, 9 | pub _x20: *mut u8, 10 | pub SourceBuffer: *mut u8, 11 | pub Name: [u8; 256usize], 12 | pub _x130: u8, 13 | pub _x131: u8, 14 | pub isLoaded: bool, 15 | } 16 | 17 | #[repr(C)] 18 | pub struct ModuleId { 19 | pub build_id: [u8; 32usize], 20 | } 21 | 22 | #[repr(C)] 23 | pub struct NroHeader { 24 | pub entrypoint_insn: u32, 25 | pub mod_offset: u32, 26 | pub _x8: [u8; 8usize], 27 | pub magic: u32, 28 | pub _x14: [u8; 4usize], 29 | pub size: u32, 30 | pub reserved_1C: [u8; 4usize], 31 | pub text_offset: u32, 32 | pub text_size: u32, 33 | pub ro_offset: u32, 34 | pub ro_size: u32, 35 | pub rw_offset: u32, 36 | pub rw_size: u32, 37 | pub bss_size: u32, 38 | pub _x3C: [u8; 4usize], 39 | pub module_id: root::nn::ro::ModuleId, 40 | pub _x60: [u8; 32usize], 41 | } 42 | 43 | #[repr(C)] 44 | pub struct ProgramId { 45 | pub value: u64, 46 | } 47 | 48 | #[repr(C)] 49 | pub struct NrrHeader { 50 | pub magic: u32, 51 | pub _x4: [u8; 12usize], 52 | pub program_id_mask: u64, 53 | pub program_id_pattern: u64, 54 | pub _x20: [u8; 16usize], 55 | pub modulus: [u8; 256usize], 56 | pub fixed_key_signature: [u8; 256usize], 57 | pub nrr_signature: [u8; 256usize], 58 | pub program_id: root::nn::ro::ProgramId, 59 | pub size: u32, 60 | pub type_: u8, 61 | pub _x33D: [u8; 3usize], 62 | pub hashes_offset: u32, 63 | pub num_hashes: u32, 64 | pub _x348: [u8; 8usize], 65 | } 66 | 67 | #[repr(C)] 68 | pub struct RegistrationInfo { 69 | pub state: root::nn::ro::RegistrationInfo_State, 70 | pub nrrPtr: *mut root::nn::ro::NrrHeader, 71 | pub _x10: u64, 72 | pub _x18: u64, 73 | } 74 | pub const RegistrationInfo_State_State_Unregistered: 75 | root::nn::ro::RegistrationInfo_State = 0; 76 | pub const RegistrationInfo_State_State_Registered: 77 | root::nn::ro::RegistrationInfo_State = 1; 78 | pub type RegistrationInfo_State = u32; 79 | 80 | pub const BindFlag_BindFlag_Now: root::nn::ro::BindFlag = 1; 81 | pub const BindFlag_BindFlag_Lazy: root::nn::ro::BindFlag = 2; 82 | pub type BindFlag = u32; 83 | extern "C" { 84 | #[link_name = "\u{1}_ZN2nn2ro10InitializeEv"] 85 | pub fn Initialize() -> root::Result; 86 | } 87 | extern "C" { 88 | #[link_name = "\u{1}_ZN2nn2ro12LookupSymbolEPmPKc"] 89 | pub fn LookupSymbol( 90 | pOutAddress: *mut usize, 91 | name: *const u8, 92 | ) -> root::Result; 93 | } 94 | extern "C" { 95 | #[link_name = "\u{1}_ZN2nn2ro18LookupModuleSymbolEPmPKNS0_6ModuleEPKc"] 96 | pub fn LookupModuleSymbol( 97 | pOutAddress: *mut usize, 98 | pModule: *const root::nn::ro::Module, 99 | name: *const u8, 100 | ) -> root::Result; 101 | } 102 | extern "C" { 103 | #[link_name = "\u{1}_ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmi"] 104 | pub fn LoadModule( 105 | pOutModule: *mut root::nn::ro::Module, 106 | pImage: *const u8, 107 | buffer: *mut u8, 108 | bufferSize: root::size_t, 109 | flag: i32, 110 | ) -> root::Result; 111 | } 112 | extern "C" { 113 | #[link_name = "\u{1}_ZN2nn2ro12UnloadModuleEPNS0_6ModuleE"] 114 | pub fn UnloadModule(arg1: *mut root::nn::ro::Module) -> root::Result; 115 | } 116 | extern "C" { 117 | #[link_name = "\u{1}_ZN2nn2ro13GetBufferSizeEPmPKv"] 118 | pub fn GetBufferSize( 119 | arg1: *mut root::size_t, 120 | arg2: *const u8, 121 | ) -> root::Result; 122 | } 123 | extern "C" { 124 | #[link_name = "\u{1}_ZN2nn2ro18RegisterModuleInfoEPNS0_16RegistrationInfoEPKv"] 125 | pub fn RegisterModuleInfo( 126 | arg1: *mut root::nn::ro::RegistrationInfo, 127 | arg2: *const u8, 128 | ) -> root::Result; 129 | } 130 | extern "C" { 131 | #[link_name = "\u{1}_ZN2nn2ro18RegisterModuleInfoEPNS0_16RegistrationInfoEPKvj"] 132 | pub fn RegisterModuleInfo1( 133 | arg1: *mut root::nn::ro::RegistrationInfo, 134 | arg2: *const u8, 135 | arg3: root::uint, 136 | ) -> root::Result; 137 | } 138 | extern "C" { 139 | #[link_name = "\u{1}_ZN2nn2ro20UnregisterModuleInfoEPNS0_16RegistrationInfoE"] 140 | pub fn UnregisterModuleInfo( 141 | arg1: *mut root::nn::ro::RegistrationInfo, 142 | ) -> root::Result; 143 | } -------------------------------------------------------------------------------- /src/nn/settings.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | pub mod system; 5 | 6 | pub const Language_Language_Japanese: root::nn::settings::Language = 0; 7 | pub const Language_Language_English: root::nn::settings::Language = 1; 8 | pub const Language_Language_French: root::nn::settings::Language = 2; 9 | pub const Language_Language_German: root::nn::settings::Language = 3; 10 | pub const Language_Language_Italian: root::nn::settings::Language = 4; 11 | pub const Language_Language_Spanish: root::nn::settings::Language = 5; 12 | pub const Language_Language_Chinese: root::nn::settings::Language = 6; 13 | pub const Language_Language_Korean: root::nn::settings::Language = 7; 14 | pub const Language_Language_Dutch: root::nn::settings::Language = 8; 15 | pub const Language_Language_Portuguese: root::nn::settings::Language = 9; 16 | pub const Language_Language_Russian: root::nn::settings::Language = 10; 17 | pub const Language_Language_Taiwanese: root::nn::settings::Language = 11; 18 | pub const Language_Language_BritishEnglish: root::nn::settings::Language = 12; 19 | pub const Language_Language_CanadianFrench: root::nn::settings::Language = 13; 20 | pub const Language_Language_LatinAmericanSpanish: root::nn::settings::Language = 14; 21 | pub type Language = u32; 22 | #[repr(C)] 23 | #[derive(Debug, Copy, Clone)] 24 | pub struct LanguageCode { 25 | pub code: [u8; 8usize], 26 | } 27 | 28 | extern "C" { 29 | #[link_name = "\u{1}_ZN2nn8settings12LanguageCode4MakeENS0_8LanguageE"] 30 | pub fn LanguageCode_Make( 31 | arg1: root::nn::settings::Language, 32 | ) -> root::nn::settings::LanguageCode; 33 | } 34 | impl LanguageCode { 35 | #[inline] 36 | pub unsafe fn Make( 37 | arg1: root::nn::settings::Language, 38 | ) -> root::nn::settings::LanguageCode { 39 | LanguageCode_Make(arg1) 40 | } 41 | } -------------------------------------------------------------------------------- /src/nn/settings/system.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | pub struct FirmwareVersion { 5 | pub major: u8, 6 | pub minor: u8, 7 | pub micro: u8, 8 | pub padding1: u8, 9 | pub revision_major: u8, 10 | pub revision_minor: u8, 11 | pub padding2: u8, 12 | pub padding3: u8, 13 | pub platform: [u8; 32usize], 14 | pub version_hash: [u8; 64usize], 15 | pub display_version: [u8; 24usize], 16 | pub display_title: [u8; 128usize], 17 | } 18 | 19 | extern "C" { 20 | #[link_name = "\u{1}_ZN2nn8settings6system18GetFirmwareVersionEPNS1_15FirmwareVersionE"] 21 | pub fn GetFirmwareVersion( 22 | arg1: *mut root::nn::settings::system::FirmwareVersion, 23 | ) -> root::Result; 24 | } -------------------------------------------------------------------------------- /src/nn/socket.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | pub struct InAddr { 6 | pub addr: u32, 7 | } 8 | 9 | #[repr(C)] 10 | pub struct SockAddrIn { 11 | pub sin_len: u8, 12 | pub sin_family: u8, 13 | pub sin_port: u16, 14 | pub sin_addr: [u8;4], 15 | pub padding: u64, 16 | } 17 | 18 | extern "C" { 19 | #[link_name = "\u{1}_ZN2nn6socket10InitializeEPvmmi"] 20 | pub fn Initialize( 21 | pool: *mut u8, 22 | poolSize: root::ulong, 23 | allocPoolSize: root::ulong, 24 | concurLimit: i32, 25 | ) -> root::Result; 26 | } 27 | extern "C" { 28 | #[link_name = "\u{1}_ZN2nn6socket10InitializeERKNS0_6ConfigE"] 29 | pub fn Initialize_Config(config: *mut u8) -> root::Result; 30 | } 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn6socket8FinalizeEv"] 33 | pub fn Finalize() -> root::Result; 34 | } 35 | extern "C" { 36 | #[link_name = "\u{1}_ZN2nn6socket10SetSockOptEiiiPKvj"] 37 | pub fn SetSockOpt( 38 | socket: root::s32, 39 | socketLevel: root::s32, 40 | option: root::s32, 41 | arg1: *const u8, 42 | len: u32, 43 | ) -> root::s32; 44 | } 45 | extern "C" { 46 | #[link_name = "\u{1}_ZN2nn6socket4SendEiPKvmi"] 47 | pub fn Send( 48 | socket: root::s32, 49 | buffer: *const u8, 50 | bufferLength: u64, 51 | flags: root::s32, 52 | ) -> u64; 53 | } 54 | extern "C" { 55 | #[link_name = "\u{1}_ZN2nn6socket6SocketEiii"] 56 | pub fn Socket(domain: root::s32, type_: root::s32, proto: root::s32) -> root::s32; 57 | } 58 | extern "C" { 59 | #[link_name = "\u{1}_ZN2nn6socket9InetHtonsEt"] 60 | pub fn InetHtons(arg1: u16) -> u16; 61 | } 62 | extern "C" { 63 | #[link_name = "\u{1}_ZN2nn6socket8InetAtonEPKcPNS0_6InAddrE"] 64 | pub fn InetAton( 65 | str: *const u8, 66 | arg1: *mut root::nn::socket::InAddr, 67 | ) -> u32; 68 | } 69 | 70 | extern "C" { 71 | #[link_name = "\u{1}_ZN2nn6socket7ConnectEiPKNS0_8SockAddrEj"] 72 | pub fn Connect(socket: i32, sockaddrin: *const SockAddrIn, sockaddr_len: u32) -> i32; 73 | } 74 | 75 | extern "C" { 76 | #[link_name = "\u{1}_ZN2nn6socket12GetLastErrorEv"] 77 | pub fn GetLastError() -> u32; 78 | } 79 | 80 | extern "C" { 81 | #[link_name = "\u{1}_ZN2nn6socket4BindEiPK8sockaddrj"] 82 | pub fn Bind(socket: root::s32, addr: *const root::sockaddr, addrLen: u32) -> u32; 83 | } 84 | extern "C" { 85 | #[link_name = "\u{1}_ZN2nn6socket6ListenEii"] 86 | pub fn Listen(socket: root::s32, backlog: root::s32) -> u32; 87 | } 88 | extern "C" { 89 | #[link_name = "\u{1}_ZN2nn6socket6AcceptEiP8sockaddrPj"] 90 | pub fn Accept( 91 | socket: root::s32, 92 | addrOut: *mut root::sockaddr, 93 | addrLenOut: *mut u32, 94 | ) -> u32; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/nn/ssl.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | extern "C" { 5 | #[link_name = "\u{1}_ZN2nn3ssl10InitializeEv"] 6 | pub fn Initialize() -> root::Result; 7 | 8 | #[link_name = "\u{1}_ZN2nn3ssl8FinalizeEv"] 9 | pub fn Finalize() -> root::Result; 10 | } 11 | pub mod Context { 12 | 13 | pub enum CertificateFormat { 14 | PEM = 0x1, 15 | DER = 0x2, 16 | } 17 | 18 | #[repr(C)] 19 | pub enum SslVersion { 20 | Auto = 0x1, 21 | Tls10 = 0x8, 22 | Tls11 = 0x10, 23 | Tls12 = 0x20, 24 | } 25 | 26 | // Estimate through SDK binary usage of the fields 27 | #[repr(C)] 28 | #[derive(Clone, Copy)] 29 | pub struct Context { 30 | _x: u64, 31 | } 32 | 33 | impl Context { 34 | pub fn new() -> Self { 35 | Self { 36 | _x: 0, 37 | } 38 | } 39 | } 40 | 41 | extern "C" { 42 | #[link_name = "\u{1}_ZN2nn3ssl7ContextC1Ev"] 43 | pub fn Context(this: *mut Context); 44 | } 45 | extern "C" { 46 | #[link_name = "\u{1}_ZN2nn3ssl7Context6CreateENS1_10SslVersionE"] 47 | pub fn Create(this: *mut Context, version: SslVersion) -> i32; 48 | } 49 | extern "C" { 50 | #[link_name = "\u{1}_ZN2nn3ssl7Context15ImportClientPkiEPmPKcS4_jj"] 51 | pub fn ImportClientPki(this: *mut Context, out_store_id: &mut u64, p12_buf: *const u8, password_buf: *const u8, p12_buf_len: u32, password_buf_len: u32) -> i32; 52 | } 53 | extern "C" { 54 | #[link_name = "\u{1}_ZN2nn3ssl7Context15ImportServerPkiEPmPKcjNS0_17CertificateFormatE"] 55 | pub fn ImportServerPki( 56 | this: *mut Context, 57 | arg1: *mut u64, 58 | certData: *const u8, 59 | certSize: u32, 60 | certFormat: CertificateFormat, 61 | ) -> super::root::Result; 62 | } 63 | extern "C" { 64 | #[link_name = "\u{1}_ZN2nn3ssl7Context9ImportCrlEPmPKcj"] 65 | pub fn ImportCrl(this: *mut Context, out_store_id: &mut u64, crl_der_buf: *const u8, crl_der_buf_len: u32) -> i32; 66 | } 67 | extern "C" { 68 | #[link_name = "\u{1}_ZN2nn3ssl7Context7DestroyEv"] 69 | pub fn Destroy(this: *const Context) -> u32; 70 | } 71 | } 72 | mod Connection { 73 | // Estimate through SDK binary usage of the fields. Might be 0x28? 74 | #[repr(C)] 75 | #[derive(Clone, Copy)] 76 | pub struct Connection { 77 | _x: [u8;0x24], 78 | } 79 | 80 | impl Connection { 81 | pub fn new() -> Self { 82 | Self { 83 | _x: [0;0x24], 84 | } 85 | } 86 | } 87 | 88 | extern "C" { 89 | #[link_name = "\u{1}_ZN2nn3ssl10ConnectionC1Ev"] 90 | pub fn Connection(this: *mut Connection); 91 | } 92 | extern "C" { 93 | #[link_name = "\u{1}_ZN2nn3ssl10Connection6CreateEPNS0_7ContextE"] 94 | pub fn Create(this: *mut Connection, context: *const super::Context::Context) -> u32; 95 | } 96 | extern "C" { 97 | #[link_name = "\u{1}_ZN2nn3ssl10Connection19SetSocketDescriptorEi"] 98 | pub fn SetSocketDescriptor(this: *mut Connection, socket_desc: u32) -> u32; 99 | } 100 | extern "C" { 101 | #[link_name = "\u{1}_ZN2nn3ssl10Connection11SetHostNameEPKcj"] 102 | pub fn SetHostName(this: *mut Connection, host_name: *const u8, name_len: u32) -> i32; 103 | } 104 | extern "C" { 105 | #[link_name = "\u{1}_ZN2nn3ssl10Connection11DoHandshakeEv"] 106 | pub fn DoHandshake(this: *mut Connection) -> u32; 107 | } 108 | extern "C" { 109 | #[link_name = "\u{1}_ZN2nn3ssl10Connection4ReadEPcj"] 110 | pub fn Read(this: *const Connection, out_buf: *mut u8, buf_len: usize) -> i32; 111 | } 112 | extern "C" { 113 | #[link_name = "\u{1}_ZN2nn3ssl10Connection4ReadEPcPij"] 114 | pub fn Read1(this: *const Connection, out_buf: *mut u8, out_size_read: *mut i32, buf_len: usize) -> i32; 115 | } 116 | extern "C" { 117 | #[link_name = "\u{1}_ZN2nn3ssl10Connection5WriteEPKcj"] 118 | pub fn Write(this: *const Connection, buf: *const u8, buf_len: usize) -> i32; 119 | } 120 | extern "C" { 121 | #[link_name = "\u{1}_ZN2nn3ssl10Connection5WriteEPKcPij"] 122 | pub fn Write1(this: *const Connection, buf: *const u8, out_size_write: *mut i32, buf_len: usize) -> i32; 123 | } 124 | extern "C" { 125 | #[link_name = "\u{1}_ZN2nn3ssl10Connection7PendingEv"] 126 | pub fn Pending(this: *const Connection) -> usize; 127 | } 128 | extern "C" { 129 | #[link_name = "\u{1}_ZN2nn3ssl10Connection17FlushSessionCacheEv"] 130 | pub fn FlushSessionCache(this: *mut Connection) -> u32; 131 | } 132 | extern "C" { 133 | #[link_name = "\u{1}_ZN2nn3ssl10Connection9SetOptionENS1_10OptionTypeEb"] 134 | pub fn SetOption(this: *mut Connection, option: u32, enable: bool) -> u32; 135 | } 136 | extern "C" { 137 | #[link_name = "\u{1}_ZN2nn3ssl10Connection15SetVerifyOptionENS1_12VerifyOptionE"] 138 | pub fn SetVerifyOption(this: *mut Connection, options: u32) -> u32; 139 | } 140 | extern "C" { 141 | #[link_name = "\u{1}_ZN2nn3ssl10Connection12GetLastErrorEPNS_6ResultE"] 142 | pub fn GetLastError(this: *const Connection, out_result: *mut u32) -> u32; 143 | } 144 | extern "C" { 145 | #[link_name = "\u{1}_ZN2nn3ssl10Connection7DestroyEv"] 146 | pub fn Destroy(this: *const Connection) -> u32; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/nn/svc.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | #[repr(C)] 5 | pub struct Handle { 6 | pub handle: u32, 7 | } -------------------------------------------------------------------------------- /src/nn/swkbd.rs: -------------------------------------------------------------------------------- 1 | use alloc::{vec::Vec, boxed::Box, string::String}; 2 | use libc::c_void; 3 | use libc::free; 4 | 5 | #[repr(C)] 6 | pub struct KeyboardConfig { 7 | // inner: [u8; 0x4d0], 8 | unk1: [u8; 0x3ab], 9 | // 0x3ac 10 | max_text_length: u8, // Confirmed to be a u32 11 | // min_text_length follows immediately after, u32 12 | unk2: [u8; 0xd], 13 | // 0x3b9 14 | input_mode: u8, // Not sure, probably set by the presets already 15 | unk3: u32, 16 | // 0x3bd 17 | cancel_disabled: bool, 18 | unk4: [u8; 0x113], 19 | } 20 | 21 | impl KeyboardConfig { 22 | pub fn new() -> Self { 23 | Self { 24 | unk1: [0u8;0x3ab], 25 | max_text_length: 0, 26 | unk2: [0u8;0xd], 27 | input_mode: 0, 28 | unk3: 0, 29 | cancel_disabled: false, 30 | unk4: [0u8;0x113], 31 | } 32 | } 33 | 34 | /// Maximum is 500 characters, however we represent it as a u8 for now because more reverse engineering is needed to confirm the type. 35 | pub fn set_text_max_length(&mut self, max_length: u8) { 36 | self.max_text_length = if max_length == 0 { 37 | 1 38 | } else { 39 | max_length 40 | } 41 | } 42 | 43 | pub fn enable_cancel_button(&mut self, enable: bool) { 44 | self.cancel_disabled = !enable; 45 | } 46 | } 47 | 48 | impl Default for KeyboardConfig { 49 | fn default() -> Self { 50 | Self::new() 51 | } 52 | } 53 | 54 | #[repr(C)] 55 | pub struct ShowKeyboardArg { 56 | pub keyboard_config: [u8; 0x4D0], 57 | pub work_buffer: *mut c_void, 58 | pub work_buffer_size: usize, 59 | pub text_buffer: *const c_void, 60 | pub text_buffer_size: usize, 61 | pub custom_dictionary_buffer: *const c_void, 62 | pub custom_dictionary_buffer_size: usize, 63 | } 64 | 65 | #[repr(transparent)] 66 | pub struct SwkbdString(Box<[u16]>); 67 | 68 | impl SwkbdString { 69 | fn that_big_size() -> Self { 70 | let x: Box<[u16; 1002]> = unsafe { Box::new_zeroed().assume_init() }; 71 | SwkbdString(x) 72 | } 73 | } 74 | 75 | impl From for String { 76 | fn from(s: SwkbdString) -> String { 77 | let end = s.0.iter().position(|c| *c == 0).unwrap_or_else(|| s.0.len()); 78 | String::from_utf16_lossy(&s.0[..end]) 79 | } 80 | } 81 | 82 | impl ShowKeyboardArg { 83 | pub fn new() -> Box { 84 | let mut arg: Box = unsafe { Box::new_zeroed().assume_init() }; 85 | 86 | unsafe { 87 | make_preset_default(&mut arg.keyboard_config); 88 | } 89 | // max length 90 | arg.keyboard_config[0x3ac] = 20; 91 | // mode 92 | arg.keyboard_config[0x3b8] = 0; 93 | // cancel 94 | arg.keyboard_config[0x3bc] = 0; 95 | 96 | 97 | 98 | let work_buffer_size = 0xd000; 99 | let work_buffer: Box<[u8; 0xd000]> = unsafe { Box::new_zeroed().assume_init() }; 100 | let work_buffer = Box::leak(work_buffer) as *mut _ as *mut c_void; 101 | 102 | arg.work_buffer = work_buffer; 103 | arg.work_buffer_size = work_buffer_size; 104 | 105 | arg 106 | } 107 | 108 | pub fn header_text(&mut self, s: &str) -> &mut Self { 109 | let x: Vec = s.encode_utf16().chain(core::iter::once(0)).collect(); 110 | 111 | unsafe { 112 | set_header_text(&self.keyboard_config, x.as_ptr() as _); 113 | } 114 | 115 | core::mem::drop(x); 116 | 117 | self 118 | } 119 | 120 | pub fn show(&self) -> Option { 121 | let string = SwkbdString::that_big_size(); 122 | if unsafe { show_keyboard(&string, self) } == 0x29f { 123 | None 124 | } else { 125 | Some(string.into()) 126 | } 127 | } 128 | } 129 | 130 | 131 | 132 | impl Drop for ShowKeyboardArg { 133 | fn drop(&mut self) { 134 | if !self.work_buffer.is_null() { 135 | unsafe { 136 | free(self.work_buffer); 137 | } 138 | } 139 | } 140 | } 141 | 142 | /// The buffer can represent both a UTF8 and UTF16 C string depending on a bool set in KeyboardConfig. 143 | /// The is_utf8 bool is not yet defined in the structure as only the low-level API has been exposed so far. 144 | /// For now, assume the buffer always represents a UTF16 and convert accordingly. 145 | #[repr(C)] 146 | pub struct ShowKeyboardString { 147 | pub string_buffer: *const u8, 148 | pub buffer_len: usize, 149 | } 150 | 151 | impl ShowKeyboardString { 152 | pub fn new() -> Self { 153 | Self { 154 | string_buffer: 0 as _, 155 | buffer_len: 0, 156 | } 157 | } 158 | } 159 | 160 | impl Default for ShowKeyboardString { 161 | fn default() -> Self { 162 | Self::new() 163 | } 164 | } 165 | 166 | extern "C" { 167 | 168 | #[link_name = "_ZN2nn5swkbd25GetRequiredWorkBufferSizeEb"] 169 | pub fn get_required_work_buffer_size(use_dictionary: bool) -> usize; 170 | 171 | // #[link_name = "_ZN2nn5swkbd17MakePresetDefaultEPNS0_14KeyboardConfigE"] 172 | // pub fn make_preset_default(keyboard_config: *mut KeyboardConfig); 173 | 174 | #[link_name = "_ZN2nn5swkbd17MakePresetDefaultEPNS0_14KeyboardConfigE"] 175 | pub fn make_preset_default(x: *mut [u8; 0x4d0]); 176 | 177 | #[link_name = "_ZN2nn5swkbd18MakePresetPasswordEPNS0_14KeyboardConfigE"] 178 | pub fn make_preset_password(keyboard_config: *mut KeyboardConfig); 179 | 180 | #[link_name = "_ZN2nn5swkbd18MakePresetUserNameEPNS0_14KeyboardConfigE"] 181 | pub fn make_preset_user_name(keyboard_config: *mut KeyboardConfig); 182 | 183 | #[allow(improper_ctypes)] 184 | #[link_name = "_ZN2nn5swkbd12ShowKeyboardEPNS0_6StringERKNS0_15ShowKeyboardArgE"] 185 | fn show_keyboard(string: *const SwkbdString, arg: *const ShowKeyboardArg) -> u32; 186 | 187 | //#[link_name = "_ZN2nn5swkbd17SetHeaderTextUtf8EPNS0_14KeyboardConfigEPKc"] 188 | #[link_name = "_ZN2nn5swkbd13SetHeaderTextEPNS0_14KeyboardConfigEPKDs"] 189 | pub fn set_header_text(keyboard_config: *const [u8; 0x4d0], text: *const u16); 190 | 191 | #[link_name = "_ZN2nn5swkbd17SetHeaderTextUtf8EPNS0_14KeyboardConfigEPKc"] 192 | pub fn set_header_text_utf8(keyboard_config: *mut KeyboardConfig, text: *const u8); 193 | 194 | #[link_name = "_ZN2nn5swkbd16SetGuideTextUtf8EPNS0_14KeyboardConfigEPKc"] 195 | pub fn set_guide_text_utf8(keyboard_config: *mut KeyboardConfig, text: *const u8); 196 | 197 | #[link_name = "_ZN2nn5swkbd18SetInitialTextUtf8EPNS0_15ShowKeyboardArgEPKc"] 198 | pub fn set_initial_text_utf8(keyboard_config: *mut ShowKeyboardArg, text: *const u8); 199 | 200 | #[link_name = "_ZN2nn5swkbd28SetLeftOptionalSymbolKeyUtf8EPNS0_14KeyboardConfigEPKc"] 201 | pub fn set_left_optional_symbol_key_utf8(keyboard_config: *mut KeyboardConfig, text: *const u8); 202 | 203 | #[link_name = "_ZN2nn5swkbd13SetOkTextUtf8EPNS0_14KeyboardConfigEPKc"] 204 | pub fn set_ok_text_utf8(keyboard_config: *mut KeyboardConfig, text: *const u8); 205 | 206 | #[link_name = "_ZN2nn5swkbd14SetSubTextUtf8EPNS0_14KeyboardConfigEPKc"] 207 | pub fn set_sub_text_utf8(keyboard_config: *mut KeyboardConfig, text: *const u8); 208 | } -------------------------------------------------------------------------------- /src/nn/time.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | extern "C" { 4 | #[link_name = "\u{1}_ZN2nn4time10InitializeEv"] 5 | pub fn Initialize() -> root::Result; 6 | #[link_name = "\u{1}_ZN2nn4time8FinalizeEv"] 7 | pub fn Finalize() -> root::Result; 8 | #[link_name = "\u{1}_ZN2nn4time13IsInitializedEv"] 9 | pub fn IsInitialized() -> bool; 10 | } 11 | #[repr(C)] 12 | #[derive(Debug, Copy, Clone)] 13 | pub struct CalendarTime { 14 | pub year: root::s16, 15 | pub month: root::s8, 16 | pub day: root::s8, 17 | pub hour: root::s8, 18 | pub minute: root::s8, 19 | pub second: root::s8, 20 | } 21 | 22 | pub const DayOfTheWeek_Sunday: root::nn::time::DayOfTheWeek = 0; 23 | pub const DayOfTheWeek_Monday: root::nn::time::DayOfTheWeek = 1; 24 | pub const DayOfTheWeek_Tuesday: root::nn::time::DayOfTheWeek = 2; 25 | pub const DayOfTheWeek_Wednesday: root::nn::time::DayOfTheWeek = 3; 26 | pub const DayOfTheWeek_Thursday: root::nn::time::DayOfTheWeek = 4; 27 | pub const DayOfTheWeek_Friday: root::nn::time::DayOfTheWeek = 5; 28 | pub const DayOfTheWeek_Saturday: root::nn::time::DayOfTheWeek = 6; 29 | pub type DayOfTheWeek = u32; 30 | 31 | #[repr(C)] 32 | #[derive(Debug, Copy, Clone, Default)] 33 | pub struct TimeZone { 34 | pub standardTimeName: [u8; 8usize], 35 | pub _9: bool, 36 | pub utcOffset: root::s32, 37 | } 38 | 39 | #[repr(C)] 40 | #[derive(Debug, Copy, Clone)] 41 | pub struct CalendarAdditionalInfo { 42 | pub dayOfTheWeek: root::nn::time::DayOfTheWeek, 43 | pub dayofYear: root::s32, 44 | pub timeZone: root::nn::time::TimeZone, 45 | } 46 | 47 | #[repr(C)] 48 | #[derive(Debug, Default, Copy, Clone)] 49 | pub struct PosixTime { 50 | pub time: u64, 51 | } 52 | 53 | #[repr(C)] 54 | #[derive(Debug, Copy, Clone)] 55 | pub struct StandardUserSystemClock { 56 | pub _address: u8, 57 | } 58 | 59 | extern "C" { 60 | #[link_name = "\u{1}_ZN2nn4time23StandardUserSystemClock14GetCurrentTimeEPNS0_9PosixTimeE"] 61 | pub fn StandardUserSystemClock_GetCurrentTime( 62 | arg1: *mut root::nn::time::PosixTime, 63 | ) -> root::Result; 64 | } 65 | impl StandardUserSystemClock { 66 | #[inline] 67 | pub fn GetCurrentTime(arg1: *mut root::nn::time::PosixTime) -> root::Result { 68 | unsafe { StandardUserSystemClock_GetCurrentTime(arg1) } 69 | } 70 | } 71 | 72 | #[repr(C)] 73 | #[derive(Debug, Copy, Clone)] 74 | pub struct TimeZoneRule { 75 | _unused: [u8; 0], 76 | } 77 | extern "C" { 78 | #[link_name = "\u{1}_ZN2nn4time14ToCalendarTimeEPNS0_12CalendarTimeEPNS0_22CalendarAdditionalInfoERKNS0_9PosixTimeE"] 79 | pub fn ToCalendarTime( 80 | arg1: *mut root::nn::time::CalendarTime, 81 | arg2: *mut root::nn::time::CalendarAdditionalInfo, 82 | arg3: *const root::nn::time::PosixTime, 83 | ) -> root::Result; 84 | } 85 | 86 | pub fn get_calendar_time() -> CalendarTime { 87 | let mut do_init = false; 88 | unsafe { 89 | if !IsInitialized() { 90 | do_init = true; 91 | Initialize(); 92 | } 93 | } 94 | let mut calendar = CalendarTime { year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0 }; 95 | 96 | let mut calendar_info = CalendarAdditionalInfo { dayOfTheWeek: 0, dayofYear: 0, timeZone: TimeZone::default()}; 97 | 98 | let mut posix_time = PosixTime { time: 0 }; 99 | unsafe { StandardUserSystemClock_GetCurrentTime(&mut posix_time)}; 100 | 101 | unsafe { ToCalendarTime(&mut calendar, &mut calendar_info, &posix_time)}; 102 | 103 | if do_init { 104 | unsafe { Finalize(); } 105 | } 106 | 107 | return calendar; 108 | } 109 | -------------------------------------------------------------------------------- /src/nn/ui2d.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | 4 | use core::ops::{Deref, DerefMut}; 5 | 6 | use alloc::string::String; 7 | 8 | pub mod resources; 9 | pub use resources::*; 10 | 11 | #[repr(C)] 12 | #[derive(Debug)] 13 | pub struct ResAnimationContent { 14 | pub name: [libc::c_char; 28], 15 | pub count: u8, 16 | pub anim_content_type: u8, 17 | padding: [libc::c_char; 2], 18 | } 19 | 20 | /** 21 | * Block Header Kind 22 | * 23 | * ANIM_TAG: pat1 24 | * ANIM_SHARE: pah1 25 | * ANIM_INFO: pai1 26 | */ 27 | 28 | #[repr(C)] 29 | #[derive(Debug)] 30 | pub struct ResAnimationBlock { 31 | pub block_header_kind: u32, 32 | pub block_header_size: u32, 33 | pub num_frames: u16, 34 | pub is_loop: bool, 35 | pad: [libc::c_char; 1], 36 | pub file_count: u16, 37 | pub anim_cont_count: u16, 38 | pub anim_cont_offsets_offset: u32, 39 | } 40 | 41 | #[repr(C)] 42 | pub struct AnimTransform { 43 | pub res_animation_block: *mut ResAnimationBlock, 44 | pub frame: f32, 45 | pub enabled: bool, 46 | } 47 | 48 | #[repr(C)] 49 | #[derive(Debug)] 50 | pub struct AnimTransformNode { 51 | pub prev: *mut AnimTransformNode, 52 | pub next: *mut AnimTransformNode, 53 | } 54 | 55 | #[repr(C)] 56 | pub struct AnimTransformList { 57 | pub root: AnimTransformNode, 58 | } 59 | 60 | #[repr(C, align(8))] 61 | #[derive(Debug, Copy, Clone)] 62 | pub struct Pane { 63 | pub vtable: u64, 64 | pub link: PaneNode, 65 | pub parent: *mut Pane, 66 | pub children_list: PaneNode, 67 | pub pos_x: f32, 68 | pub pos_y: f32, 69 | pub pos_z: f32, 70 | pub rot_x: f32, 71 | pub rot_y: f32, 72 | pub rot_z: f32, 73 | pub scale_x: f32, 74 | pub scale_y: f32, 75 | pub size_x: f32, 76 | pub size_y: f32, 77 | pub flags: u8, 78 | pub alpha: u8, 79 | pub global_alpha: u8, 80 | pub base_position: u8, 81 | pub flag_ex: u8, 82 | // This is supposed to be 3 bytes padding + flags of 4 bytes + padding of 4 bytes 83 | pad: [u8; 3 + 4 + 4 + 8], 84 | pub global_matrix: [[f32; 3]; 4], 85 | pub user_matrix: *const u64, 86 | pub ext_user_data_list: *const u64, 87 | pub name: [libc::c_char; 25], 88 | pub user_data: [libc::c_char; 9], 89 | } 90 | 91 | #[repr(C)] 92 | #[derive(Debug, Copy, Clone)] 93 | pub enum PaneFlag { 94 | Visible, 95 | InfluencedAlpha, 96 | LocationAdjust, 97 | UserAllocated, 98 | IsGlobalMatrixDirty, 99 | UserMatrix, 100 | UserGlobalMatrix, 101 | IsConstantBufferReady, 102 | Max, 103 | } 104 | 105 | impl Pane { 106 | pub unsafe fn as_parts(&mut self) -> &mut Parts { 107 | &mut *(self as *mut Pane as *mut Parts) 108 | } 109 | 110 | pub unsafe fn as_picture(&mut self) -> &mut Picture { 111 | &mut *(self as *mut Pane as *mut Picture) 112 | } 113 | 114 | pub unsafe fn as_textbox(&mut self) -> &mut TextBox { 115 | &mut *(self as *mut Pane as *mut TextBox) 116 | } 117 | 118 | pub unsafe fn as_window(&mut self) -> &mut Window { 119 | &mut *(self as *mut Pane as *mut Window) 120 | } 121 | 122 | pub unsafe fn set_visible(&mut self, visible: bool) { 123 | match visible { 124 | true => self.flags |= 1 << PaneFlag::Visible as u8, 125 | false => self.flags &= !(1 << PaneFlag::Visible as u8), 126 | } 127 | } 128 | 129 | pub fn get_name(&self) -> String { 130 | self.name 131 | .iter() 132 | .take_while(|b| **b != 0) 133 | .map(|b| *b as char) 134 | .collect::() 135 | } 136 | } 137 | 138 | #[repr(C)] 139 | #[derive(Debug)] 140 | pub struct Parts { 141 | pub pane: Pane, 142 | // Some IntrusiveList 143 | pub link: PaneNode, 144 | pub layout: *mut Layout, 145 | } 146 | 147 | impl Deref for Parts { 148 | type Target = Pane; 149 | 150 | fn deref(&self) -> &Self::Target { 151 | &self.pane 152 | } 153 | } 154 | 155 | impl DerefMut for Parts { 156 | fn deref_mut(&mut self) -> &mut Self::Target { 157 | &mut self.pane 158 | } 159 | } 160 | 161 | #[repr(C)] 162 | #[derive(Debug, Copy, Clone)] 163 | pub struct Picture { 164 | pub pane: Pane, 165 | pub material: *mut Material, 166 | pub vertex_colors: [[u8; 4]; 4], 167 | pub shared_memory: *mut u8, 168 | } 169 | 170 | impl Deref for Picture { 171 | type Target = Pane; 172 | 173 | fn deref(&self) -> &Self::Target { 174 | &self.pane 175 | } 176 | } 177 | 178 | impl DerefMut for Picture { 179 | fn deref_mut(&mut self) -> &mut Self::Target { 180 | &mut self.pane 181 | } 182 | } 183 | 184 | #[repr(C)] 185 | #[derive(Debug, Copy, Clone)] 186 | pub enum TextBoxFlag { 187 | // TODO: Check if Horizontal is first or Vertical is 188 | TextAlignmentHorizontal, 189 | TextAlignmentVertical, 190 | IsPTDirty, 191 | ShadowEnabled, 192 | InvisibleBorderEnabled, 193 | DoubleDrawnBorderEnabled, 194 | WidthLimitEnabled, 195 | PerCharacterTransformEnabled, 196 | CenterCeilingEnabled, 197 | PerCharacterTransformSplitByCharWidth, 198 | PerCharacterTransformAutoShadowAlpha, 199 | DrawFromRightToLeft, 200 | PerCharacterTransformOriginToCenter, 201 | PerCharacterTransformFixSpace, 202 | LinefeedByCharacterHeightEnabled, 203 | PerCharacterTransformSplitByCharWidthInsertSpaceEnabled, 204 | } 205 | 206 | pub enum HorizontalPosition { 207 | Center, 208 | Left, 209 | Right, 210 | MaxHorizontalPosition, 211 | } 212 | 213 | pub enum VerticalPosition { 214 | Center, 215 | Top, 216 | Bottom, 217 | MaxVerticalPosition, 218 | } 219 | 220 | #[repr(C)] 221 | #[derive(Debug, Copy, Clone)] 222 | pub struct TextBox { 223 | pub pane: Pane, 224 | // Actually a union 225 | pub text_buf: *mut libc::c_char, 226 | pub p_text_id: *const libc::c_char, 227 | pub text_colors: [[u8; 4]; 2], 228 | pub p_font: *const libc::c_void, 229 | pub font_size_x: f32, 230 | pub font_size_y: f32, 231 | pub line_space: f32, 232 | pub char_space: f32, 233 | 234 | // Actually a union 235 | pub p_tag_processor: *const libc::c_char, 236 | 237 | pub text_buf_len: u16, 238 | pub text_len: u16, 239 | 240 | // Use TextBoxFlag 241 | pub bits: u16, 242 | pub text_position: u8, 243 | 244 | pub is_utf8: bool, 245 | 246 | pub italic_ratio: f32, 247 | 248 | pub shadow_offset: ResVec2, 249 | pub shadow_scale: ResVec2, 250 | pub shadow_color: [ResColor; 2], 251 | pub shadow_italic_ratio: f32, 252 | 253 | pub p_line_width_offset: *const libc::c_void, 254 | 255 | pub p_material: *mut Material, 256 | pub p_disp_string_buf: *const libc::c_void, 257 | 258 | pub p_per_character_transform: *const libc::c_void, 259 | } 260 | 261 | impl TextBox { 262 | pub fn set_color(&mut self, r: u8, g: u8, b: u8, a: u8) { 263 | let input_color = [r, g, b, a]; 264 | let mut dirty: bool = false; 265 | self.text_colors.iter_mut().for_each(|top_or_bottom_color| { 266 | if *top_or_bottom_color != input_color { 267 | dirty = true; 268 | } 269 | *top_or_bottom_color = input_color; 270 | }); 271 | 272 | if dirty { 273 | self.bits |= 1 << TextBoxFlag::IsPTDirty as u8; 274 | } 275 | } 276 | 277 | pub unsafe fn set_material_white_color(&mut self, r: f32, g: f32, b: f32, a: f32) { 278 | (*self.p_material).set_white_color(r, g, b, a); 279 | } 280 | 281 | pub unsafe fn set_material_black_color(&mut self, r: f32, g: f32, b: f32, a: f32) { 282 | (*self.p_material).set_black_color(r, g, b, a); 283 | } 284 | 285 | pub unsafe fn set_default_material_colors(&mut self) { 286 | self.set_material_white_color(255.0, 255.0, 255.0, 255.0); 287 | self.set_material_black_color(0.0, 0.0, 0.0, 255.0); 288 | } 289 | 290 | pub fn text_outline_enable(&mut self, enabled: bool) { 291 | match enabled { 292 | true => self.bits &= !(1 << TextBoxFlag::InvisibleBorderEnabled as u8), 293 | false => self.bits |= 1 << TextBoxFlag::InvisibleBorderEnabled as u8, 294 | } 295 | } 296 | 297 | pub fn text_shadow_enable(&mut self, enabled: bool) { 298 | match enabled { 299 | true => self.bits |= 1 << TextBoxFlag::ShadowEnabled as u8, 300 | false => self.bits &= !(1 << TextBoxFlag::ShadowEnabled as u8), 301 | } 302 | } 303 | 304 | pub fn set_text_shadow( 305 | &mut self, 306 | offset: ResVec2, 307 | scale: ResVec2, 308 | colors: [ResColor; 2], 309 | italic_ratio: f32, 310 | ) { 311 | self.shadow_offset = offset; 312 | self.shadow_scale = scale; 313 | self.shadow_color = colors; 314 | self.shadow_italic_ratio = italic_ratio; 315 | } 316 | 317 | pub fn set_text_alignment( 318 | &mut self, 319 | horizontal: HorizontalPosition, 320 | vertical: VerticalPosition, 321 | ) { 322 | self.text_position = 323 | horizontal as u8 * HorizontalPosition::MaxHorizontalPosition as u8 + vertical as u8; 324 | } 325 | } 326 | 327 | impl Deref for TextBox { 328 | type Target = Pane; 329 | 330 | fn deref(&self) -> &Self::Target { 331 | &self.pane 332 | } 333 | } 334 | 335 | impl DerefMut for TextBox { 336 | fn deref_mut(&mut self) -> &mut Self::Target { 337 | &mut self.pane 338 | } 339 | } 340 | 341 | #[repr(C)] 342 | pub union MaterialColor { 343 | pub byte_color: [[u8; 4]; 2], 344 | pub p_float_color: *mut *mut f32, 345 | } 346 | 347 | use core::fmt; 348 | impl fmt::Debug for MaterialColor { 349 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 350 | unsafe { 351 | f.debug_struct("MaterialColor") 352 | .field("byteColor", &self.byte_color) 353 | .field("pFloatColor", &self.p_float_color) 354 | .finish() 355 | } 356 | } 357 | } 358 | 359 | #[repr(C)] 360 | #[derive(Debug, PartialEq)] 361 | pub enum MaterialColorType { 362 | BlackColor, 363 | WhiteColor, 364 | } 365 | 366 | #[repr(C)] 367 | #[derive(Debug, PartialEq)] 368 | pub enum MaterialFlags { 369 | UserAllocated, 370 | TextureOnly, 371 | ThresholdingAlphaInterpolation, 372 | BlackColorFloat, 373 | WhiteColorFloat, 374 | DynamicAllocatedColorData, 375 | } 376 | 377 | #[repr(C)] 378 | #[derive(Debug)] 379 | pub struct Material { 380 | pub vtable: u64, 381 | pub m_colors: MaterialColor, 382 | // Actually a struct 383 | m_mem_cap: u32, 384 | // Actually a struct 385 | m_mem_count: u32, 386 | pub m_p_mem: *mut libc::c_void, 387 | pub m_p_shader_info: *const libc::c_void, 388 | pub m_p_name: *const libc::c_char, 389 | pub m_vertex_shader_constant_buffer_offset: u32, 390 | pub m_pixel_shader_constant_buffer_offset: u32, 391 | pub m_p_user_shader_constant_buffer_information: *const libc::c_void, 392 | pub m_p_blend_state: *const libc::c_void, 393 | pub m_packed_values: u8, 394 | pub m_flag: u8, 395 | pub m_shader_variation: u16, 396 | } 397 | 398 | impl Material { 399 | pub fn set_color_int(&mut self, idx: usize, r: u8, g: u8, b: u8, a: u8) { 400 | let input_color = [r, g, b, a]; 401 | unsafe { 402 | self.m_colors.byte_color[idx] = input_color; 403 | } 404 | } 405 | 406 | pub fn set_color_float(&mut self, idx: usize, r: f32, g: f32, b: f32, a: f32) { 407 | unsafe { 408 | *(*(self.m_colors.p_float_color.add(idx)).add(0)) = r; 409 | *(*(self.m_colors.p_float_color.add(idx)).add(1)) = g; 410 | *(*(self.m_colors.p_float_color.add(idx)).add(2)) = b; 411 | *(*(self.m_colors.p_float_color.add(idx)).add(3)) = a; 412 | } 413 | } 414 | 415 | pub fn set_color(&mut self, color_type: MaterialColorType, r: f32, g: f32, b: f32, a: f32) { 416 | let (is_float_flag, idx) = if color_type == MaterialColorType::BlackColor { 417 | (MaterialFlags::BlackColorFloat as u8, 0) 418 | } else { 419 | (MaterialFlags::WhiteColorFloat as u8, 1) 420 | }; 421 | if self.m_flag & (0x1 << is_float_flag) != 0 { 422 | self.set_color_float(idx, r, g, b, a); 423 | } else { 424 | self.set_color_int(idx, r as u8, g as u8, b as u8, a as u8); 425 | } 426 | } 427 | 428 | pub fn set_white_color(&mut self, r: f32, g: f32, b: f32, a: f32) { 429 | self.set_color(MaterialColorType::WhiteColor, r, g, b, a); 430 | } 431 | 432 | pub fn set_black_color(&mut self, r: f32, g: f32, b: f32, a: f32) { 433 | self.set_color(MaterialColorType::BlackColor, r, g, b, a); 434 | } 435 | 436 | pub fn set_white_res_color(&mut self, white: ResColor) { 437 | self.set_white_color( 438 | white.r as f32, 439 | white.g as f32, 440 | white.b as f32, 441 | white.a as f32, 442 | ); 443 | } 444 | 445 | pub fn set_black_res_color(&mut self, black: ResColor) { 446 | self.set_black_color( 447 | black.r as f32, 448 | black.g as f32, 449 | black.b as f32, 450 | black.a as f32, 451 | ); 452 | } 453 | } 454 | 455 | #[repr(C)] 456 | #[derive(Debug, Copy, Clone)] 457 | pub struct Window { 458 | pub pane: Pane, 459 | // TODO 460 | } 461 | 462 | impl Deref for Window { 463 | type Target = Pane; 464 | 465 | fn deref(&self) -> &Self::Target { 466 | &self.pane 467 | } 468 | } 469 | 470 | impl DerefMut for Window { 471 | fn deref_mut(&mut self) -> &mut Self::Target { 472 | &mut self.pane 473 | } 474 | } 475 | 476 | #[derive(Debug, Copy, Clone)] 477 | pub struct PaneNode { 478 | pub prev: *mut PaneNode, 479 | pub next: *mut PaneNode, 480 | } 481 | 482 | #[repr(C)] 483 | pub struct Group { 484 | pub pane_list: PaneNode, 485 | pub name: *const libc::c_char, 486 | } 487 | 488 | #[repr(C)] 489 | pub struct GroupContainer {} 490 | 491 | #[repr(C)] 492 | #[derive(Debug)] 493 | pub struct Layout { 494 | pub vtable: u64, 495 | pub anim_trans_list: AnimTransformNode, 496 | pub root_pane: *mut Pane, 497 | pub group_container: u64, 498 | pub layout_size: f64, 499 | pub layout_name: *const libc::c_char, 500 | } 501 | -------------------------------------------------------------------------------- /src/nn/ui2d/resources.rs: -------------------------------------------------------------------------------- 1 | use alloc::string::String; 2 | 3 | #[allow(unused_imports)] 4 | use self::super::root; 5 | 6 | use core::ops::{Deref, DerefMut}; 7 | 8 | #[repr(C)] 9 | #[derive(Debug, Copy, Clone)] 10 | pub struct ResVec2 { 11 | pub x: f32, 12 | pub y: f32, 13 | } 14 | 15 | impl ResVec2 { 16 | pub fn default() -> ResVec2 { 17 | ResVec2 { x: 0.0, y: 0.0 } 18 | } 19 | 20 | pub fn new(x: f32, y: f32) -> ResVec2 { 21 | ResVec2 { x, y } 22 | } 23 | } 24 | 25 | #[repr(C)] 26 | #[derive(Debug, Copy, Clone)] 27 | pub struct ResVec3 { 28 | pub x: f32, 29 | pub y: f32, 30 | pub z: f32, 31 | } 32 | 33 | impl ResVec3 { 34 | pub fn default() -> ResVec3 { 35 | ResVec3 { 36 | x: 0.0, 37 | y: 0.0, 38 | z: 0.0, 39 | } 40 | } 41 | 42 | pub fn new(x: f32, y: f32, z: f32) -> ResVec3 { 43 | ResVec3 { x, y, z } 44 | } 45 | } 46 | 47 | // Maybe needs a vtable. 48 | #[repr(C)] 49 | #[derive(Debug, Copy, Clone)] 50 | pub struct ResColor { 51 | pub r: u8, 52 | pub g: u8, 53 | pub b: u8, 54 | pub a: u8, 55 | } 56 | 57 | #[repr(C)] 58 | #[derive(Debug, Copy, Clone)] 59 | pub struct ResPane { 60 | pub block_header_kind: u32, 61 | pub block_header_size: u32, 62 | pub flag: u8, 63 | pub base_position: u8, 64 | pub alpha: u8, 65 | pub flag_ex: u8, 66 | pub name: [libc::c_char; 24], 67 | pub user_data: [libc::c_char; 8], 68 | pub pos: ResVec3, 69 | pub rot_x: f32, 70 | pub rot_y: f32, 71 | pub rot_z: f32, 72 | pub scale_x: f32, 73 | pub scale_y: f32, 74 | pub size_x: f32, 75 | pub size_y: f32, 76 | } 77 | 78 | impl ResPane { 79 | // For null pane 80 | pub fn new(name: &str) -> ResPane { 81 | let mut pane = ResPane { 82 | block_header_kind: u32::from_le_bytes([b'p', b'a', b'n', b'1']), 83 | block_header_size: 84, 84 | /// Visible | InfluencedAlpha 85 | flag: 0x3, 86 | base_position: 0, 87 | alpha: 0xFF, 88 | flag_ex: 0, 89 | name: [0; 24], 90 | user_data: [0; 8], 91 | pos: ResVec3 { 92 | x: 0.0, 93 | y: 0.0, 94 | z: 0.0, 95 | }, 96 | rot_x: 0.0, 97 | rot_y: 0.0, 98 | rot_z: 0.0, 99 | scale_x: 1.0, 100 | scale_y: 1.0, 101 | size_x: 30.0, 102 | size_y: 40.0, 103 | }; 104 | pane.set_name(name); 105 | pane 106 | } 107 | 108 | pub fn set_name(&mut self, name: &str) { 109 | assert!( 110 | name.len() <= 24, 111 | "Name of pane must be at most 24 characters" 112 | ); 113 | unsafe { 114 | core::ptr::copy_nonoverlapping(name.as_ptr(), self.name.as_mut_ptr(), name.len()); 115 | } 116 | } 117 | 118 | pub fn set_pos(&mut self, pos: ResVec3) { 119 | self.pos = pos; 120 | } 121 | 122 | pub fn set_size(&mut self, size: ResVec2) { 123 | self.size_x = size.x; 124 | self.size_y = size.y; 125 | } 126 | 127 | pub fn get_name(&self) -> String { 128 | self.name 129 | .iter() 130 | .take_while(|b| **b != 0) 131 | .map(|b| *b as char) 132 | .collect::() 133 | } 134 | 135 | pub fn name_matches(&self, other: &str) -> bool { 136 | self.get_name() == other 137 | } 138 | } 139 | 140 | #[repr(C)] 141 | #[derive(Debug, PartialEq)] 142 | enum TextBoxFlag { 143 | ShadowEnabled, 144 | ForceAssignTextLength, 145 | InvisibleBorderEnabled, 146 | DoubleDrawnBorderEnabled, 147 | PerCharacterTransformEnabled, 148 | CenterCeilingEnabled, 149 | LineWidthOffsetEnabled, 150 | ExtendedTagEnabled, 151 | PerCharacterTransformSplitByCharWidth, 152 | PerCharacterTransformAutoShadowAlpha, 153 | DrawFromRightToLeft, 154 | PerCharacterTransformOriginToCenter, 155 | KeepingFontScaleEnabled, 156 | PerCharacterTransformFixSpace, 157 | PerCharacterTransformSplitByCharWidthInsertSpaceEnabled, 158 | Max, 159 | } 160 | 161 | #[repr(C)] 162 | #[derive(Debug, Copy, Clone)] 163 | pub enum TextAlignment { 164 | Synchronous, 165 | Left, 166 | Center, 167 | Right, 168 | MaxTextAlignment, 169 | } 170 | 171 | #[repr(C)] 172 | #[derive(Debug, Copy, Clone)] 173 | pub struct ResTextBox { 174 | pub pane: ResPane, 175 | pub text_buf_bytes: u16, 176 | pub text_str_bytes: u16, 177 | pub material_idx: u16, 178 | pub font_idx: u16, 179 | pub text_position: u8, 180 | pub text_alignment: u8, 181 | pub text_box_flag: u16, 182 | pub italic_ratio: f32, 183 | pub text_str_offset: u32, 184 | pub text_cols: [ResColor; 2], 185 | pub font_size: ResVec2, 186 | pub char_space: f32, 187 | pub line_space: f32, 188 | pub text_id_offset: u32, 189 | pub shadow_offset: ResVec2, 190 | pub shadow_scale: ResVec2, 191 | pub shadow_cols: [ResColor; 2], 192 | pub shadow_italic_ratio: f32, 193 | pub line_width_offset_offset: u32, 194 | pub per_character_transform_offset: u32, 195 | /* Additional Info 196 | uint16_t text[]; // Text. 197 | char textId[]; // The text ID. 198 | u8 lineWidthOffsetCount; // The quantity of widths and offsets for each line. 199 | float lineOffset[]; // The offset for each line. 200 | float lineWidth[]; // The width of each line. 201 | ResPerCharacterTransform perCharacterTransform // Information for per-character animation. 202 | ResAnimationInfo perCharacterTransformAnimationInfo; // Animation information for per-character animation. 203 | */ 204 | } 205 | 206 | impl Deref for ResTextBox { 207 | type Target = ResPane; 208 | 209 | fn deref(&self) -> &Self::Target { 210 | &self.pane 211 | } 212 | } 213 | 214 | impl DerefMut for ResTextBox { 215 | fn deref_mut(&mut self) -> &mut Self::Target { 216 | &mut self.pane 217 | } 218 | } 219 | 220 | impl ResTextBox { 221 | pub fn enable_shadow(&mut self) { 222 | self.text_box_flag |= 0x1 << TextBoxFlag::ShadowEnabled as u8; 223 | } 224 | 225 | pub fn text_alignment(&mut self, align: TextAlignment) { 226 | self.text_alignment = align as u8; 227 | } 228 | } 229 | 230 | #[repr(C)] 231 | #[derive(Debug, Copy, Clone)] 232 | pub struct ResPicture { 233 | pub pane: ResPane, 234 | pub vtx_cols: [ResColor; 4], 235 | pub material_idx: u16, 236 | pub tex_coord_count: u8, 237 | pub flags: u8, 238 | /* Additional Info 239 | ResVec2 texCoords[texCoordCount][VERTEX_MAX]; 240 | uint32_t shapeBinaryIndex; 241 | */ 242 | } 243 | 244 | impl Deref for ResPicture { 245 | type Target = ResPane; 246 | 247 | fn deref(&self) -> &Self::Target { 248 | &self.pane 249 | } 250 | } 251 | 252 | impl DerefMut for ResPicture { 253 | fn deref_mut(&mut self) -> &mut Self::Target { 254 | &mut self.pane 255 | } 256 | } 257 | 258 | #[repr(C)] 259 | #[derive(Debug, Copy, Clone)] 260 | pub struct ResPictureWithTex { 261 | pub picture: ResPicture, 262 | pub tex_coords: [[ResVec2; TEX_COORD_COUNT]; 4], 263 | } 264 | 265 | impl Deref for ResPictureWithTex { 266 | type Target = ResPane; 267 | 268 | fn deref(&self) -> &Self::Target { 269 | &self.picture 270 | } 271 | } 272 | 273 | impl DerefMut for ResPictureWithTex { 274 | fn deref_mut(&mut self) -> &mut Self::Target { 275 | &mut self.picture 276 | } 277 | } 278 | 279 | #[repr(C)] 280 | #[derive(Debug, Copy, Clone)] 281 | pub struct ResParts { 282 | pub pane: ResPane, 283 | pub property_count: u32, 284 | pub magnify: ResVec2, 285 | } 286 | 287 | impl Deref for ResParts { 288 | type Target = ResPane; 289 | 290 | fn deref(&self) -> &Self::Target { 291 | &self.pane 292 | } 293 | } 294 | 295 | impl DerefMut for ResParts { 296 | fn deref_mut(&mut self) -> &mut Self::Target { 297 | &mut self.pane 298 | } 299 | } 300 | 301 | #[repr(C)] 302 | #[derive(Debug, Copy, Clone)] 303 | pub struct ResPartsProperty { 304 | pub name: [libc::c_char; 24], 305 | pub usage_flag: u8, 306 | pub basic_usage_flag: u8, 307 | pub material_usage_flag: u8, 308 | pub system_ext_user_data_override_flag: u8, 309 | pub property_offset: u32, 310 | pub ext_user_data_offset: u32, 311 | pub pane_basic_info_offset: u32, 312 | } 313 | 314 | #[repr(C)] 315 | #[derive(Debug, Copy, Clone)] 316 | pub struct ResPartsWithProperty { 317 | pub parts: ResParts, 318 | pub property_table: [ResPartsProperty; PROPERTY_COUNT], 319 | } 320 | 321 | #[repr(C)] 322 | #[derive(Debug, Copy, Clone)] 323 | pub struct ResWindowInflation { 324 | pub left: i16, 325 | pub right: i16, 326 | pub top: i16, 327 | pub bottom: i16, 328 | } 329 | 330 | #[repr(C)] 331 | #[derive(Debug, Copy, Clone)] 332 | pub struct ResWindowFrameSize { 333 | pub left: u16, 334 | pub right: u16, 335 | pub top: u16, 336 | pub bottom: u16, 337 | } 338 | 339 | #[repr(C)] 340 | #[derive(Debug, Copy, Clone)] 341 | pub struct ResWindowContent { 342 | pub vtx_cols: [ResColor; 4], 343 | pub material_idx: u16, 344 | pub tex_coord_count: u8, 345 | pub padding: [u8; 1], 346 | /* Additional Info 347 | nn::util::Float2 texCoords[texCoordCount][VERTEX_MAX]; 348 | */ 349 | } 350 | 351 | #[repr(C)] 352 | #[derive(Debug, Copy, Clone)] 353 | pub struct ResWindowContentWithTexCoords { 354 | pub window_content: ResWindowContent, 355 | // This has to be wrong. 356 | // Should be [[ResVec2; TEX_COORD_COUNT]; 4]? 357 | pub tex_coords: [[ResVec3; TEX_COORD_COUNT]; 1], 358 | } 359 | 360 | #[repr(C)] 361 | #[derive(Debug, Copy, Clone)] 362 | pub struct ResWindowFrame { 363 | pub material_idx: u16, 364 | pub texture_flip: u8, 365 | pub padding: [u8; 1], 366 | } 367 | 368 | #[repr(C)] 369 | #[derive(Debug, Copy, Clone)] 370 | pub struct ResWindow { 371 | pub pane: ResPane, 372 | pub inflation: ResWindowInflation, 373 | pub frame_size: ResWindowFrameSize, 374 | pub frame_count: u8, 375 | pub window_flags: u8, 376 | pub padding: [u8; 2], 377 | pub content_offset: u32, 378 | pub frame_offset_table_offset: u32, 379 | pub content: ResWindowContent, 380 | /* Additional Info 381 | 382 | ResWindowContent content; 383 | 384 | detail::uint32_t frameOffsetTable[frameCount]; 385 | ResWindowFrame frames; 386 | 387 | */ 388 | } 389 | 390 | impl Deref for ResWindow { 391 | type Target = ResPane; 392 | 393 | fn deref(&self) -> &Self::Target { 394 | &self.pane 395 | } 396 | } 397 | 398 | impl DerefMut for ResWindow { 399 | fn deref_mut(&mut self) -> &mut Self::Target { 400 | &mut self.pane 401 | } 402 | } 403 | 404 | #[repr(C)] 405 | #[derive(Debug, Copy, Clone)] 406 | pub struct ResWindowWithTexCoordsAndFrames { 407 | pub window: ResWindow, 408 | pub content: ResWindowContentWithTexCoords, 409 | pub frame_offset_table: [u32; FRAME_COUNT], 410 | pub frames: [ResWindowFrame; FRAME_COUNT], 411 | } 412 | 413 | impl Deref 414 | for ResWindowWithTexCoordsAndFrames 415 | { 416 | type Target = ResPane; 417 | 418 | fn deref(&self) -> &Self::Target { 419 | &self.window 420 | } 421 | } 422 | 423 | impl DerefMut 424 | for ResWindowWithTexCoordsAndFrames 425 | { 426 | fn deref_mut(&mut self) -> &mut Self::Target { 427 | &mut self.window 428 | } 429 | } 430 | -------------------------------------------------------------------------------- /src/nn/util.rs: -------------------------------------------------------------------------------- 1 | #[repr(simd)] 2 | pub struct Vector3f { 3 | pub value: [f32;3] 4 | } 5 | 6 | #[repr(simd)] 7 | pub struct Vector4f { 8 | pub value: [f32;4] 9 | } 10 | 11 | #[allow(unused_imports)] 12 | use self::super::root; 13 | 14 | #[repr(C)] 15 | pub struct Unorm8x4 { 16 | pub elements: [u8; 4usize], 17 | } 18 | 19 | #[repr(C)] 20 | pub struct Color4u8 { 21 | pub r: u8, 22 | pub g: u8, 23 | pub b: u8, 24 | pub a: u8, 25 | } 26 | 27 | pub const CharacterEncodingResult_Success: CharacterEncodingResult = 0; 28 | pub const CharacterEncodingResult_BadLength: CharacterEncodingResult = 29 | 1; 30 | pub const CharacterEncodingResult_InvalidFormat: 31 | CharacterEncodingResult = 2; 32 | pub type CharacterEncodingResult = u32; 33 | extern "C" { 34 | #[link_name = "\u{1}_ZN2nn4util30PickOutCharacterFromUtf8StringEPcPPKc"] 35 | pub fn PickOutCharacterFromUtf8String( 36 | arg1: *mut u8, 37 | str: *mut *const u8, 38 | ) -> CharacterEncodingResult; 39 | } 40 | extern "C" { 41 | #[link_name = "\u{1}_ZN2nn4util27ConvertCharacterUtf8ToUtf32EPjPKc"] 42 | pub fn ConvertCharacterUtf8ToUtf32( 43 | dest: *mut u32, 44 | src: *const u8, 45 | ) -> CharacterEncodingResult; 46 | } 47 | extern "C" { 48 | #[link_name = "\u{1}_ZN2nn4util30ConvertStringUtf16NativeToUtf8EPciPKti"] 49 | pub fn ConvertStringUtf16NativeToUtf8( 50 | arg1: *mut u8, 51 | arg2: root::s32, 52 | arg3: *const u16, 53 | arg4: root::s32, 54 | ) -> CharacterEncodingResult; 55 | } 56 | extern "C" { 57 | #[link_name = "\u{1}_ZN2nn4util30ConvertStringUtf8ToUtf16NativeEPtiPKci"] 58 | pub fn ConvertStringUtf8ToUtf16Native( 59 | arg1: *mut u16, 60 | arg2: root::s32, 61 | arg3: *const u8, 62 | arg4: root::s32, 63 | ) -> CharacterEncodingResult; 64 | } 65 | 66 | #[repr(C)] 67 | pub struct RelocationTable { 68 | pub mMagic: root::s32, 69 | pub mPosition: u32, 70 | pub mSectionCount: root::s32, 71 | } 72 | 73 | extern "C" { 74 | #[link_name = "\u{1}_ZN2nn4util15RelocationTable8RelocateEv"] 75 | pub fn RelocationTable_Relocate(this: *mut RelocationTable); 76 | } 77 | extern "C" { 78 | #[link_name = "\u{1}_ZN2nn4util15RelocationTable10UnrelocateEv"] 79 | pub fn RelocationTable_Unrelocate(this: *mut RelocationTable); 80 | } 81 | impl RelocationTable { 82 | #[inline] 83 | pub unsafe fn Relocate(&mut self) { 84 | RelocationTable_Relocate(self) 85 | } 86 | #[inline] 87 | pub unsafe fn Unrelocate(&mut self) { 88 | RelocationTable_Unrelocate(self) 89 | } 90 | } 91 | #[repr(C)] 92 | pub struct BinaryFileHeader { 93 | pub mMagic: root::s32, 94 | pub mSig: u32, 95 | pub mVerMicro: u8, 96 | pub mVerMinor: u8, 97 | pub mVerMajor: u16, 98 | pub mBOM: u16, 99 | pub mAlignment: u8, 100 | pub mTargetAddrSize: u8, 101 | pub mFileNameOffset: u32, 102 | pub mFlag: u16, 103 | pub mFirstBlockOffs: u16, 104 | pub mRelocationTableOffs: u32, 105 | pub mSize: u32, 106 | } 107 | 108 | extern "C" { 109 | #[link_name = "\u{1}_ZNK2nn4util16BinaryFileHeader7IsValidEliii"] 110 | pub fn BinaryFileHeader_IsValid( 111 | this: *const BinaryFileHeader, 112 | packedSig: root::s64, 113 | majorVer: root::s32, 114 | minorVer: root::s32, 115 | microVer: root::s32, 116 | ) -> bool; 117 | } 118 | extern "C" { 119 | #[link_name = "\u{1}_ZNK2nn4util16BinaryFileHeader11IsRelocatedEv"] 120 | pub fn BinaryFileHeader_IsRelocated( 121 | this: *const BinaryFileHeader, 122 | ) -> bool; 123 | } 124 | extern "C" { 125 | #[link_name = "\u{1}_ZNK2nn4util16BinaryFileHeader15IsEndianReverseEv"] 126 | pub fn BinaryFileHeader_IsEndianReverse( 127 | this: *const BinaryFileHeader, 128 | ) -> bool; 129 | } 130 | extern "C" { 131 | #[link_name = "\u{1}_ZN2nn4util16BinaryFileHeader18GetRelocationTableEv"] 132 | pub fn BinaryFileHeader_GetRelocationTable( 133 | this: *mut BinaryFileHeader, 134 | ) -> *mut RelocationTable; 135 | } 136 | 137 | impl BinaryFileHeader { 138 | #[inline] 139 | pub unsafe fn IsValid( 140 | &self, 141 | packedSig: root::s64, 142 | majorVer: root::s32, 143 | minorVer: root::s32, 144 | microVer: root::s32, 145 | ) -> bool { 146 | BinaryFileHeader_IsValid(self, packedSig, majorVer, minorVer, microVer) 147 | } 148 | #[inline] 149 | pub unsafe fn IsRelocated(&self) -> bool { 150 | BinaryFileHeader_IsRelocated(self) 151 | } 152 | #[inline] 153 | pub unsafe fn IsEndianReverse(&self) -> bool { 154 | BinaryFileHeader_IsEndianReverse(self) 155 | } 156 | #[inline] 157 | pub unsafe fn GetRelocationTable( 158 | &mut self, 159 | ) -> *mut RelocationTable { 160 | BinaryFileHeader_GetRelocationTable(self) 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/nn/vi.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | #[derive(Debug, Copy, Clone)] 5 | pub struct Display { 6 | _unused: [u8; 0], 7 | } 8 | #[repr(C)] 9 | #[derive(Debug, Copy, Clone)] 10 | pub struct Layer { 11 | _unused: [u8; 0], 12 | } 13 | pub const ScalingMode_None: root::nn::vi::ScalingMode = 0; 14 | pub const ScalingMode_Exact: root::nn::vi::ScalingMode = 1; 15 | pub const ScalingMode_FitLayer: root::nn::vi::ScalingMode = 2; 16 | pub const ScalingMode_ScaleAndCrop: root::nn::vi::ScalingMode = 3; 17 | pub const ScalingMode_PreserveAspectRatio: root::nn::vi::ScalingMode = 4; 18 | pub type ScalingMode = u32; 19 | extern "C" { 20 | #[link_name = "\u{1}_ZN2nn2vi10InitializeEv"] 21 | pub fn Initialize(); 22 | } 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn2vi18OpenDefaultDisplayEPPNS0_7DisplayE"] 25 | pub fn OpenDefaultDisplay( 26 | out_Disp: *mut *mut root::nn::vi::Display, 27 | ) -> root::Result; 28 | } 29 | extern "C" { 30 | #[link_name = "\u{1}_ZN2nn2vi11CreateLayerEPNS0_5LayerEPNS0_7DisplayE"] 31 | pub fn CreateLayer( 32 | out_Layer: *mut root::nn::vi::Layer, 33 | disp: *mut root::nn::vi::Display, 34 | ) -> root::Result; 35 | } 36 | extern "C" { 37 | #[link_name = "\u{1}_ZN2nn2vi19SetLayerScalingModeEPNS0_5LayerENS0_11ScalingModeE"] 38 | pub fn SetLayerScalingMode( 39 | layer: *mut root::nn::vi::Layer, 40 | scalingMode: root::nn::vi::ScalingMode, 41 | ) -> root::Result; 42 | } 43 | extern "C" { 44 | #[link_name = "\u{1}_ZN2nn2vi20GetDisplayVsyncEventEPNS_2os15SystemEventTypeEPNS0_7DisplayE"] 45 | pub fn GetDisplayVsyncEvent( 46 | arg1: *mut root::nn::os::SystemEventType, 47 | arg2: *mut root::nn::vi::Display, 48 | ) -> root::Result; 49 | } 50 | extern "C" { 51 | #[link_name = "\u{1}_ZN2nn2vi15GetNativeWindowEPPvPNS0_5LayerE"] 52 | pub fn GetNativeWindow( 53 | window: *mut *mut u8, 54 | arg1: *mut root::nn::vi::Layer, 55 | ) -> root::Result; 56 | } -------------------------------------------------------------------------------- /src/nn/web.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | pub mod offlinewebsession; 4 | 5 | #[repr(C)] 6 | pub struct ShowOfflineHtmlPageArg { 7 | data: [u8; 0x2000], 8 | } 9 | #[repr(C)] 10 | #[derive(Copy, Clone, Debug, PartialEq)] 11 | pub enum OfflineBootDisplayKind { 12 | Default, 13 | White, 14 | Black, 15 | Screenshot, 16 | BlurredScreenshot, 17 | } 18 | #[repr(C)] 19 | #[derive(Copy, Clone, Debug, PartialEq)] 20 | pub enum OfflineBackgroundKind { 21 | Default, 22 | Screenshot, 23 | BlurredScreenshot, 24 | } 25 | #[repr(C)] 26 | #[derive(Copy, Clone, Debug, PartialEq)] 27 | pub enum WebSessionBootMode { 28 | Default, 29 | InitiallyHidden, 30 | } 31 | extern "C" { 32 | #[link_name = "\u{1}_ZN2nn3web19ShowOfflineHtmlPageEPNS0_26OfflineHtmlPageReturnValueERKNS0_22ShowOfflineHtmlPageArgE"] 33 | pub fn ShowOfflineHtmlPage( 34 | return_value: *mut OfflineHtmlPageReturnValue, 35 | arg: *const ShowOfflineHtmlPageArg, 36 | ) -> u32; 37 | } 38 | extern "C" { 39 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArgC2EPKc"] 40 | pub fn ShowOfflineHtmlPageArg( 41 | this: *mut ShowOfflineHtmlPageArg, 42 | page_path: *const u8, 43 | ); 44 | } 45 | extern "C" { 46 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg21SetJsExtensionEnabledEb"] 47 | pub fn SetOfflineJsExtensionEnabled( 48 | this: *mut ShowOfflineHtmlPageArg, 49 | enabled: bool, 50 | ); 51 | } 52 | extern "C" { 53 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg16SetFooterEnabledEb"] 54 | pub fn SetOfflineFooterEnabled(this: *mut ShowOfflineHtmlPageArg, enabled: bool); 55 | } 56 | extern "C" { 57 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg17SetPointerEnabledEb"] 58 | pub fn SetOfflinePointerEnabled(this: *mut ShowOfflineHtmlPageArg, enabled: bool); 59 | } 60 | extern "C" { 61 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg25SetBootLoadingIconEnabledEb"] 62 | pub fn SetOfflineBootLoadingIconEnabled( 63 | this: *mut ShowOfflineHtmlPageArg, 64 | enabled: bool, 65 | ); 66 | } 67 | extern "C" { 68 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg18SetWebAudioEnabledEb"] 69 | pub fn SetOfflineWebAudioEnabled(this: *mut ShowOfflineHtmlPageArg, enabled: bool); 70 | } 71 | extern "C" { 72 | /// On a scale of 0.0 to 4.0 73 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg22OverrideWebAudioVolumeEf"] 74 | pub fn OverrideOfflineWebAudioVolume( 75 | this: *mut ShowOfflineHtmlPageArg, 76 | volume: f32, 77 | ); 78 | } 79 | extern "C" { 80 | /// On a scale of 0.0 to 4.0 81 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg24OverrideMediaAudioVolumeEf"] 82 | pub fn OverrideOfflineMediaAudioVolume( 83 | this: *mut ShowOfflineHtmlPageArg, 84 | volume: f32, 85 | ); 86 | } 87 | extern "C" { 88 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg20SetBootAsMediaPlayerEb"] 89 | pub fn SetOfflineBootAsMediaPlayer( 90 | this: *mut ShowOfflineHtmlPageArg, 91 | enabled: bool, 92 | ); 93 | } 94 | extern "C" { 95 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg18SetPageFadeEnabledEb"] 96 | pub fn SetOfflinePageFadeEnabled(this: *mut ShowOfflineHtmlPageArg, enabled: bool); 97 | } 98 | extern "C" { 99 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg19SetPageCacheEnabledEb"] 100 | pub fn SetOfflinePageCacheEnabled(this: *mut ShowOfflineHtmlPageArg, enabled: bool); 101 | } 102 | extern "C" { 103 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg18SetBootDisplayKindENS0_22OfflineBootDisplayKindE"] 104 | pub fn SetOfflineBootDisplayKind( 105 | this: *mut ShowOfflineHtmlPageArg, 106 | boot_display_kind: OfflineBootDisplayKind, 107 | ); 108 | } 109 | extern "C" { 110 | #[link_name = "\u{1}_ZN2nn3web22ShowOfflineHtmlPageArg17SetBackgroundKindERKNS0_21OfflineBackgroundKindE"] 111 | pub fn SetOfflineBackgroundKind( 112 | this: *mut ShowOfflineHtmlPageArg, 113 | background_kind: *const OfflineBackgroundKind, 114 | ); 115 | } 116 | extern "C" { 117 | #[link_name = "\u{1}_ZN2nn3web11SetBootModeEPNS0_22ShowOfflineHtmlPageArgENS0_18WebSessionBootModeE"] 118 | pub fn SetBootMode(webpage_arg: &ShowOfflineHtmlPageArg, mode: WebSessionBootMode); 119 | } 120 | impl ShowOfflineHtmlPageArg { 121 | #[cfg(not(feature = "rustc-dep-of-std"))] 122 | #[inline] 123 | pub fn new>(page_path: T) -> Result { 124 | let mut path_bytes = page_path.as_ref().to_vec(); 125 | 126 | if path_bytes.len() > 3072 { 127 | path_bytes.truncate(3071); 128 | } 129 | 130 | path_bytes.append(&mut "\0".as_bytes().to_vec()); 131 | 132 | unsafe { 133 | let mut instance = ShowOfflineHtmlPageArg { data: [0; 0x2000] }; 134 | ShowOfflineHtmlPageArg(&mut instance, path_bytes.as_ptr()); 135 | Ok(instance) 136 | } 137 | } 138 | 139 | pub fn set_background_kind(&mut self, kind: OfflineBackgroundKind) { 140 | unsafe { SetOfflineBackgroundKind(self, &kind) } 141 | } 142 | 143 | pub fn set_boot_display_kind(&mut self, kind: OfflineBootDisplayKind) { 144 | unsafe { SetOfflineBootDisplayKind(self, kind) } 145 | } 146 | 147 | pub fn display_footer(&mut self, enabled: bool) { 148 | unsafe { SetOfflineFooterEnabled(self, enabled) } 149 | } 150 | 151 | pub fn enable_javascript(&mut self, enabled: bool) { 152 | unsafe { SetOfflineJsExtensionEnabled(self, enabled) } 153 | } 154 | 155 | pub fn enable_pointer(&mut self, enabled: bool) { 156 | unsafe { SetOfflinePointerEnabled(self, enabled) } 157 | } 158 | 159 | pub fn enable_boot_loading_icon(&mut self, enabled: bool) { 160 | unsafe { SetOfflineBootLoadingIconEnabled(self, enabled) } 161 | } 162 | 163 | pub fn enable_web_audio(&mut self, enabled: bool) { 164 | unsafe { SetOfflineWebAudioEnabled(self, enabled) } 165 | } 166 | 167 | pub fn set_boot_mode(&mut self, mode: WebSessionBootMode) { 168 | unsafe { SetBootMode(self, mode) } 169 | } 170 | } 171 | #[repr(C)] 172 | pub struct OfflineHtmlPageReturnValue { 173 | exit_reason: u64, 174 | last_url: [u8; 4096], 175 | last_url_size: u64, 176 | } 177 | #[repr(C)] 178 | #[derive(Copy, Clone, Debug, PartialEq)] 179 | pub enum OfflineExitReason { 180 | ExitPressed = 0, 181 | BackPressed = 1, 182 | Requested = 2, 183 | LastUrl = 3, 184 | ErrorDialog = 7, 185 | Unexpected = 20, 186 | } 187 | extern "C" { 188 | #[link_name = "\u{1}_ZN2nn3web26OfflineHtmlPageReturnValueC1Ev"] 189 | pub fn OfflineHtmlPageReturnValue(this: *mut OfflineHtmlPageReturnValue); 190 | } 191 | extern "C" { 192 | #[link_name = "\u{1}_ZNK2nn3web26OfflineHtmlPageReturnValue20GetOfflineExitReasonEv"] 193 | pub fn GetOfflineExitReason( 194 | this: *const OfflineHtmlPageReturnValue, 195 | ) -> OfflineExitReason; 196 | } 197 | extern "C" { 198 | #[link_name = "\u{1}_ZNK2nn3web26OfflineHtmlPageReturnValue10GetLastUrlEv"] 199 | pub fn GetLastUrl(this: *const OfflineHtmlPageReturnValue) -> *const u8; 200 | } 201 | extern "C" { 202 | #[link_name = "\u{1}_ZNK2nn3web26OfflineHtmlPageReturnValue14GetLastUrlSizeEv"] 203 | pub fn GetLastUrlSize(this: *const OfflineHtmlPageReturnValue) -> usize; 204 | } 205 | impl OfflineHtmlPageReturnValue { 206 | pub fn new() -> Self { 207 | let mut instance = OfflineHtmlPageReturnValue { 208 | exit_reason: 0, 209 | last_url: [0; 4096], 210 | last_url_size: 0, 211 | }; 212 | 213 | unsafe { 214 | OfflineHtmlPageReturnValue(&mut instance); 215 | } 216 | 217 | instance 218 | } 219 | 220 | pub fn get_exit_reason(&self) -> OfflineExitReason { 221 | unsafe { GetOfflineExitReason(self) } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /src/nn/web/offlinewebsession.rs: -------------------------------------------------------------------------------- 1 | use self::super::root; 2 | use self::super::{OfflineHtmlPageReturnValue, ShowOfflineHtmlPageArg}; 3 | #[repr(C)] 4 | #[derive(Debug)] 5 | pub struct OfflineWebSession { 6 | pub inner_web_impl: *const u8, 7 | } 8 | impl OfflineWebSession { 9 | pub fn new() -> Self { 10 | let web_impl_size = unsafe { GetWorkBufferSize() }; 11 | let inner_web_impl = 12 | alloc::vec![0u8; web_impl_size].leak().as_ptr() as *const u8; 13 | 14 | let session = Self { inner_web_impl }; 15 | 16 | unsafe { 17 | Initialize(&session, inner_web_impl); 18 | } 19 | 20 | session 21 | } 22 | } 23 | extern "C" { 24 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession17GetWorkBufferSizeEv"] 25 | pub fn GetWorkBufferSize() -> usize; 26 | } 27 | extern "C" { 28 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession10InitializeEPvm"] 29 | pub fn Initialize( 30 | session: *const OfflineWebSession, 31 | offline_web_impl: *const u8, 32 | ); 33 | } 34 | extern "C" { 35 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession5StartEPPNS_2os15SystemEventTypeERKNS0_22ShowOfflineHtmlPageArgE"] 36 | pub fn Start( 37 | session: &OfflineWebSession, 38 | system_evt: &&root::nn::os::SystemEventType, 39 | webpage_arg: &ShowOfflineHtmlPageArg, 40 | ); 41 | } 42 | extern "C" { 43 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession6AppearEv"] 44 | pub fn Appear(session: &OfflineWebSession) -> bool; 45 | } 46 | extern "C" { 47 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession21TrySendContentMessageEPKcm"] 48 | pub fn TrySendContentMessage( 49 | session: &OfflineWebSession, 50 | buffer: *const u8, 51 | buf_len: usize, 52 | ) -> bool; 53 | } 54 | extern "C" { 55 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession24TryReceiveContentMessageEPmPcm"] 56 | pub fn TryReceiveContentMessage( 57 | session: &OfflineWebSession, 58 | out_size: *mut usize, 59 | buffer: *const u8, 60 | buf_len: usize, 61 | ) -> bool; 62 | } 63 | extern "C" { 64 | #[link_name = "\u{1}_ZN2nn3web17OfflineWebSession11WaitForExitEPNS0_26OfflineHtmlPageReturnValueE"] 65 | pub fn WaitForExit( 66 | session: &OfflineWebSession, 67 | return_val: &OfflineHtmlPageReturnValue, 68 | ) -> root::Result; 69 | } -------------------------------------------------------------------------------- /src/rtld.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use self::super::root; 3 | #[repr(C)] 4 | #[derive(Copy, Clone)] 5 | pub struct ModuleObject { 6 | pub next: *mut ModuleObject, 7 | pub prev: *mut ModuleObject, 8 | pub rela_or_rel_plt: ModuleObject__bindgen_ty_1, 9 | pub rela_or_rel: ModuleObject__bindgen_ty_2, 10 | pub module_base: u64, 11 | pub dynamic: *mut root::Elf64_Dyn, 12 | pub is_rela: bool, 13 | pub rela_or_rel_plt_size: u64, 14 | pub dt_init: ::core::option::Option, 15 | pub dt_fini: ::core::option::Option, 16 | pub hash_bucket: *mut u32, 17 | pub hash_chain: *mut u32, 18 | pub dynstr: *mut u8, 19 | pub dynsym: *mut root::Elf64_Sym, 20 | pub dynstr_size: u64, 21 | pub got: *mut *mut u8, 22 | pub rela_dyn_size: u64, 23 | pub rel_dyn_size: u64, 24 | pub rel_count: u64, 25 | pub rela_count: u64, 26 | pub hash_nchain_value: u64, 27 | pub hash_nbucket_value: u64, 28 | pub got_stub_ptr: u64, 29 | } 30 | #[repr(C)] 31 | #[derive(Copy, Clone)] 32 | pub union ModuleObject__bindgen_ty_1 { 33 | pub rel: *mut root::Elf64_Rel, 34 | pub rela: *mut root::Elf64_Rela, 35 | pub raw: *mut u8, 36 | _bindgen_union_align: u64, 37 | } 38 | #[repr(C)] 39 | #[derive(Copy, Clone)] 40 | pub union ModuleObject__bindgen_ty_2 { 41 | pub rel: *mut root::Elf64_Rel, 42 | pub rela: *mut root::Elf64_Rela, 43 | _bindgen_union_align: u64, 44 | } 45 | extern "C" { 46 | #[link_name = "\u{1}_ZN4rtld12ModuleObject10InitializeEmP9Elf64_Dyn"] 47 | pub fn ModuleObject_Initialize( 48 | this: *mut ModuleObject, 49 | aslr_base: u64, 50 | dynamic: *mut root::Elf64_Dyn, 51 | ); 52 | } 53 | extern "C" { 54 | #[link_name = "\u{1}_ZN4rtld12ModuleObject8RelocateEv"] 55 | pub fn ModuleObject_Relocate(this: *mut ModuleObject); 56 | } 57 | extern "C" { 58 | #[link_name = "\u{1}_ZN4rtld12ModuleObject15GetSymbolByNameEPKc"] 59 | pub fn ModuleObject_GetSymbolByName( 60 | this: *mut ModuleObject, 61 | name: *const u8, 62 | ) -> *mut root::Elf64_Sym; 63 | } 64 | extern "C" { 65 | #[link_name = "\u{1}_ZN4rtld12ModuleObject14ResolveSymbolsEb"] 66 | pub fn ModuleObject_ResolveSymbols( 67 | this: *mut ModuleObject, 68 | do_lazy_got_init: bool, 69 | ); 70 | } 71 | extern "C" { 72 | #[link_name = "\u{1}_ZN4rtld12ModuleObject16TryResolveSymbolEPmP9Elf64_Sym"] 73 | pub fn ModuleObject_TryResolveSymbol( 74 | this: *mut ModuleObject, 75 | target_symbol_address: *mut root::Elf64_Addr, 76 | symbol: *mut root::Elf64_Sym, 77 | ) -> bool; 78 | } 79 | impl ModuleObject { 80 | #[inline] 81 | pub unsafe fn Initialize(&mut self, aslr_base: u64, dynamic: *mut root::Elf64_Dyn) { 82 | ModuleObject_Initialize(self, aslr_base, dynamic) 83 | } 84 | #[inline] 85 | pub unsafe fn Relocate(&mut self) { 86 | ModuleObject_Relocate(self) 87 | } 88 | #[inline] 89 | pub unsafe fn GetSymbolByName( 90 | &mut self, 91 | name: *const u8, 92 | ) -> *mut root::Elf64_Sym { 93 | ModuleObject_GetSymbolByName(self, name) 94 | } 95 | #[inline] 96 | pub unsafe fn ResolveSymbols(&mut self, do_lazy_got_init: bool) { 97 | ModuleObject_ResolveSymbols(self, do_lazy_got_init) 98 | } 99 | #[inline] 100 | pub unsafe fn TryResolveSymbol( 101 | &mut self, 102 | target_symbol_address: *mut root::Elf64_Addr, 103 | symbol: *mut root::Elf64_Sym, 104 | ) -> bool { 105 | ModuleObject_TryResolveSymbol(self, target_symbol_address, symbol) 106 | } 107 | } --------------------------------------------------------------------------------