mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 04:22:50 +02:00
Added support for NsProgressAsyncResult and nsRequestVerifyAddOnContentsRights/nsRequestVerifyApplication. Updated docs.
This commit is contained in:
parent
d8a50a46cf
commit
129b3a95b8
@ -64,6 +64,7 @@ Result asyncValueCancel(AsyncValue *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the \ref ErrorContext.
|
||||
* @note Only available on [4.0.0+].
|
||||
* @param a \ref AsyncValue
|
||||
* @param[out] context \ref ErrorContext
|
||||
*/
|
||||
@ -104,6 +105,7 @@ Result asyncResultCancel(AsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the \ref ErrorContext.
|
||||
* @note Only available on [4.0.0+].
|
||||
* @param a \ref AsyncResult
|
||||
* @param[out] context \ref ErrorContext
|
||||
*/
|
||||
|
@ -51,6 +51,12 @@ typedef struct {
|
||||
Service s; ///< IRequestServerStopper
|
||||
} NsRequestServerStopper;
|
||||
|
||||
/// ProgressAsyncResult
|
||||
typedef struct {
|
||||
Service s; ///< IProgressAsyncResult
|
||||
Event event; ///< Event with autoclear=false.
|
||||
} NsProgressAsyncResult;
|
||||
|
||||
/// SystemUpdateControl
|
||||
typedef struct {
|
||||
Service s; ///< ISystemUpdateControl
|
||||
@ -120,7 +126,7 @@ typedef struct {
|
||||
u64 end_timestamp; ///< POSIX timestamp for the promotion end.
|
||||
s64 remaining_time; ///< Remaining time until the promotion ends, in nanoseconds ({end_timestamp - current_time} converted to nanoseconds).
|
||||
u8 unk_x18[0x4]; ///< Not set, left at zero.
|
||||
u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear: remaining_time is set.
|
||||
u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear: remaining_time is set.
|
||||
u8 pad[3]; ///< Padding.
|
||||
} NsPromotionInfo;
|
||||
|
||||
@ -572,6 +578,25 @@ Result nsIsApplicationUpdateRequested(u64 application_id, bool *flag, u32 *out);
|
||||
*/
|
||||
Result nsWithdrawApplicationUpdateRequest(u64 application_id);
|
||||
|
||||
/**
|
||||
* @brief RequestVerifyAddOnContentsRights
|
||||
* @note Only available on [3.0.0+].
|
||||
* @param[out] a \ref NsProgressAsyncResult
|
||||
* @param[in] application_id ApplicationId.
|
||||
*/
|
||||
Result nsRequestVerifyAddOnContentsRights(NsProgressAsyncResult *a, u64 application_id);
|
||||
|
||||
/**
|
||||
* @brief RequestVerifyApplication
|
||||
* @note On pre-5.0.0 this uses cmd RequestVerifyApplicationDeprecated, otherwise cmd RequestVerifyApplication is used.
|
||||
* @param[out] a \ref NsProgressAsyncResult. The data available with \ref nsProgressAsyncResultGetProgress is basically the same as \ref NsSystemUpdateProgress.
|
||||
* @param[in] application_id ApplicationId.
|
||||
* @param[in] unk Unknown. A default value of 0x7 can be used (which is what qlaunch uses). Only used on [5.0.0+].
|
||||
* @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes.
|
||||
* @param[in] size 0x1000-byte aligned buffer size for TransferMemory. qlaunch uses size 0x100000.
|
||||
*/
|
||||
Result nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 application_id, u32 unk, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief IsAnyApplicationEntityInstalled
|
||||
* @note Only available on [2.0.0+].
|
||||
@ -881,6 +906,61 @@ void nsRequestServerStopperClose(NsRequestServerStopper *r);
|
||||
|
||||
///@}
|
||||
|
||||
///@name IProgressAsyncResult
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Close a \ref NsProgressAsyncResult.
|
||||
* @note When the object is initialized, this uses \ref nsProgressAsyncResultCancel then \ref nsProgressAsyncResultWait with timeout=U64_MAX.
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
*/
|
||||
void nsProgressAsyncResultClose(NsProgressAsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Waits for the async operation to finish using the specified timeout.
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
* @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout.
|
||||
*/
|
||||
Result nsProgressAsyncResultWait(NsProgressAsyncResult *a, u64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Gets the Result.
|
||||
* @note Prior to using the cmd, this uses \ref nsProgressAsyncResultWait with timeout=U64_MAX.
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
*/
|
||||
Result nsProgressAsyncResultGet(NsProgressAsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Cancels the async operation.
|
||||
* @note Used automatically by \ref nsProgressAsyncResultClose.
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
*/
|
||||
Result nsProgressAsyncResultCancel(NsProgressAsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the progress.
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
* @param[out] buffer Output buffer.
|
||||
* @param[in] size Output buffer size.
|
||||
*/
|
||||
Result nsProgressAsyncResultGetProgress(NsProgressAsyncResult *a, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief GetDetailResult
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
*/
|
||||
Result nsProgressAsyncResultGetDetailResult(NsProgressAsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the \ref ErrorContext.
|
||||
* @note Only available on [4.0.0+].
|
||||
* @param a \ref NsProgressAsyncResult
|
||||
* @param[out] context \ref ErrorContext
|
||||
*/
|
||||
Result nsProgressAsyncResultGetErrorContext(NsProgressAsyncResult *a, ErrorContext *context);
|
||||
|
||||
///@}
|
||||
|
||||
///@name ns:vm
|
||||
///@{
|
||||
|
||||
|
@ -622,6 +622,86 @@ Result nsWithdrawApplicationUpdateRequest(u64 application_id) {
|
||||
return _nsCmdInU64(&g_nsAppManSrv, application_id, 907);
|
||||
}
|
||||
|
||||
static Result _nsRequestVerifyApplicationDeprecated(NsProgressAsyncResult *a, u64 application_id, TransferMemory *tmem) {
|
||||
const struct {
|
||||
u64 application_id;
|
||||
u64 size;
|
||||
} in = { application_id, tmem->size };
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
Handle event = INVALID_HANDLE;
|
||||
Result rc = serviceDispatchIn(&g_nsAppManSrv, 1000, in,
|
||||
.in_num_handles = 1,
|
||||
.in_handles = { tmem->handle },
|
||||
.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 _nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 application_id, u32 unk, TransferMemory *tmem) { // [5.0.0+]
|
||||
const struct {
|
||||
u32 unk;
|
||||
u32 pad;
|
||||
u64 application_id;
|
||||
u64 size;
|
||||
} in = { unk, 0, application_id, tmem->size };
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
Handle event = INVALID_HANDLE;
|
||||
Result rc = serviceDispatchIn(&g_nsAppManSrv, 1003, in,
|
||||
.in_num_handles = 1,
|
||||
.in_handles = { tmem->handle },
|
||||
.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;
|
||||
}
|
||||
|
||||
Result nsRequestVerifyAddOnContentsRights(NsProgressAsyncResult *a, u64 application_id) {
|
||||
if (hosversionBefore(3,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
Handle event = INVALID_HANDLE;
|
||||
Result rc = serviceDispatchIn(&g_nsAppManSrv, 1002, application_id,
|
||||
.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;
|
||||
}
|
||||
|
||||
Result nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 application_id, u32 unk, void* buffer, size_t size) {
|
||||
Result rc=0;
|
||||
TransferMemory tmem={0};
|
||||
|
||||
rc = tmemCreateFromMemory(&tmem, buffer, size, Perm_None);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (hosversionBefore(5,0,0))
|
||||
rc = _nsRequestVerifyApplicationDeprecated(a, application_id, &tmem);
|
||||
else
|
||||
rc = _nsRequestVerifyApplication(a, application_id, unk, &tmem);
|
||||
}
|
||||
tmemClose(&tmem);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nsIsAnyApplicationEntityInstalled(u64 application_id, bool *out) {
|
||||
if (hosversionBefore(2,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
@ -1058,6 +1138,70 @@ void nsRequestServerStopperClose(NsRequestServerStopper *r) {
|
||||
serviceClose(&r->s);
|
||||
}
|
||||
|
||||
// IProgressAsyncResult
|
||||
|
||||
void nsProgressAsyncResultClose(NsProgressAsyncResult *a) {
|
||||
if (serviceIsActive(&a->s)) {
|
||||
nsProgressAsyncResultCancel(a); // Official sw ignores rc from this prior to waiting on the event.
|
||||
nsProgressAsyncResultWait(a, U64_MAX);
|
||||
}
|
||||
|
||||
serviceClose(&a->s);
|
||||
eventClose(&a->event);
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultWait(NsProgressAsyncResult *a, u64 timeout) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return eventWait(&a->event, timeout);
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultGet(NsProgressAsyncResult *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
Result rc = nsProgressAsyncResultWait(a, U64_MAX);
|
||||
if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&a->s, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultCancel(NsProgressAsyncResult *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _nsCmdNoIO(&a->s, 1);
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultGetProgress(NsProgressAsyncResult *a, void* buffer, size_t size) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return serviceDispatch(&a->s, 2,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { buffer, size } },
|
||||
);
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultGetDetailResult(NsProgressAsyncResult *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _nsCmdNoIO(&a->s, 3);
|
||||
}
|
||||
|
||||
Result nsProgressAsyncResultGetErrorContext(NsProgressAsyncResult *a, ErrorContext *context) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(4,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return serviceDispatch(&a->s, 4,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { context, sizeof(*context) } },
|
||||
);
|
||||
}
|
||||
|
||||
// ns:vm
|
||||
|
||||
NX_GENERATE_SERVICE_GUARD(nsvm);
|
||||
|
Loading…
Reference in New Issue
Block a user