From 94444aa8d449d312ddd92e5f3a4ae303c0067bae Mon Sep 17 00:00:00 2001 From: MasaGratoR Date: Sun, 7 Dec 2025 16:20:57 +0100 Subject: [PATCH] Add nsGetApplicationControlData2 (#699) --- nx/include/switch/services/ns.h | 14 ++++++++++++++ nx/source/services/ns.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index 1e7f4551..969610a2 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -312,6 +312,20 @@ Result nsGetDocumentInterface(Service* srv_out); */ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); +/** + * @brief Gets the \ref NsApplicationControlData for the specified application. + * @note Only available on [19.0.0+]. + * @param[in] source Source, official sw uses ::NsApplicationControlSource_Storage. + * @param[in] application_id ApplicationId. + * @param[out] buffer \ref NsApplicationControlData + * @param[in] size Size of the buffer. + * @param[in] flag1 Default is 0. 0xFF speeds up execution. + * @param[in] flag2 Default is 0. + * @param[out] actual_size Actual output size. + * @param[out] unk Returned with size, always 0. + */ +Result nsGetApplicationControlData2(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u8 flag1, u8 flag2, u64* actual_size, u32* unk); + /** * @brief GetApplicationDesiredLanguage. Selects a \ref NacpLanguageEntry to use from the specified \ref NacpStruct. * @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index fd87c6c6..a1ec650e 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -488,6 +488,36 @@ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 applic return rc; } +Result nsGetApplicationControlData2(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u8 flag1, u8 flag2, u64* actual_size, u32* unk) { + if (hosversionBefore(19,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + u32 cmd_id = 6; + rc = nsGetReadOnlyApplicationControlDataInterface(&srv); + + const struct { + u8 source; + u8 flags[2]; + u8 pad[5]; + u64 application_id; + } in = { source, {flag1, flag2}, {0}, application_id }; + + u64 tmp=0; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, cmd_id, in, tmp, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { buffer, size } }, + ); + if (R_SUCCEEDED(rc)) { + if (actual_size) *actual_size = tmp >> 32; + if (unk) *unk = (u32)tmp; + } + + serviceClose(&srv); + return rc; +} + Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry) { if (nacp==NULL || langentry==NULL) return MAKERESULT(Module_Libnx, LibnxError_BadInput);