Skip to main content

nnsdk/nn/
account.rs

1use alloc::{vec::Vec,vec, string::String};
2
3#[allow(unused_imports)]
4use self::super::root;
5
6pub mod detail;
7//pub type Nickname = [u8; 33usize];
8#[repr(transparent)]
9pub struct Nickname(pub [u8; 33usize]);
10
11impl Nickname {
12    pub fn new() -> Self {
13        Self([0; 33])
14    }
15}
16
17#[cfg(not(feature = "rustc-dep-of-std"))]
18impl 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
31pub type NetworkServiceAccountId = u64;
32
33#[repr(C)]
34#[derive(Debug, Copy, Clone)]
35pub struct Uid {
36    pub id: [u64; 2usize],
37}
38
39impl Uid {
40    pub fn new() -> Self {
41        Self { id: [0, 0] }
42    }
43}
44
45#[repr(C)]
46#[derive(Debug, Clone)]
47pub struct UserHandle {
48    pub id: [u64; 3usize],
49}
50
51impl UserHandle {
52    pub fn new() -> Self {
53        Self { id: [0u64; 3] }
54    }
55}
56
57extern "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
137pub fn initialize() {
138    unsafe { Initialize() };
139}
140
141pub fn finalize() {
142    unsafe { Finalize() };
143}
144
145pub fn show_user_creator() {
146    unsafe { ShowUserCreator() };
147}
148
149pub fn list_all_users() -> Vec<Uid> {
150    let num_users = get_user_count();
151
152    let mut out_len = 0;
153    let mut out_uids: Vec<Uid> = 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
162pub fn get_user_count() -> i32 {
163    let mut count = 0;
164
165    unsafe {
166        GetUserCount(&mut count);
167    }
168
169    return count
170}
171
172pub 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
181pub fn open_preselected_user() -> UserHandle {
182    let mut handle = UserHandle::new();
183    unsafe {
184        OpenPreselectedUser(&mut handle);
185    }
186    return handle;
187}
188
189pub fn try_open_preselected_user() -> Option<UserHandle> {
190    let mut handle = UserHandle::new();
191
192    unsafe {
193        TryOpenPreselectedUser(&mut handle).then(|| handle)
194    }
195}
196
197pub fn get_user_id(user_handle: &UserHandle) -> Result<Uid, root::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
211pub 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
221pub fn close_user(user_handle: UserHandle) {
222    unsafe { CloseUser(&user_handle) }
223}
224
225pub fn ensure_network_service_account_available(handle: &UserHandle) {
226    unsafe {
227        EnsureNetworkServiceAccountAvailable(handle);
228    }
229}
230
231pub fn ensure_network_service_account_id_token_cache_async(context: &mut AsyncContext, handle: &UserHandle) {
232    unsafe {
233        EnsureNetworkServiceAccountIdTokenCacheAsync(context, handle);
234    }
235}
236
237pub 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
247pub 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)]
261pub struct AsyncContext {
262    pub _address: u8,
263}
264
265extern "C" {
266    #[link_name = "\u{1}_ZN2nn7account12AsyncContext7HasDoneEPb"]
267    pub fn AsyncContext_HasDone(
268        this: *mut AsyncContext,
269        arg1: *mut bool,
270    ) -> root::Result;
271}
272extern "C" {
273    #[link_name = "\u{1}_ZN2nn7account12AsyncContext9GetResultEv"]
274    pub fn AsyncContext_GetResult(
275        this: *mut AsyncContext,
276    ) -> root::Result;
277}
278extern "C" {
279    #[link_name = "\u{1}_ZN2nn7account12AsyncContext6CancelEv"]
280    pub fn AsyncContext_Cancel(
281        this: *mut AsyncContext,
282    ) -> root::Result;
283}
284extern "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
292extern "C" {
293    #[link_name = "\u{1}_ZN2nn7account12AsyncContextC1Ev"]
294    pub fn AsyncContext_AsyncContext(this: *mut AsyncContext);
295}
296
297impl 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}