diff --git a/nx/include/switch.h b/nx/include/switch.h index b51d25d5..5b06c4fd 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -64,6 +64,7 @@ extern "C" { #include "switch/services/bpc.h" #include "switch/services/pcv.h" #include "switch/services/clkrst.h" +#include "switch/services/fan.h" #include "switch/services/psm.h" #include "switch/services/spsm.h" //#include "switch/services/bsd.h" Use instead @@ -84,6 +85,7 @@ extern "C" { #include "switch/services/ns.h" #include "switch/services/ldr.h" #include "switch/services/ro.h" +#include "switch/services/tc.h" #include "switch/services/ts.h" #include "switch/services/pm.h" #include "switch/services/set.h" diff --git a/nx/include/switch/nacp.h b/nx/include/switch/nacp.h index 4faffdc4..784581df 100644 --- a/nx/include/switch/nacp.h +++ b/nx/include/switch/nacp.h @@ -77,5 +77,6 @@ typedef struct { } NacpStruct; /// Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty. +/// If you're using ns you may want to use \ref nsGetApplicationDesiredLanguage instead. Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry); diff --git a/nx/include/switch/services/apm.h b/nx/include/switch/services/apm.h index b1d44e34..2c792db9 100644 --- a/nx/include/switch/services/apm.h +++ b/nx/include/switch/services/apm.h @@ -33,6 +33,12 @@ Service* apmGetServiceSession(void); /// Gets the Service object for ISession. Service* apmGetServiceSession_Session(void); +/** + * @brief Gets the current ApmPerformanceMode. + * @param[out] out_performanceMode ApmPerformanceMode + */ +Result apmGetPerformanceMode(ApmPerformanceMode* out_performanceMode); + /** * @brief Sets the PerformanceConfiguration for the specified PerformanceMode. * @param[in] PerformanceMode \ref ApmPerformanceMode diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index ee02c6f0..2fc56b32 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -2468,6 +2468,10 @@ AppletOperationMode appletGetOperationMode(void); ApmPerformanceMode appletGetPerformanceMode(void); AppletFocusState appletGetFocusState(void); +/** + * @brief Sets the current \ref AppletFocusHandlingMode. + * @note Should only be called with AppletType_Application. + */ Result appletSetFocusHandlingMode(AppletFocusHandlingMode mode); ///@} diff --git a/nx/include/switch/services/fan.h b/nx/include/switch/services/fan.h new file mode 100644 index 00000000..b77bf4b4 --- /dev/null +++ b/nx/include/switch/services/fan.h @@ -0,0 +1,32 @@ +/** + * @file fan.h + * @brief Fan service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef struct { + Service s; +} FanController; + +/// Initialize fan. +Result fanInitialize(void); + +/// Exit fan. +void fanExit(void); + +/// Gets the Service object for the actual fan service session. +Service* fanGetServiceSession(void); + +/// Opens IController session. +Result fanOpenController(FanController *out, u32 device_code); + +/// Close IController session. +void fanControllerClose(FanController *controller); + +/// @warning Disabling your fan can damage your system. +Result fanControllerSetRotationSpeedLevel(FanController *controller, float level); +Result fanControllerGetRotationSpeedLevel(FanController *controller, float *level); diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 3b4ebcc8..b69b3246 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -350,6 +350,8 @@ Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, NcmStorageId storag Result fsOpenDeviceOperator(FsDeviceOperator* out); Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out); +Result fsIsSignedSystemPartitionOnSdCardValid(bool *out); + /// Retrieves the rights id corresponding to the content path. Only available on [2.0.0+]. Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id); diff --git a/nx/include/switch/services/lbl.h b/nx/include/switch/services/lbl.h index 6a6feff0..03bfb548 100644 --- a/nx/include/switch/services/lbl.h +++ b/nx/include/switch/services/lbl.h @@ -8,6 +8,13 @@ #include "../types.h" #include "../sf/service.h" +typedef enum { + LblBacklightSwitchStatus_Disabled = 0, + LblBacklightSwitchStatus_Enabled = 1, + LblBacklightSwitchStatus_Enabling = 2, + LblBacklightSwitchStatus_Disabling = 3, +} LblBacklightSwitchStatus; + /// Initialize lbl. Result lblInitialize(void); @@ -17,8 +24,8 @@ void lblExit(void); /// Gets the Service object for the actual lbl service session. Service* lblGetServiceSession(void); -Result lblSwitchBacklightOn(u64 fade_time); -Result lblSwitchBacklightOff(u64 fade_time); +Result lblSaveCurrentSetting(void); +Result lblLoadCurrentSetting(void); /** * @note The brightness goes from 0 to 1.0. @@ -26,6 +33,58 @@ Result lblSwitchBacklightOff(u64 fade_time); Result lblSetCurrentBrightnessSetting(float brightness); Result lblGetCurrentBrightnessSetting(float *out_value); +Result lblApplyCurrentBrightnessSettingToBacklight(void); +Result lblGetBrightnessSettingAppliedToBacklight(float *out_value); + +Result lblSwitchBacklightOn(u64 fade_time); +Result lblSwitchBacklightOff(u64 fade_time); +Result lblGetBacklightSwitchStatus(LblBacklightSwitchStatus *out_value); + +Result lblEnableDimming(void); +Result lblDisableDimming(void); +Result lblIsDimmingEnabled(bool *out_value); + Result lblEnableAutoBrightnessControl(void); Result lblDisableAutoBrightnessControl(void); Result lblIsAutoBrightnessControlEnabled(bool *out_value); + +Result lblSetAmbientLightSensorValue(float value); + +/** + * @note Used internally by \ref appletGetAmbientLightSensorValue and \ref appletGetCurrentIlluminanceEx. + */ +Result lblGetAmbientLightSensorValue(bool *over_limit, float *lux); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletIsIlluminanceAvailable. + */ +Result lblIsAmbientLightSensorAvailable(bool *out_value); + +/** + * @note Only available on [3.0.0+]. + */ +Result lblSetCurrentBrightnessSettingForVrMode(float brightness); + +/** + * @note Only available on [3.0.0+]. + */ +Result lblGetCurrentBrightnessSettingForVrMode(float *out_value); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletSetVrModeEnabled. + */ +Result lblEnableVrMode(void); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletSetVrModeEnabled. + */ +Result lblDisableVrMode(void); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletIsVrModeEnabled. + */ +Result lblIsVrModeEnabled(bool *out_value); diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index b7123787..c4383481 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -74,6 +74,11 @@ typedef struct { u8 icon[0x20000]; ///< JPEG } NsApplicationControlData; +/// ApplicationOccupiedSize +typedef struct { + u8 unk_x0[0x80]; ///< Unknown. +} NsApplicationOccupiedSize; + /// NsApplicationContentMetaStatus typedef struct { u8 meta_type; ///< \ref NcmContentMetaType @@ -216,6 +221,11 @@ typedef struct { u8 unk_x1a[0x6]; ///< Unknown. } NsApplicationRightsOnClient; +/// DownloadTaskStatus +typedef struct { + u8 unk_x0[0x20]; ///< Unknown. +} NsDownloadTaskStatus; + /// Default size for \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater. This is the size used by qlaunch for SetupCardUpdate. #define NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT 0x100000 @@ -231,9 +241,148 @@ void nsExit(void); /// Gets the Service object for the actual ns:* service session. Only initialized on [3.0.0+], on pre-3.0.0 see \ref nsGetServiceSession_ApplicationManagerInterface. Service* nsGetServiceSession_GetterInterface(void); -/// Gets the Service object for IApplicationManagerInterface. +/// Gets the Service object for IApplicationManagerInterface. Only initialized on pre-3.0.0, on [3.0.0+] use \ref nsGetApplicationManagerInterface. Service* nsGetServiceSession_ApplicationManagerInterface(void); +/// Gets the Service object for IDynamicRightsInterface via the cmd for that. +/// Only available on [6.0.0+]. +Result nsGetDynamicRightsInterface(Service* srv_out); + +/// Gets the Service object for IReadOnlyApplicationControlDataInterface via the cmd for that. +/// Only available on [5.1.0+]. +Result nsGetReadOnlyApplicationControlDataInterface(Service* srv_out); + +/// Gets the Service object for IReadOnlyApplicationRecordInterface via the cmd for that. +/// Only available on [5.0.0+]. +Result nsGetReadOnlyApplicationRecordInterface(Service* srv_out); + +/// Gets the Service object for IECommerceInterface via the cmd for that. +/// Only available on [4.0.0+]. +Result nsGetECommerceInterface(Service* srv_out); + +/// Gets the Service object for IApplicationVersionInterface via the cmd for that. +/// Only available on [4.0.0+]. +Result nsGetApplicationVersionInterface(Service* srv_out); + +/// Gets the Service object for IFactoryResetInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetFactoryResetInterface(Service* srv_out); + +/// Gets the Service object for IAccountProxyInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetAccountProxyInterface(Service* srv_out); + +/// Gets the Service object for IApplicationManagerInterface via the cmd for that. +/// Only available on [3.0.0+], on prior sysvers use \ref nsGetServiceSession_ApplicationManagerInterface. +Result nsGetApplicationManagerInterface(Service* srv_out); + +/// Gets the Service object for IDownloadTaskInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetDownloadTaskInterface(Service* srv_out); + +/// Gets the Service object for IContentManagementInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetContentManagementInterface(Service* srv_out); + +/// Gets the Service object for IDocumentInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetDocumentInterface(Service* srv_out); + +///@} + +///@name IReadOnlyApplicationControlDataInterface +///@{ + +/** + * @brief Gets the \ref NsApplicationControlData for the specified application. + * @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. + * @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[out] actual_size Actual output size. + */ +Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); + +/** + * @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. + * @param[in] nacp \ref NacpStruct + * @param[out] langentry \ref NacpLanguageEntry + */ +Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry); + +///@} + +///@name IECommerceInterface +///@{ + +/** + * @brief RequestLinkDevice + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] uid \ref AccountUid + */ +Result nsRequestLinkDevice(AsyncResult *a, AccountUid uid); + +/** + * @brief RequestSyncRights + * @note Only available on [6.0.0+]. + * @param[out] a \ref AsyncResult + */ +Result nsRequestSyncRights(AsyncResult *a); + +/** + * @brief RequestUnlinkDevice + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [6.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] uid \ref AccountUid + */ +Result nsRequestUnlinkDevice(AsyncResult *a, AccountUid uid); + +///@} + +///@name IFactoryResetInterface +///@{ + +/** + * @brief ResetToFactorySettings + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsResetToFactorySettings(void); + +/** + * @brief ResetToFactorySettingsWithoutUserSaveData + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsResetToFactorySettingsWithoutUserSaveData(void); + +/** + * @brief ResetToFactorySettingsForRefurbishment + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsResetToFactorySettingsForRefurbishment(void); + +/** + * @brief ResetToFactorySettingsWithPlatformRegion + * @note Only available on [9.1.0+]. + */ +Result nsResetToFactorySettingsWithPlatformRegion(void); + +/** + * @brief ResetToFactorySettingsWithPlatformRegionAuthentication + * @note Only available on [9.1.0+]. + */ +Result nsResetToFactorySettingsWithPlatformRegionAuthentication(void); + +///@} + +///@name IApplicationManagerInterface +///@{ + /** * @brief Gets an listing of \ref NsApplicationRecord. * @param[out] records Output array of \ref NsApplicationRecord. @@ -337,20 +486,6 @@ Result nsCleanupSdCard(void); */ Result nsGetSdCardMountStatusChangedEvent(Event* out_event); -/** - * @brief Returns the total storage capacity (used + free) from content manager services. - * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. - * @param[out] size Pointer to output the total storage size to. - */ -Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size); - -/** - * @brief Returns the available storage capacity from content manager services. - * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. - * @param[out] size Pointer to output the free storage size to. - */ -Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size); - /** * @brief GetGameCardUpdateDetectionEvent * @note The Event must be closed by the user once finished with it. @@ -477,16 +612,6 @@ Result nsUnregisterNetworkServiceAccount(AccountUid uid); */ Result nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion(AccountUid uid); -/** - * @brief Gets the \ref NsApplicationControlData for the specified application. - * @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[out] actual_size Actual output size. - */ -Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); - /** * @brief RequestDownloadApplicationControlData * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. @@ -587,17 +712,6 @@ Result nsGetLastGameCardMountFailureResult(void); */ Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total_out); -/** - * @brief Gets an listing of \ref NsApplicationContentMetaStatus. - * @note Only available on [2.0.0+]. - * @param[in] application_id ApplicationId. - * @param[in] index Starting entry index. - * @param[out] list Output array of \ref NsApplicationContentMetaStatus. - * @param[in] count Size of the list array in entries. - * @param[out] out_entrycount Total output entries. - */ -Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount); - /** * @brief TouchApplication * @note Only available on [2.0.0+]. @@ -938,6 +1052,138 @@ Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, Accoun ///@} +///@name IDownloadTaskInterface +///@{ + +/** + * @brief ClearTaskStatusList + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsClearTaskStatusList(void); + +/** + * @brief RequestDownloadTaskList + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsRequestDownloadTaskList(void); + +/** + * @brief RequestEnsureDownloadTask + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncResult + */ +Result nsRequestEnsureDownloadTask(AsyncResult *a); + +/** + * @brief ListDownloadTaskStatus + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] tasks Output array of \ref NsDownloadTaskStatus. + * @param[in] count Size of the tasks array in entries. A maximum of 0x100 tasks can be stored in state. + * @param[out] total_out Total output entries. + */ +Result nsListDownloadTaskStatus(NsDownloadTaskStatus* tasks, s32 count, s32 *total_out); + +/** + * @brief RequestDownloadTaskListData + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncValue + */ +Result nsRequestDownloadTaskListData(AsyncValue *a); + +/** + * @brief TryCommitCurrentApplicationDownloadTask + * @note Only available on [4.0.0+]. + */ +Result nsTryCommitCurrentApplicationDownloadTask(void); + +/** + * @brief EnableAutoCommit + * @note Only available on [4.0.0+]. + */ +Result nsEnableAutoCommit(void); + +/** + * @brief DisableAutoCommit + * @note Only available on [4.0.0+]. + */ +Result nsDisableAutoCommit(void); + +/** + * @brief TriggerDynamicCommitEvent + * @note Only available on [4.0.0+]. + */ +Result nsTriggerDynamicCommitEvent(void); + +///@} + +///@name IContentManagementInterface +///@{ + +/** + * @brief CalculateApplicationOccupiedSize + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] application_id ApplicationId. + * @param[out] out \ref NsApplicationOccupiedSize + */ +Result nsCalculateApplicationOccupiedSize(u64 application_id, NsApplicationOccupiedSize *out); + +/** + * @brief CheckSdCardMountStatus + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsCheckSdCardMountStatus(void); + +/** + * @brief Returns the total storage capacity (used + free) from content manager services. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. + * @param[out] size Pointer to output the total storage size to. + */ +Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size); + +/** + * @brief Returns the available storage capacity from content manager services. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. + * @param[out] size Pointer to output the free storage size to. + */ +Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size); + +/** + * @brief CountApplicationContentMeta + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] out Output count. + */ +Result nsCountApplicationContentMeta(u64 application_id, s32 *out); + +/** + * @brief Gets an listing of \ref NsApplicationContentMetaStatus. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[in] index Starting entry index. + * @param[out] list Output array of \ref NsApplicationContentMetaStatus. + * @param[in] count Size of the list array in entries. + * @param[out] out_entrycount Total output entries. + */ +Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount); + +/** + * @brief IsAnyApplicationRunning + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result nsIsAnyApplicationRunning(bool *out); + +///@} + ///@name IRequestServerStopper ///@{ diff --git a/nx/include/switch/services/tc.h b/nx/include/switch/services/tc.h new file mode 100644 index 00000000..56be6c06 --- /dev/null +++ b/nx/include/switch/services/tc.h @@ -0,0 +1,26 @@ +/** + * @file tc.h + * @brief Temperature control (tc) service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Initialize tc. +Result tcInitialize(void); + +/// Exit tc. +void tcExit(void); + +/// Gets the Service for tc. +Service* tcGetServiceSession(void); + +Result tcEnableFanControl(void); +/// @warning Disabling your fan can damage your system. +Result tcDisableFanControl(void); +Result tcIsFanControlEnabled(bool *status); +/// Only available on [5.0.0+]. +Result tcGetSkinTemperatureMilliC(s32 *skinTemp); + diff --git a/nx/include/switch/services/ts.h b/nx/include/switch/services/ts.h index cc85b0c8..81ce554e 100644 --- a/nx/include/switch/services/ts.h +++ b/nx/include/switch/services/ts.h @@ -10,8 +10,8 @@ /// Location typedef enum { - TsLocation_Internal = 0, ///< Internal - TsLocation_External = 1, ///< External + TsLocation_Internal = 0, ///< TMP451 Internal: PCB + TsLocation_External = 1, ///< TMP451 External: SoC } TsLocation; /// Initialize ts. diff --git a/nx/source/display/native_window.c b/nx/source/display/native_window.c index 4703c97c..47081ced 100644 --- a/nx/source/display/native_window.c +++ b/nx/source/display/native_window.c @@ -324,13 +324,8 @@ Result nwindowReleaseBuffers(NWindow* nw) if (nw->cur_slot >= 0) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput); - else if (nw->is_connected && nw->slots_configured) { - for (u32 i = 0; i < 64; i ++) - if (nw->slots_configured & (1UL << i)) - bqDetachBuffer(&nw->bq, i); - + else if (nw->is_connected && nw->slots_configured) rc = _nwindowDisconnect(nw); - } mutexUnlock(&nw->mutex); return rc; diff --git a/nx/source/services/apm.c b/nx/source/services/apm.c index 1eddb72e..02650b83 100644 --- a/nx/source/services/apm.c +++ b/nx/source/services/apm.c @@ -39,6 +39,10 @@ static Result _apmCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id) { ); } +Result apmGetPerformanceMode(ApmPerformanceMode* out_performanceMode) { + return serviceDispatchOut(&g_apmSrv, 1, *out_performanceMode); +} + Result apmSetPerformanceConfiguration(ApmPerformanceMode PerformanceMode, u32 PerformanceConfiguration) { const struct { u32 PerformanceMode; diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index e66ac5ba..f83ed9f0 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -541,6 +541,8 @@ Result appletSetFocusHandlingMode(AppletFocusHandlingMode mode) { Result rc; bool invals[4]; + if (__nx_applet_type != AppletType_Application) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); if (mode >= AppletFocusHandlingMode_Max) return MAKERESULT(Module_Libnx, LibnxError_BadInput); diff --git a/nx/source/services/fan.c b/nx/source/services/fan.c new file mode 100644 index 00000000..1a94d147 --- /dev/null +++ b/nx/source/services/fan.c @@ -0,0 +1,39 @@ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" +#include "services/fan.h" +#include "runtime/hosversion.h" + +static Service g_fanSrv; + +NX_GENERATE_SERVICE_GUARD(fan); + +Result _fanInitialize(void) { + return smGetService(&g_fanSrv, "fan"); +} + +void _fanCleanup(void) { + serviceClose(&g_fanSrv); +} + +Result fanOpenController(FanController *out, u32 device_code) { + return serviceDispatchIn(&g_fanSrv, 0, device_code, + .out_num_objects = 1, + .out_objects = &out->s, + ); +} + +Service* fanGetServiceSession(void) { + return &g_fanSrv; +} + +void fanControllerClose(FanController *controller) { + serviceClose(&controller->s); +} + +Result fanControllerSetRotationSpeedLevel(FanController *controller, float level) { + return serviceDispatchIn(&controller->s, 0, level); +} + +Result fanControllerGetRotationSpeedLevel(FanController *controller, float *level) { + return serviceDispatchOut(&controller->s, 2, *level); +} diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index ba5bda71..2613f3f2 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -402,6 +402,13 @@ Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out) { return _fsCmdGetSession(&g_fsSrv, &out->s, 500); } +Result fsIsSignedSystemPartitionOnSdCardValid(bool *out) { + if (!hosversionBetween(4, 8)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _fsCmdNoInOutBool(&g_fsSrv, out, 640); +} + Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -622,9 +629,6 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void * if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - char send_path[FS_MAX_PATH] = {0}; - strncpy(send_path, path, sizeof(send_path)-1); - return _fsObjectDispatchIn(&fs->s, 15, query_id, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In, @@ -632,9 +636,9 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void * SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, }, .buffers = { - { send_path, sizeof(send_path) }, - { in, in_size }, - { out, out_size }, + { path, FS_MAX_PATH }, + { in, in_size }, + { out, out_size }, }, ); } @@ -648,7 +652,8 @@ Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out) { return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); u8 tmp=0; - Result rc = fsFsQueryEntry(fs, &tmp, sizeof(tmp), NULL, 0, "/", FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard); + char send_path[FS_MAX_PATH] = "/"; + Result rc = fsFsQueryEntry(fs, &tmp, sizeof(tmp), NULL, 0, send_path, FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } diff --git a/nx/source/services/lbl.c b/nx/source/services/lbl.c index 5dbbd1b8..6e491692 100644 --- a/nx/source/services/lbl.c +++ b/nx/source/services/lbl.c @@ -1,6 +1,7 @@ #define NX_SERVICE_ASSUME_NON_DOMAIN #include "service_guard.h" #include "services/lbl.h" +#include "runtime/hosversion.h" static Service g_lblSrv; @@ -37,6 +38,38 @@ static Result _lblCmdNoInOutBool(bool *out, u32 cmd_id) { return rc; } +static Result _lblCmdNoInOutFloat(float *out, u32 cmd_id) { + return serviceDispatchOut(&g_lblSrv, cmd_id, *out); +} + +static Result _lblCmdInFloatNoOut(float in, u32 cmd_id) { + return serviceDispatchIn(&g_lblSrv, cmd_id, in); +} + +Result lblSaveCurrentSetting(void) { + return _lblCmdNoIO(0); +} + +Result lblLoadCurrentSetting(void) { + return _lblCmdNoIO(1); +} + +Result lblSetCurrentBrightnessSetting(float brightness) { + return _lblCmdInFloatNoOut(brightness, 2); +} + +Result lblGetCurrentBrightnessSetting(float *out_value) { + return _lblCmdNoInOutFloat(out_value, 3); +} + +Result lblApplyCurrentBrightnessSettingToBacklight(void) { + return _lblCmdNoIO(4); +} + +Result lblGetBrightnessSettingAppliedToBacklight(float *out_value) { + return _lblCmdNoInOutFloat(out_value, 5); +} + Result lblSwitchBacklightOn(u64 fade_time) { return _lblCmdInU64NoOut(fade_time, 6); } @@ -45,12 +78,20 @@ Result lblSwitchBacklightOff(u64 fade_time) { return _lblCmdInU64NoOut(fade_time, 7); } -Result lblSetCurrentBrightnessSetting(float brightness) { - return serviceDispatchIn(&g_lblSrv, 2, brightness); +Result lblGetBacklightSwitchStatus(LblBacklightSwitchStatus *out_value) { + return serviceDispatchOut(&g_lblSrv, 8, *out_value); } -Result lblGetCurrentBrightnessSetting(float *out_value) { - return serviceDispatchOut(&g_lblSrv, 3, *out_value); +Result lblEnableDimming(void) { + return _lblCmdNoIO(9); +} + +Result lblDisableDimming(void) { + return _lblCmdNoIO(10); +} + +Result lblIsDimmingEnabled(bool *out_value) { + return _lblCmdNoInOutBool(out_value, 11); } Result lblEnableAutoBrightnessControl(void) { @@ -64,3 +105,55 @@ Result lblDisableAutoBrightnessControl(void) { Result lblIsAutoBrightnessControlEnabled(bool *out_value){ return _lblCmdNoInOutBool(out_value, 14); } + +Result lblSetAmbientLightSensorValue(float value) { + return _lblCmdInFloatNoOut(value, 15); +} + +Result lblGetAmbientLightSensorValue(bool *over_limit, float *lux) { + struct { + u32 over_limit; + float lux; + } out; + + Result rc = serviceDispatchOut(&g_lblSrv, 16, out); + if (R_SUCCEEDED(rc)) { + if (over_limit) *over_limit = out.over_limit & 1; + if (lux) *lux = out.lux; + } + return rc; +} + +Result lblIsAmbientLightSensorAvailable(bool *out_value) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdNoInOutBool(out_value, 23); +} +Result lblSetCurrentBrightnessSettingForVrMode(float brightness) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdInFloatNoOut(brightness, 24); +} +Result lblGetCurrentBrightnessSettingForVrMode(float *out_value) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdNoInOutFloat(out_value, 25); +} + +Result lblEnableVrMode(void) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdNoIO(26); +} + +Result lblDisableVrMode(void) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdNoIO(27); +} + +Result lblIsVrModeEnabled(bool *out_value) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _lblCmdNoInOutBool(out_value, 28); +} diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index eb9e3950..c2716ecf 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -19,23 +19,24 @@ NX_GENERATE_SERVICE_GUARD(ns); Result _nsInitialize(void) { Result rc=0; + static const char* const servarray[5] = {"ns:ec", "ns:web", "ns:rid", "ns:rt", "ns:am2"}; // This is the order used used by official sw, however the below loop uses this in reverse since ns:am2 is last in the list. if(hosversionBefore(3,0,0)) return smGetService(&g_nsAppManSrv, "ns:am"); - rc = smGetService(&g_nsGetterSrv, "ns:am2");//TODO: Support the other services?(Only useful when ns:am2 isn't accessible) - if (R_FAILED(rc)) return rc; - - rc = _nsGetSession(&g_nsGetterSrv, &g_nsAppManSrv, 7996); + for (s32 i=4; i>=0; i--) { + rc = smGetService(&g_nsGetterSrv, servarray[i]); + if (R_SUCCEEDED(rc)) break; + } return rc; } void _nsCleanup(void) { - serviceClose(&g_nsAppManSrv); - if(hosversionBefore(3,0,0)) return; - - serviceClose(&g_nsGetterSrv); + if(hosversionBefore(3,0,0)) + serviceClose(&g_nsAppManSrv); + else + serviceClose(&g_nsGetterSrv); } Service* nsGetServiceSession_GetterInterface(void) { @@ -46,6 +47,83 @@ Service* nsGetServiceSession_ApplicationManagerInterface(void) { return &g_nsAppManSrv; } +Result nsGetDynamicRightsInterface(Service* srv_out) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7988); +} + +Result nsGetReadOnlyApplicationControlDataInterface(Service* srv_out) { + if (hosversionBefore(5,1,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7989); +} + +Result nsGetReadOnlyApplicationRecordInterface(Service* srv_out) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7991); +} + +Result nsGetECommerceInterface(Service* srv_out) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7992); +} + +Result nsGetApplicationVersionInterface(Service* srv_out) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7993); +} + +Result nsGetFactoryResetInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7994); +} + +Result nsGetAccountProxyInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7995); +} + +Result nsGetApplicationManagerInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7996); +} + +Result nsGetDownloadTaskInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7997); +} + +Result nsGetContentManagementInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7998); +} + +Result nsGetDocumentInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7999); +} + static Result _nsGetSession(Service* srv, Service* srv_out, u32 cmd_id) { return serviceDispatch(srv, cmd_id, .out_num_objects = 1, @@ -66,6 +144,20 @@ static Result _nsCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 return rc; } +static Result _nsManCmdGetEvent(Event* out_event, bool autoclear, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdGetEvent(srv_ptr, out_event, autoclear, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInHandle64NoOut(Service* srv, Handle handle, u64 inval, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, inval, .in_num_handles = 1, @@ -81,6 +173,20 @@ static Result _nsCmdNoIO(Service* srv, u32 cmd_id) { return serviceDispatch(srv, cmd_id); } +static Result _nsManCmdNoIO(u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInBool(Service* srv, bool inval, u32 cmd_id) { u8 in = inval!=0; @@ -91,6 +197,20 @@ static Result _nsCmdInU64(Service* srv, u64 inval, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, inval); } +static Result _nsManCmdInU64(u64 inval, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64(srv_ptr, inval, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInU64OutU64(Service* srv, u64 inval, u64 *out, u32 cmd_id) { return serviceDispatchInOut(srv, cmd_id, inval, *out); } @@ -106,6 +226,20 @@ static Result _nsCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) { return rc; } +static Result _nsManCmdNoInOutBool(bool *out, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutBool(srv_ptr, out, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdNoInOutU64(Service* srv, u64 *out, u32 cmd_id) { return serviceDispatchOut(srv, cmd_id, *out); } @@ -120,6 +254,20 @@ static Result _nsCmdInU8U64NoOut(Service* srv, u8 in8, u64 in64, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, in); } +static Result _nsManCmdInU8U64NoOut(u8 in8, u64 in64, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU8U64NoOut(srv_ptr, in8, in64, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInU64OutStorageIdS64(Service* srv, u64 inval, NcmStorageId *storage_id, s64 *outval, u32 cmd_id) { struct { u8 storage_id; @@ -135,10 +283,38 @@ static Result _nsCmdInU64OutStorageIdS64(Service* srv, u64 inval, NcmStorageId * return rc; } +static Result _nsManCmdInU64OutStorageIdS64(u64 inval, NcmStorageId *storage_id, s64 *outval, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutStorageIdS64(srv_ptr, inval, storage_id, outval, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInUidNoOut(Service* srv, AccountUid uid, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, uid); } +static Result _nsManCmdInUidNoOut(AccountUid uid, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInUidNoOut(srv_ptr, uid, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdNoInOutSystemUpdateProgress(Service* srv, NsSystemUpdateProgress *out, u32 cmd_id) { return serviceDispatchOut(srv, cmd_id, *out); } @@ -214,6 +390,20 @@ static Result _nsCmdInU64OutAsyncValue(Service* srv, AsyncValue *a, u64 inval, u return rc; } +static Result _nsManCmdInU64OutAsyncValue(AsyncValue *a, u64 inval, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutAsyncValue(srv_ptr, a, inval, cmd_id); + + serviceClose(&srv); + return rc; +} + static Result _nsCmdInU64OutAsyncResult(Service* srv, AsyncResult *a, u64 inval, u32 cmd_id) { memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; @@ -230,23 +420,266 @@ static Result _nsCmdInU64OutAsyncResult(Service* srv, AsyncResult *a, u64 inval, return rc; } +static Result _nsManCmdInU64OutAsyncResult(AsyncResult *a, u64 inval, u32 cmd_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutAsyncResult(srv_ptr, a, inval, cmd_id); + + serviceClose(&srv); + return rc; +} + +static Result _nsCmdInUidOutAsyncResult(Service* srv, AsyncResult *a, AccountUid uid, u32 cmd_id) { + memset(a, 0, sizeof(*a)); + Handle event = INVALID_HANDLE; + Result rc = serviceDispatchIn(srv, cmd_id, uid, + .out_num_objects = 1, + .out_objects = &a->s, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &event, + ); + + if (R_SUCCEEDED(rc)) + eventLoadRemote(&a->event, event, false); + + return rc; +} + static Result _nsCheckNifm(void) { return nifmIsAnyInternetRequestAccepted(nifmGetClientId()) ? 0 : MAKERESULT(16, 340); } +// IReadOnlyApplicationControlDataInterface + +Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + u32 cmd_id = 400; + if (hosversionAtLeast(5,1,0)) { + rc = nsGetReadOnlyApplicationControlDataInterface(&srv); + cmd_id = 0; + } + else + srv_ptr = &g_nsAppManSrv; + + const struct { + u8 source; + u8 pad[7]; + u64 application_id; + } in = { source, {0}, application_id }; + + u32 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) && actual_size) *actual_size = tmp; + + serviceClose(&srv); + return rc; +} + +Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry) { + if (nacp==NULL || langentry==NULL) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + *langentry = NULL; + + NacpLanguageEntry *entry = NULL; + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + u32 cmd_id = 55; + if (hosversionAtLeast(5,1,0)) { + rc = nsGetReadOnlyApplicationControlDataInterface(&srv); + cmd_id = 1; + } + else + srv_ptr = &g_nsAppManSrv; + + u8 lang_bitmask=0, out=0; + + if (R_SUCCEEDED(rc)) { + for (u32 i=0; i<16; i++) { + entry = &nacp->lang[i]; + if (entry->name[0] || entry->author[0]) lang_bitmask |= BIT(i); + } + if (!lang_bitmask) { + *langentry = &nacp->lang[0]; + return 0; + } + } + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, cmd_id, lang_bitmask, out); + if (R_SUCCEEDED(rc)) { + if (out > 16) out = 0; + if (lang_bitmask & BIT(out)) + *langentry = &nacp->lang[out]; + else + rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + } + + serviceClose(&srv); + return rc; +} + +// IECommerceInterface + +Result nsRequestLinkDevice(AsyncResult *a, AccountUid uid) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Result rc = _nsCheckNifm(); + if (R_FAILED(rc)) return rc; + + Service srv={0}; + rc = nsGetECommerceInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdInUidOutAsyncResult(&srv, a, uid, 0); + + serviceClose(&srv); + return rc; +} + +Result nsRequestSyncRights(AsyncResult *a) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetECommerceInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutAsyncResult(&srv, a, 3); + + serviceClose(&srv); + return rc; +} + +Result nsRequestUnlinkDevice(AsyncResult *a, AccountUid uid) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Result rc = _nsCheckNifm(); + if (R_FAILED(rc)) return rc; + + Service srv={0}; + rc = nsGetECommerceInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdInUidOutAsyncResult(&srv, a, uid, 4); + + serviceClose(&srv); + return rc; +} + +// IFactoryResetInterface + +Result nsResetToFactorySettings(void) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetFactoryResetInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 100); + + serviceClose(&srv); + return rc; +} + +Result nsResetToFactorySettingsWithoutUserSaveData(void) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetFactoryResetInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 101); + + serviceClose(&srv); + return rc; +} + +Result nsResetToFactorySettingsForRefurbishment(void) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetFactoryResetInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 102); + + serviceClose(&srv); + return rc; +} + +Result nsResetToFactorySettingsWithPlatformRegion(void) { + if (hosversionBefore(9,1,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetFactoryResetInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 103); + + serviceClose(&srv); + return rc; +} + +Result nsResetToFactorySettingsWithPlatformRegionAuthentication(void) { + if (hosversionBefore(9,1,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetFactoryResetInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 104); + + serviceClose(&srv); + return rc; +} + +// IApplicationManagerInterface + Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount) { - return serviceDispatchInOut(&g_nsAppManSrv, 0, entry_offset, *out_entrycount, + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 0, entry_offset, *out_entrycount, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { records, count*sizeof(NsApplicationRecord) } }, ); + + serviceClose(&srv); + return rc; } Result nsGetApplicationRecordUpdateSystemEvent(Event* out_event) { - return _nsCmdGetEvent(&g_nsAppManSrv, out_event, true, 2); + return _nsManCmdGetEvent(out_event, true, 2); } Result nsGetApplicationViewDeprecated(NsApplicationViewDeprecated *views, const u64 *application_ids, s32 count) { - return serviceDispatch(&g_nsAppManSrv, 3, + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatch(srv_ptr, 3, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -256,21 +689,31 @@ Result nsGetApplicationViewDeprecated(NsApplicationViewDeprecated *views, const { application_ids, count*sizeof(u64) }, }, ); + + serviceClose(&srv); + return rc; } Result nsDeleteApplicationEntity(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 4); + return _nsManCmdInU64(application_id, 4); } Result nsDeleteApplicationCompletely(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 5); + return _nsManCmdInU64(application_id, 5); } Result nsDeleteRedundantApplicationEntity(void) { - return _nsCmdNoIO(&g_nsAppManSrv, 7); + return _nsManCmdNoIO(7); } Result nsIsApplicationEntityMovable(u64 application_id, NcmStorageId storage_id, bool *out) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { u8 storage_id; u8 pad[7]; @@ -278,134 +721,153 @@ Result nsIsApplicationEntityMovable(u64 application_id, NcmStorageId storage_id, } in = { storage_id, {0}, application_id }; u8 tmp=0; - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 8, in, tmp); + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 8, in, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + + serviceClose(&srv); return rc; } Result nsMoveApplicationEntity(u64 application_id, NcmStorageId storage_id) { - return _nsCmdInU8U64NoOut(&g_nsAppManSrv, storage_id, application_id, 9); + return _nsManCmdInU8U64NoOut(storage_id, application_id, 9); } Result nsRequestApplicationUpdateInfo(AsyncValue *a, u64 application_id) { Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 30); + return _nsManCmdInU64OutAsyncValue(a, application_id, 30); } Result nsCancelApplicationDownload(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 32); + return _nsManCmdInU64(application_id, 32); } Result nsResumeApplicationDownload(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 33); + return _nsManCmdInU64(application_id, 33); } Result nsCheckApplicationLaunchVersion(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 38); + return _nsManCmdInU64(application_id, 38); } Result nsCalculateApplicationDownloadRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size) { - return _nsCmdInU64OutStorageIdS64(&g_nsAppManSrv, application_id, storage_id, size, 41); + return _nsManCmdInU64OutStorageIdS64(application_id, storage_id, size, 41); } Result nsCleanupSdCard(void) { - return _nsCmdNoIO(&g_nsAppManSrv, 42); + return _nsManCmdNoIO(42); } Result nsGetSdCardMountStatusChangedEvent(Event* out_event) { - return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 44); -} - -Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size) { - return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, (u64*)size, 47); -} - -Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size) { - return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, (u64*)size, 48); + return _nsManCmdGetEvent(out_event, false, 44); } Result nsGetGameCardUpdateDetectionEvent(Event* out_event) { - return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 52); + return _nsManCmdGetEvent(out_event, false, 52); } Result nsDisableApplicationAutoDelete(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 53); + return _nsManCmdInU64(application_id, 53); } Result nsEnableApplicationAutoDelete(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 54); + return _nsManCmdInU64(application_id, 54); } Result nsSetApplicationTerminateResult(u64 application_id, Result res) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { Result res; u32 pad; u64 application_id; } in = { res, 0, application_id }; - return serviceDispatchIn(&g_nsAppManSrv, 56, in); + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 56, in); + + serviceClose(&srv); + return rc; } Result nsClearApplicationTerminateResult(u64 application_id) { - return _nsCmdInU64(&g_nsAppManSrv, application_id, 57); + return _nsManCmdInU64(application_id, 57); } Result nsGetLastSdCardMountUnexpectedResult(void) { - return _nsCmdNoIO(&g_nsAppManSrv, 58); + return _nsManCmdNoIO(58); } Result nsGetRequestServerStopper(NsRequestServerStopper *r) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsGetSession(&g_nsAppManSrv, &r->s, 65); + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsGetSession(srv_ptr, &r->s, 65); + + serviceClose(&srv); + return rc; } Result nsCancelApplicationApplyDelta(u64 application_id) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64(&g_nsAppManSrv, application_id, 67); + return _nsManCmdInU64(application_id, 67); } Result nsResumeApplicationApplyDelta(u64 application_id) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64(&g_nsAppManSrv, application_id, 68); + return _nsManCmdInU64(application_id, 68); } Result nsCalculateApplicationApplyDeltaRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64OutStorageIdS64(&g_nsAppManSrv, application_id, storage_id, size, 69); + return _nsManCmdInU64OutStorageIdS64(application_id, storage_id, size, 69); } Result nsResumeAll(void) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoIO(&g_nsAppManSrv, 70); + return _nsManCmdNoIO(70); } Result nsGetStorageSize(NcmStorageId storage_id, s64 *total_space_size, s64 *free_space_size) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + struct { s64 total_space_size; s64 free_space_size; } out; u8 tmp = storage_id; - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 71, tmp, out); + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 71, tmp, out); if (R_SUCCEEDED(rc)) { if (total_space_size) *total_space_size = out.total_space_size; if (free_space_size) *free_space_size = out.free_space_size; } + + serviceClose(&srv); return rc; } @@ -416,68 +878,74 @@ Result nsRequestUpdateApplication2(AsyncResult *a, u64 application_id) { Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 85); + return _nsManCmdInU64OutAsyncResult(a, application_id, 85); } Result nsDeleteUserSaveDataAll(NsProgressMonitorForDeleteUserSaveDataAll *p, AccountUid uid) { - return serviceDispatchIn(&g_nsAppManSrv, 201, uid, + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 201, uid, .out_num_objects = 1, .out_objects = &p->s, ); + + serviceClose(&srv); + return rc; } Result nsDeleteUserSystemSaveData(AccountUid uid, u64 system_save_data_id) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { AccountUid uid; u64 system_save_data_id; } in = { uid, system_save_data_id }; - return serviceDispatchIn(&g_nsAppManSrv, 210, in); + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 210, in); + + serviceClose(&srv); + return rc; } Result nsDeleteSaveData(FsSaveDataSpaceId save_data_space_id, u64 save_data_id) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU8U64NoOut(&g_nsAppManSrv, save_data_space_id, save_data_id, 211); + return _nsManCmdInU8U64NoOut(save_data_space_id, save_data_id, 211); } Result nsUnregisterNetworkServiceAccount(AccountUid uid) { - return _nsCmdInUidNoOut(&g_nsAppManSrv, uid, 220); + return _nsManCmdInUidNoOut(uid, 220); } Result nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion(AccountUid uid) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInUidNoOut(&g_nsAppManSrv, uid, 221); -} - -Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size) { - const struct { - u8 source; - u8 pad[7]; - u64 application_id; - } in = { source, {0}, application_id }; - - u32 tmp=0; - - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 400, in, tmp, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { buffer, size } }, - ); - if (R_SUCCEEDED(rc) && actual_size) *actual_size = tmp; - return rc; + return _nsManCmdInUidNoOut(uid, 221); } Result nsRequestDownloadApplicationControlData(AsyncResult *a, u64 application_id) { Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 402); + return _nsManCmdInU64OutAsyncResult(a, application_id, 402); } static Result _nsListApplicationTitleIcon(AsyncValue *a, NsApplicationControlSource source, const u64 *application_ids, s32 count, TransferMemory *tmem, u32 cmd_id) { // [8.0.0+] + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u8 source; u8 pad[7]; @@ -486,7 +954,7 @@ static Result _nsListApplicationTitleIcon(AsyncValue *a, NsApplicationControlSou memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, cmd_id, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, cmd_id, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { application_ids, count*sizeof(u64) } }, .in_num_handles = 1, @@ -499,6 +967,8 @@ static Result _nsListApplicationTitleIcon(AsyncValue *a, NsApplicationControlSou if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + + serviceClose(&srv); return rc; } @@ -537,7 +1007,7 @@ Result nsRequestCheckGameCardRegistration(AsyncResult *a, u64 application_id) { Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 502); + return _nsManCmdInU64OutAsyncResult(a, application_id, 502); } Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 application_id) { @@ -547,6 +1017,12 @@ Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; + Service srv={0}, *srv_ptr = &srv; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { AccountUid uid; u64 application_id; @@ -554,7 +1030,7 @@ Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - rc = serviceDispatchIn(&g_nsAppManSrv, 503, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 503, in, .out_num_objects = 1, .out_objects = &a->s, .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, @@ -564,6 +1040,7 @@ Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + serviceClose(&srv); return rc; } @@ -574,6 +1051,12 @@ Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; + Service srv={0}, *srv_ptr = &srv; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { s32 inval; u32 pad; @@ -583,7 +1066,7 @@ Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - rc = serviceDispatchIn(&g_nsAppManSrv, 504, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 504, in, .out_num_objects = 1, .out_objects = &a->s, .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, @@ -593,6 +1076,7 @@ Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + serviceClose(&srv); return rc; } @@ -600,78 +1084,77 @@ Result nsGetGameCardMountFailureEvent(Event* out_event) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 505); + return _nsManCmdGetEvent(out_event, false, 505); } Result nsIsGameCardInserted(bool *out) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoInOutBool(&g_nsAppManSrv, out, 506); + return _nsManCmdNoInOutBool(out, 506); } Result nsEnsureGameCardAccess(void) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoIO(&g_nsAppManSrv, 507); + return _nsManCmdNoIO(507); } Result nsGetLastGameCardMountFailureResult(void) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoIO(&g_nsAppManSrv, 508); + return _nsManCmdNoIO(508); } Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total_out) { if (hosversionBefore(5,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchOut(&g_nsAppManSrv, 509, *total_out, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 509, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { application_ids, count*sizeof(u64) } }, ); -} -Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount) { - if (hosversionBefore(2,0,0)) - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - - const struct { - s32 index; - u32 pad; - u64 application_id; - } in = { index, 0, application_id }; - - return serviceDispatchInOut(&g_nsAppManSrv, 601, in, *out_entrycount, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } }, - ); + serviceClose(&srv); + return rc; } Result nsTouchApplication(u64 application_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64(&g_nsAppManSrv, application_id, 904); + return _nsManCmdInU64(application_id, 904); } Result nsIsApplicationUpdateRequested(u64 application_id, bool *flag, u32 *out) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + struct { u8 flag; u8 pad[3]; u32 out; } tmpout; - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 906, application_id, tmpout); + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 906, application_id, tmpout); if (R_SUCCEEDED(rc)) { if (flag) *flag = tmpout.flag & 1; if (out) *out = tmpout.out; } + + serviceClose(&srv); return rc; } @@ -679,10 +1162,17 @@ Result nsWithdrawApplicationUpdateRequest(u64 application_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64(&g_nsAppManSrv, application_id, 907); + return _nsManCmdInU64(application_id, 907); } static Result _nsRequestVerifyApplicationDeprecated(NsProgressAsyncResult *a, u64 application_id, TransferMemory *tmem) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + const struct { u64 application_id; u64 size; @@ -690,7 +1180,7 @@ static Result _nsRequestVerifyApplicationDeprecated(NsProgressAsyncResult *a, u6 memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, 1000, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(srv_ptr, 1000, in, .in_num_handles = 1, .in_handles = { tmem->handle }, .out_num_objects = 1, @@ -701,10 +1191,15 @@ static Result _nsRequestVerifyApplicationDeprecated(NsProgressAsyncResult *a, u6 if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + + serviceClose(&srv); return rc; } static Result _nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 application_id, u32 unk, TransferMemory *tmem) { // [5.0.0+] + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u32 unk; u32 pad; @@ -714,7 +1209,7 @@ static Result _nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 applicat memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, 1003, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 1003, in, .in_num_handles = 1, .in_handles = { tmem->handle }, .out_num_objects = 1, @@ -725,6 +1220,8 @@ static Result _nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 applicat if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + + serviceClose(&srv); return rc; } @@ -732,9 +1229,12 @@ Result nsRequestVerifyAddOnContentsRights(NsProgressAsyncResult *a, u64 applicat if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, 1002, application_id, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 1002, application_id, .out_num_objects = 1, .out_objects = &a->s, .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, @@ -743,6 +1243,8 @@ Result nsRequestVerifyAddOnContentsRights(NsProgressAsyncResult *a, u64 applicat if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + + serviceClose(&srv); return rc; } @@ -766,9 +1268,18 @@ Result nsIsAnyApplicationEntityInstalled(u64 application_id, bool *out) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetApplicationManagerInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + u8 tmp=0; - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 1300, application_id, tmp); + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 1300, application_id, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + + serviceClose(&srv); return rc; } @@ -776,40 +1287,49 @@ Result nsCleanupUnavailableAddOnContents(u64 application_id, AccountUid uid) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u64 application_id; AccountUid uid; } in = { application_id, uid }; - return serviceDispatchIn(&g_nsAppManSrv, 1309, in); + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 1309, in); + + serviceClose(&srv); + return rc; } Result nsFormatSdCard(void) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoIO(&g_nsAppManSrv, 1500); + return _nsManCmdNoIO(1500); } Result nsNeedsSystemUpdateToFormatSdCard(bool *out) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoInOutBool(&g_nsAppManSrv, out, 1501); + return _nsManCmdNoInOutBool(out, 1501); } Result nsGetLastSdCardFormatUnexpectedResult(void) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdNoIO(&g_nsAppManSrv, 1502); + return _nsManCmdNoIO(1502); } Result nsGetApplicationView(NsApplicationView *views, const u64 *application_ids, s32 count) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatch(&g_nsAppManSrv, 1701, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatch(&srv, 1701, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -819,23 +1339,35 @@ Result nsGetApplicationView(NsApplicationView *views, const u64 *application_ids { application_ids, count*sizeof(u64) }, }, ); + + serviceClose(&srv); + return rc; } Result nsGetApplicationViewDownloadErrorContext(u64 application_id, ErrorContext *context) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchIn(&g_nsAppManSrv, 1703, application_id, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 1703, application_id, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { context, sizeof(*context) } }, ); + + serviceClose(&srv); + return rc; } Result nsGetApplicationViewWithPromotionInfo(NsApplicationViewWithPromotionInfo *out, const u64 *application_ids, s32 count) { if (hosversionBefore(8,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatch(&g_nsAppManSrv, 1704, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatch(&srv, 1704, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -845,6 +1377,9 @@ Result nsGetApplicationViewWithPromotionInfo(NsApplicationViewWithPromotionInfo { application_ids, count*sizeof(u64) }, }, ); + + serviceClose(&srv); + return rc; } Result nsRequestDownloadApplicationPrepurchasedRights(AsyncResult *a, u64 application_id) { @@ -854,24 +1389,33 @@ Result nsRequestDownloadApplicationPrepurchasedRights(AsyncResult *a, u64 applic Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 1901); + return _nsManCmdInU64OutAsyncResult(a, application_id, 1901); } Result nsGetSystemDeliveryInfo(NsSystemDeliveryInfo *info) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatch(&g_nsAppManSrv, 2000, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatch(&srv, 2000, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { info, sizeof(*info) } }, ); + + serviceClose(&srv); + return rc; } Result nsSelectLatestSystemDeliveryInfo(const NsSystemDeliveryInfo *sys_list, s32 sys_count, const NsSystemDeliveryInfo *base_info, const NsApplicationDeliveryInfo *app_list, s32 app_count, s32 *index) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchOut(&g_nsAppManSrv, 2001, *index, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2001, *index, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -883,44 +1427,64 @@ Result nsSelectLatestSystemDeliveryInfo(const NsSystemDeliveryInfo *sys_list, s3 { app_list, app_count*sizeof(NsApplicationDeliveryInfo) }, }, ); + + serviceClose(&srv); + return rc; } Result nsVerifyDeliveryProtocolVersion(const NsSystemDeliveryInfo *info) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatch(&g_nsAppManSrv, 2002, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatch(&srv, 2002, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { info, sizeof(*info) } }, ); + + serviceClose(&srv); + return rc; } Result nsGetApplicationDeliveryInfo(NsApplicationDeliveryInfo *info, s32 count, u64 application_id, u32 attr, s32 *total_out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u32 attr; u32 pad; u64 application_id; } in = { attr, 0, application_id }; - return serviceDispatchInOut(&g_nsAppManSrv, 2003, in, *total_out, + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2003, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { info, count*sizeof(NsApplicationDeliveryInfo) } }, ); + + serviceClose(&srv); + return rc; } Result nsHasAllContentsToDeliver(const NsApplicationDeliveryInfo *info, s32 count, bool *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + u8 tmp=0; - Result rc = serviceDispatchOut(&g_nsAppManSrv, 2004, tmp, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2004, tmp, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { info, count*sizeof(NsApplicationDeliveryInfo) } }, ); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + + serviceClose(&srv); return rc; } @@ -928,7 +1492,10 @@ Result nsCompareApplicationDeliveryInfo(const NsApplicationDeliveryInfo *info0, if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchOut(&g_nsAppManSrv, 2005, out, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2005, out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -938,14 +1505,20 @@ Result nsCompareApplicationDeliveryInfo(const NsApplicationDeliveryInfo *info0, { info1, count1*sizeof(NsApplicationDeliveryInfo) }, }, ); + + serviceClose(&srv); + return rc; } Result nsCanDeliverApplication(const NsApplicationDeliveryInfo *info0, s32 count0, const NsApplicationDeliveryInfo *info1, s32 count1, bool *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + u8 tmp=0; - Result rc = serviceDispatchOut(&g_nsAppManSrv, 2006, tmp, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2006, tmp, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -956,6 +1529,8 @@ Result nsCanDeliverApplication(const NsApplicationDeliveryInfo *info0, s32 count }, ); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + + serviceClose(&srv); return rc; } @@ -963,7 +1538,10 @@ Result nsListContentMetaKeyToDeliverApplication(NcmContentMetaKey *meta, s32 met if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_nsAppManSrv, 2007, meta_index, *total_out, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2007, meta_index, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -973,14 +1551,20 @@ Result nsListContentMetaKeyToDeliverApplication(NcmContentMetaKey *meta, s32 met { info, info_count*sizeof(NsApplicationDeliveryInfo) }, }, ); + + serviceClose(&srv); + return rc; } Result nsNeedsSystemUpdateToDeliverApplication(const NsApplicationDeliveryInfo *info, s32 count, const NsSystemDeliveryInfo *sys_info, bool *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + u8 tmp=0; - Result rc = serviceDispatchOut(&g_nsAppManSrv, 2008, tmp, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2008, tmp, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -991,6 +1575,8 @@ Result nsNeedsSystemUpdateToDeliverApplication(const NsApplicationDeliveryInfo * }, ); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + + serviceClose(&srv); return rc; } @@ -998,16 +1584,25 @@ Result nsEstimateRequiredSize(const NcmContentMetaKey *meta, s32 count, s64 *out if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchOut(&g_nsAppManSrv, 2009, *out, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2009, *out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { meta, count*sizeof(NcmContentMetaKey) } }, ); + + serviceClose(&srv); + return rc; } Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count, NcmStorageId storage_id) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u8 storage_id; u8 pad; @@ -1019,7 +1614,7 @@ Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 appli memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, 2010, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 2010, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { meta, count*sizeof(NcmContentMetaKey) } }, .out_num_objects = 1, @@ -1031,6 +1626,7 @@ Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 appli if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + serviceClose(&srv); return rc; } @@ -1038,20 +1634,29 @@ Result nsCommitReceiveApplication(u64 application_id) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _nsCmdInU64(&g_nsAppManSrv, application_id, 2011); + return _nsManCmdInU64(application_id, 2011); } Result nsGetReceiveApplicationProgress(u64 application_id, NsReceiveApplicationProgress *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_nsAppManSrv, 2012, application_id, *out); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2012, application_id, *out); + + serviceClose(&srv); + return rc; } Result nsRequestSendApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u16 port; u16 pad2; @@ -1061,7 +1666,7 @@ Result nsRequestSendApplication(AsyncResult *a, u32 addr, u16 port, u64 applicat memset(a, 0, sizeof(*a)); Handle event = INVALID_HANDLE; - Result rc = serviceDispatchIn(&g_nsAppManSrv, 2013, in, + if (R_SUCCEEDED(rc)) rc = serviceDispatchIn(&srv, 2013, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { meta, count*sizeof(NcmContentMetaKey) } }, .out_num_objects = 1, @@ -1073,6 +1678,7 @@ Result nsRequestSendApplication(AsyncResult *a, u32 addr, u16 port, u64 applicat if (R_SUCCEEDED(rc)) eventLoadRemote(&a->event, event, false); + serviceClose(&srv); return rc; } @@ -1080,14 +1686,23 @@ Result nsGetSendApplicationProgress(u64 application_id, NsSendApplicationProgres if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_nsAppManSrv, 2014, application_id, *out); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2014, application_id, *out); + + serviceClose(&srv); + return rc; } Result nsCompareSystemDeliveryInfo(const NsSystemDeliveryInfo *info0, const NsSystemDeliveryInfo *info1, s32 *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchOut(&g_nsAppManSrv, 2015, out, + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2015, out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -1097,34 +1712,48 @@ Result nsCompareSystemDeliveryInfo(const NsSystemDeliveryInfo *info0, const NsSy { info1, sizeof(*info1) }, }, ); + + serviceClose(&srv); + return rc; } Result nsListNotCommittedContentMeta(NcmContentMetaKey *meta, s32 count, u64 application_id, s32 unk, s32 *total_out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { s32 unk; u32 pad; u64 application_id; } in = { unk, 0, application_id }; - return serviceDispatchInOut(&g_nsAppManSrv, 2016, in, *total_out, + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2016, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { meta, count*sizeof(NcmContentMetaKey) } }, ); + + serviceClose(&srv); + return rc; } Result nsGetApplicationDeliveryInfoHash(const NsApplicationDeliveryInfo *info, s32 count, u8 *out_hash) { if (hosversionBefore(5,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + u8 tmp[0x20]; - Result rc = serviceDispatchOut(&g_nsAppManSrv, 2018, tmp, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2018, tmp, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { info, count*sizeof(NsApplicationDeliveryInfo) } }, ); if (R_SUCCEEDED(rc) && out_hash) memcpy(out_hash, tmp, sizeof(tmp)); + + serviceClose(&srv); return rc; } @@ -1132,13 +1761,22 @@ Result nsGetApplicationTerminateResult(u64 application_id, Result *res) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_nsAppManSrv, 2100, application_id, *res); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2100, application_id, *res); + + serviceClose(&srv); + return rc; } Result nsGetApplicationRightsOnClient(NsApplicationRightsOnClient *rights, s32 count, u64 application_id, AccountUid uid, u32 flags, s32 *total_out) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + const struct { u32 flags; u32 pad; @@ -1146,10 +1784,13 @@ Result nsGetApplicationRightsOnClient(NsApplicationRightsOnClient *rights, s32 c AccountUid uid; } in = { flags, 0, application_id, uid }; - return serviceDispatchInOut(&g_nsAppManSrv, 2050, in, *total_out, + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(&srv, 2050, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { rights, count*sizeof(NsApplicationRightsOnClient) } }, ); + + serviceClose(&srv); + return rc; } Result nsRequestNoDownloadRightsErrorResolution(AsyncValue *a, u64 application_id) { @@ -1159,7 +1800,7 @@ Result nsRequestNoDownloadRightsErrorResolution(AsyncValue *a, u64 application_i Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 2351); + return _nsManCmdInU64OutAsyncValue(a, application_id, 2351); } Result nsRequestResolveNoDownloadRightsError(AsyncValue *a, u64 application_id) { @@ -1169,16 +1810,19 @@ Result nsRequestResolveNoDownloadRightsError(AsyncValue *a, u64 application_id) Result rc = _nsCheckNifm(); if (R_FAILED(rc)) return rc; - return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 2352); + return _nsManCmdInU64OutAsyncValue(a, application_id, 2352); } Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, AccountUid uid) { if (hosversionBefore(8,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + Service srv={0}; + Result rc = nsGetApplicationManagerInterface(&srv); + // These are arrays, but official sw uses hard-coded value 1 for array-count. - return serviceDispatch(&g_nsAppManSrv, 2400, + if (R_SUCCEEDED(rc)) rc = serviceDispatch(&srv, 2400, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -1190,6 +1834,266 @@ Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, Accoun { &uid, sizeof(AccountUid) }, }, ); + + serviceClose(&srv); + return rc; +} + +// IDownloadTaskInterface + +Result nsClearTaskStatusList(void) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetDownloadTaskInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 701); + + serviceClose(&srv); + return rc; +} + +Result nsRequestDownloadTaskList(void) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetDownloadTaskInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 702); + + serviceClose(&srv); + return rc; +} + +Result nsRequestEnsureDownloadTask(AsyncResult *a) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetDownloadTaskInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutAsyncResult(srv_ptr, a, 703); + + serviceClose(&srv); + return rc; +} + +Result nsListDownloadTaskStatus(NsDownloadTaskStatus* tasks, s32 count, s32 *total_out) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetDownloadTaskInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(srv_ptr, 704, *total_out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { tasks, count*sizeof(NsDownloadTaskStatus) } }, + ); + + + serviceClose(&srv); + return rc; +} + +Result nsRequestDownloadTaskListData(AsyncValue *a) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetDownloadTaskInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutAsyncValue(srv_ptr, a, 705); + + serviceClose(&srv); + return rc; +} + +Result nsTryCommitCurrentApplicationDownloadTask(void) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetDownloadTaskInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 706); + + serviceClose(&srv); + return rc; +} + +Result nsEnableAutoCommit(void) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetDownloadTaskInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 707); + + serviceClose(&srv); + return rc; +} + +Result nsDisableAutoCommit(void) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetDownloadTaskInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 708); + + serviceClose(&srv); + return rc; +} + +Result nsTriggerDynamicCommitEvent(void) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetDownloadTaskInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&srv, 709); + + serviceClose(&srv); + return rc; +} + +// IContentManagementInterface + +Result nsCalculateApplicationOccupiedSize(u64 application_id, NsApplicationOccupiedSize *out) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 11, application_id, *out); + + serviceClose(&srv); + return rc; +} + +Result nsCheckSdCardMountStatus(void) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 43); + + serviceClose(&srv); + return rc; +} + +Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutU64(srv_ptr, storage_id, (u64*)size, 47); + + serviceClose(&srv); + return rc; +} + +Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutU64(srv_ptr, storage_id, (u64*)size, 48); + + serviceClose(&srv); + return rc; +} + +Result nsCountApplicationContentMeta(u64 application_id, s32 *out) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 600, application_id, *out); + + serviceClose(&srv); + return rc; +} + +Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + const struct { + s32 index; + u32 pad; + u64 application_id; + } in = { index, 0, application_id }; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 601, in, *out_entrycount, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } }, + ); + + serviceClose(&srv); + return rc; +} + +Result nsIsAnyApplicationRunning(bool *out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetContentManagementInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutBool(&srv, out, 607); + + serviceClose(&srv); + return rc; } // IRequestServerStopper diff --git a/nx/source/services/pl.c b/nx/source/services/pl.c index b8f9187c..9e33e77b 100644 --- a/nx/source/services/pl.c +++ b/nx/source/services/pl.c @@ -29,8 +29,6 @@ Result _plInitialize(void) { } } - if (R_FAILED(rc)) plExit(); - return rc; } diff --git a/nx/source/services/tc.c b/nx/source/services/tc.c new file mode 100644 index 00000000..dae85f88 --- /dev/null +++ b/nx/source/services/tc.c @@ -0,0 +1,47 @@ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include +#include "service_guard.h" +#include "runtime/hosversion.h" +#include "services/tc.h" + +static Service g_tcSrv; + +NX_GENERATE_SERVICE_GUARD(tc); + +Result _tcInitialize(void) { + return smGetService(&g_tcSrv, "tc"); +} + +void _tcCleanup(void) { + serviceClose(&g_tcSrv); +} + +Service* tcGetServiceSession(void) { + return &g_tcSrv; +} + +static Result _tcNoInNoOut(u32 cmd_id) { + return serviceDispatch(&g_tcSrv, cmd_id); +} + +Result tcEnableFanControl(void) { + return _tcNoInNoOut(6); +} + +Result tcDisableFanControl(void) { + return _tcNoInNoOut(7); +} + +Result tcIsFanControlEnabled(bool *status) { + u8 tmp=0; + Result rc = serviceDispatchOut(&g_tcSrv, 8, tmp); + if (R_SUCCEEDED(rc) && status) *status = tmp & 1; + return rc; +} + +Result tcGetSkinTemperatureMilliC(s32 *skinTemp) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return serviceDispatchOut(&g_tcSrv, 9, *skinTemp); +}