NS services: Difference between revisions
No edit summary |
|||
(24 intermediate revisions by the same user not shown) | |||
Line 1,676: | Line 1,676: | ||
Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], no output. | Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], no output. | ||
This validates the [[#SystemDeliveryInfo]] HMAC and the protocol-version fields. Then an error is returned when | This validates the [[#SystemDeliveryInfo]] HMAC and the protocol-version fields. Then an error is returned when SystemUpdateVersion is less than a state field, otherwise 0 is returned (state field originates from [[System_Settings|system-setting]] <code>contents_delivery!required_system_version_to_deliver_application</code>). | ||
==== GetApplicationDeliveryInfo ==== | ==== GetApplicationDeliveryInfo ==== | ||
Takes a type-0x6 output buffer containing an array of [[#ApplicationDeliveryInfo]], an input u32 bitmask <code>nn::ns::ApplicationDeliveryAttributeTag</code>, an [[NCM_services#ApplicationId|ApplicationId]], and returns an output s32 total_out. | Takes a type-0x6 output buffer containing an array of [[#ApplicationDeliveryInfo|ApplicationDeliveryInfo]], an input u32 bitmask <code>nn::ns::ApplicationDeliveryAttributeTag</code>, an [[NCM_services#ApplicationId|ApplicationId]], and returns an output s32 total_out. | ||
An error is thrown if any bit is set in ApplicationDeliveryAttributeTag besides bit1. The output array-count must be at least 1: only 1 entry will be written to this array (hence on success total_out will also only be 1 on success). | [11.0.0+] An error is thrown if LocalContentShare is not [[#IsLocalContentShareEnabled|enabled]]. | ||
An error is thrown if any bit is set in ApplicationDeliveryAttributeTag besides bit1, this must also be <=0x3. The output array-count must be at least 1: only 1 entry will be written to this array (hence on success total_out will also only be 1 on success). | |||
An error is thrown if a state ref-count is zero. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
HasApplicationRecord is called with the input [[NCM_services#ApplicationId|ApplicationId]], an error is returned if the record isn't found. | |||
[[#ApplicationDeliveryInfo|RequiredApplicationVersion]] is initially set to the output version from [[Shared_Database_services|avm]] GetLaunchRequiredVersion. Later when ContentMetaType == Application etc, it calls a func. This func uses [[NCM_services|ncm]] IContentMetaDatabase GetRequiredApplicationVersion. If the output version is higher than the [[#ApplicationDeliveryInfo|RequiredApplicationVersion]] field then the output version is written here. Immediately aferwards, it also checks whether the bit for Compacted is set from [[NCM_services|ncm]] IContentMetaDatabase GetAttributes, clearing [[#ApplicationDeliveryInfo|ApplicationVersion]] if the attribute is set. | |||
[20.0.0+] [[#ApplicationDeliveryInfo|ApplicationDeliveryInfo]] ContentMetaPlatform and ProperProgramExists are now set using data from [[NCM_services|ncm]]. | |||
[20.0.0+] [[Shared_Database_services|pl:s]] GetFunctionBlackListSystemVersionToAuthorize with ApplicationFunctionAuthorizationId=0x5 is now used, the output version is written to [[#ApplicationDeliveryInfo|RequiredSystemVersion]] when it's higher than the value previously written here. | |||
[20.0.0+] [[Shared_Database_services|pl:s]] GetRequiredApplicationVersion with ApplicationFunctionAuthorizationId=0x5 is now used, the output version is written to [[#ApplicationDeliveryInfo|RequiredApplicationVersion]] when it's higher than the value previously written here. | |||
==== HasAllContentsToDeliver ==== | ==== HasAllContentsToDeliver ==== | ||
Takes a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | Takes a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | ||
The array-count must match 1. After validating the [[#ApplicationDeliveryInfo]], the output bool is set to | The array-count must match 1. | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
After validating the [[#ApplicationDeliveryInfo]], the output bool is set to [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] & 0x10000002 != 0x2, then this returns 0. | |||
==== CompareApplicationDeliveryInfo ==== | ==== CompareApplicationDeliveryInfo ==== | ||
Takes two type-0x5 input buffers containing an array of [[#ApplicationDeliveryInfo]], returns an output s32. | Takes two type-0x5 input buffers containing an array of [[#ApplicationDeliveryInfo]], returns an output s32. | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
The array-count for both buffers must be 1, otherwise an error is returned. | The array-count for both buffers must be 1, otherwise an error is returned. | ||
Line 1,698: | Line 1,720: | ||
Takes two type-0x5 input buffers containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | Takes two type-0x5 input buffers containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | ||
The array-count for the second buffer must be 1, otherwise an error is returned. | The array-count for the second buffer must be 1, otherwise an error is returned. | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
The | The second [[#ApplicationDeliveryInfo]] buffer is validated. An error is thrown when [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (second buffer) & 0x3 != 0x2, likewise when bit28 is clear in this field (bitmask 0x10000000). | ||
The array-count for the first buffer must be <=1, otherwise an error is returned. If the array-count for the first buffer is 0, this will return 0 with the output bool set to 0. The first [[#ApplicationDeliveryInfo]] buffer is validated. An error is thrown when [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (first buffer) bit1 is clear or bit0 set. An error is thrown when [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (second buffer) bit1 is clear. | |||
When | When [[#ApplicationDeliveryInfo|RequiredApplicationVersion]] (first or second buffer) is higher than [[#ApplicationDeliveryInfo|ApplicationVersion]] (second buffer), this will return 0 with the output bool set to 0. | ||
* When [[#ApplicationDeliveryInfo]] (first buffer) | |||
When [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (first buffer) bit28 is set (bitmask 0x10000000): | |||
* When [[#ApplicationDeliveryInfo|ApplicationVersion]] (first buffer) >= [[#ApplicationDeliveryInfo|ApplicationVersion]] (second buffer), write 0 to the output bool, otherwise write 1. Then return 0. | |||
Otherwise when the above bit28 is clear: | Otherwise when the above bit28 is clear: | ||
* When [[#ApplicationDeliveryInfo]] (first buffer) | * When [[#ApplicationDeliveryInfo|ApplicationVersion]] (first buffer) > [[#ApplicationDeliveryInfo|ApplicationVersion]] (second buffer), write 0 to the output bool, otherwise write 1. Then return 0. | ||
==== ListContentMetaKeyToDeliverApplication ==== | ==== ListContentMetaKeyToDeliverApplication ==== | ||
Takes a type-0x6 output buffer containing an array of [[NCM_services#ContentMetaKey|ContentMetaKey]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], a s32, and returns an output s32 total_out. | Takes a type-0x6 output buffer containing an array of [[NCM_services#ContentMetaKey|ContentMetaKey]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], a s32, and returns an output s32 total_out. | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
The array-count for ContentMetaKey must be at least 1, and for ApplicationDeliveryInfo it must match 1. | The array-count for ContentMetaKey must be at least 1, and for ApplicationDeliveryInfo it must match 1. | ||
This will only return 1 ContentMetaKey entry. This will not output the entry when the input s32 is larger than 0 | The [[#ApplicationDeliveryInfo|ApplicationDeliveryInfo]] is validated (ApplicationDeliveryProtocolVersion/HMAC). An error is thrown when [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] bit0 is set. | ||
This uses the same ref-count check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
This will only return 1 ContentMetaKey entry. This will not output the entry when the input s32 is larger than 0, or when [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] bit1 is clear. | |||
==== NeedsSystemUpdateToDeliverApplication ==== | ==== NeedsSystemUpdateToDeliverApplication ==== | ||
Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], and returns an output u8 bool. | Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], and returns an output u8 bool. | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
The array-count must match 1. | The array-count must match 1. | ||
Line 1,728: | Line 1,764: | ||
* When the SystemDeliveryInfoPlatform from the input [[#SystemDeliveryInfo]] matches the [[System_Settings|sys-setting]], it does the following: | * When the SystemDeliveryInfoPlatform from the input [[#SystemDeliveryInfo]] matches the [[System_Settings|sys-setting]], it does the following: | ||
* Calls the same func as [[#SelectLatestSystemDeliveryInfo]] for GetFunctionBlackListSystemVersionToAuthorize, returning the Result on failure. | * Calls the same func as [[#SelectLatestSystemDeliveryInfo]] for GetFunctionBlackListSystemVersionToAuthorize, returning the Result on failure. | ||
* The output bool is set to: out_u8!=0 && out_u32 >= [[#SystemDeliveryInfo]] | * The output bool is set to: out_u8!=0 && out_u32 >= [[#SystemDeliveryInfo]] SystemUpdateVersion (only the upper 16bits are used from the SystemUpdateVersion). | ||
==== EstimateRequiredSize ==== | ==== EstimateRequiredSize ==== | ||
Line 1,740: | Line 1,776: | ||
[[qlaunch]] uses value Any for the StorageId, and value 55556 for the port. | [[qlaunch]] uses value Any for the StorageId, and value 55556 for the port. | ||
This uses the same LocalContentShare and ref-count checks as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
HasApplicationRecord is called with the input [[NCM_services#ApplicationId|ApplicationId]], an error is returned if the record isn't found. | |||
This loops through the input [[NCM_services#ContentMetaKey|ContentMetaKey]] array, throwing an error if the [[NCM_services#ContentMetaType|ContentMetaType]] doesn't match Patch. The input array is copied into state which is used later by the thread for [[NIM_services|nim]] | This loops through the input [[NCM_services#ContentMetaKey|ContentMetaKey]] array, throwing an error if the [[NCM_services#ContentMetaType|ContentMetaType]] doesn't match Patch. The input array is copied into state which is used later by the thread for [[NIM_services|nim]] CreateLocalCommunicationReceiveApplicationTask, max entries is 0x12. | ||
This does various setup then creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. Then the thread does: | This does various setup then creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. Then the thread does: | ||
Line 1,748: | Line 1,788: | ||
* Calls a func which does: | * Calls a func which does: | ||
** Throws an error if a state flag is set. | ** Throws an error if a state flag is set. | ||
** Uses [[NIM_services|nim]] | ** Uses [[NIM_services|nim]] CreateLocalCommunicationReceiveApplicationTask, returning the Result on failure. | ||
** Uses [[NIM_services|nim]] | ** Uses [[NIM_services|nim]] RequestLocalCommunicationReceiveApplicationTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ||
*** When the Result from Get is an error, a func is called for filling in the [[#IAsyncResult|IAsyncResult]] ErrorContext with Type4. | |||
** Handles cleanup and returns. | ** Handles cleanup and returns. | ||
* On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | * On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | ||
** The EventId is "receive_app_contents" with ApplicationId <NS ProgramId>. | ** The EventId is "receive_app_contents" with ApplicationId <NS ProgramId>. | ||
** This report has the following fields: | |||
*** "ApplicationId" | |||
*** "DestinationVersion" | |||
*** "SourceVersion" | |||
*** "HasApplicationEntity" | |||
*** "HasPatchEntity" | |||
*** "ApplicationStorageId" | |||
*** "PatchStorageId" | |||
*** "Size" | |||
*** "ThroughputKBps" | |||
==== CommitReceiveApplication ==== | ==== CommitReceiveApplication ==== | ||
Takes an input [[NCM_services#ApplicationId|ApplicationId]], no output. | Takes an input [[NCM_services#ApplicationId|ApplicationId]], no output. | ||
This uses the same LocalContentShare and ref-count checks as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
==== GetReceiveApplicationProgress ==== | ==== GetReceiveApplicationProgress ==== | ||
Takes an input [[NCM_services#ApplicationId|ApplicationId]], returns an output [[#ReceiveApplicationProgress]]. | Takes an input [[NCM_services#ApplicationId|ApplicationId]], returns an output [[#ReceiveApplicationProgress]]. | ||
This uses the same ref-count check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
Uses [[NIM_services|nim]] | Uses [[NIM_services|nim]] ListApplicationLocalCommunicationReceiveApplicationTask, throwing an error if no task is returned. Then [[NIM_services|nim]] GetLocalCommunicationReceiveApplicationTaskInfo is used, returning the error from there on failure. Lastly, this writes the 0x10-bytes from output+8 from the latter cmd to the output [[#ReceiveApplicationProgress]], and returns 0. | ||
==== RequestSendApplication ==== | ==== RequestSendApplication ==== | ||
Line 1,769: | Line 1,826: | ||
[[qlaunch]] uses value 55556 for the port. | [[qlaunch]] uses value 55556 for the port. | ||
This uses the same LocalContentShare and ref-count checks as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
The [[NCM_services#ContentMetaType|ContentMetaType]] must match Patch. | The [[NCM_services#ContentMetaType|ContentMetaType]] in the ContentMetaKey must match Patch. | ||
This does various setup and | This does various setup and loops through the input ContentMetaKey array for initializing the array passed to the nim cmd during the async task. This then creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. Then the thread does: | ||
* Calls a func which does: | * Calls a func which does: | ||
** Throws an error if a state flag is set. | ** Throws an error if a state flag is set. | ||
** Uses [[NIM_services|nim]] | ** Uses [[NIM_services|nim]] CreateLocalCommunicationSendApplicationTask, returning the Result on failure. | ||
** Uses [[NIM_services|nim]] | ** Uses [[NIM_services|nim]] RequestLocalCommunicationSendApplicationTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ||
*** When the Result from Get is an error, a func is called for filling in the [[#IAsyncResult|IAsyncResult]] ErrorContext with Type4. | |||
** Handles cleanup and returns. | ** Handles cleanup and returns. | ||
* On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | * On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | ||
** The EventId is "send_app_contents" with ApplicationId <NS ProgramId>. | ** The EventId is "send_app_contents" with ApplicationId <NS ProgramId>. | ||
** This report has the following fields: | |||
*** "ApplicationId" | |||
*** "Version" | |||
*** "ApplicationStorageId" | |||
*** "PatchStorageId" | |||
==== GetSendApplicationProgress ==== | ==== GetSendApplicationProgress ==== | ||
Takes an input [[NCM_services#ApplicationId|ApplicationId]], returns an output [[#SendApplicationProgress]]. | Takes an input [[NCM_services#ApplicationId|ApplicationId]], returns an output [[#SendApplicationProgress]]. | ||
Same as [[#GetReceiveApplicationProgress]] except this is the Send version, and uses [[NIM_services|nim]] | Same as [[#GetReceiveApplicationProgress]] except this is the Send version, and uses [[NIM_services|nim]] ListApplicationLocalCommunicationSendApplicationTask/GetLocalCommunicationSendApplicationTaskInfo instead. The data copied to output is also swapped: u64 nim_out+0x8 is copied to out+0x8, and u64 nim_out+0x10 is copied to out+0x0. | ||
==== CompareSystemDeliveryInfo ==== | ==== CompareSystemDeliveryInfo ==== | ||
Line 1,795: | Line 1,860: | ||
==== ListNotCommittedContentMeta ==== | ==== ListNotCommittedContentMeta ==== | ||
Takes a type-0x6 output buffer containing an array of [[NCM_services#ContentMetaKey|ContentMetaKey]], a s32, an [[NCM_services#ApplicationId|ApplicationId]], returns an output s32 total_out. | Takes a type-0x6 output buffer containing an array of [[NCM_services#ContentMetaKey|ContentMetaKey]], a s32, an [[NCM_services#ApplicationId|ApplicationId]], returns an output s32 total_out. | ||
This uses the same ref-count check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | |||
==== RecoverDownloadTask ==== | ==== RecoverDownloadTask ==== | ||
Takes a type-0x5 input buffer containing an array of {unknown} and an input u64, no output. | Takes a type-0x5 input buffer containing an array of {unknown} and an input u64, no output. | ||
This uses the same LocalContentShare and ref-count checks as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | |||
==== GetApplicationDeliveryInfoHash ==== | ==== GetApplicationDeliveryInfoHash ==== | ||
Takes a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output 0x20-byte SHA256 hash. | Takes a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output 0x20-byte SHA256 hash. | ||
This extracts data from the input array for hashing with SHA256, with validation being done when handling each entry. | This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | ||
This extracts data from the input array for hashing with SHA256, with validation being done when handling each entry (ApplicationDeliveryProtocolVersion/HMAC). | |||
The 0x14-bytes from [[#ApplicationDeliveryInfo|ApplicationDeliveryInfo]]+0x8 are copied into a 0x18-byte struct entry in an array buffer, with the last 4-bytes being cleared. Then each 0x18-byte struct entry is hashed. | |||
==== Cmd2019 ==== | ==== Cmd2019 ==== | ||
Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | Takes a type-0x15 input buffer containing a [[#SystemDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], a type-0x5 input buffer containing an array of [[#ApplicationDeliveryInfo]], returns an output u8 bool. | ||
This is essentially an extended version of [[#CanDeliverApplication|CanDeliverApplication]], with additional functionality for determining platform compatibility. | |||
This calls a func for validating the [[#SystemDeliveryInfo]] from the type-0x15 buffer, returning the Result on failure. | This calls a func for validating the [[#SystemDeliveryInfo]] from the type-0x15 buffer, returning the Result on failure. | ||
Line 1,814: | Line 1,891: | ||
* When the SystemDeliveryInfoPlatform from the input [[#SystemDeliveryInfo]] matches the [[System_Settings|sys-setting]], it does the following: | * When the SystemDeliveryInfoPlatform from the input [[#SystemDeliveryInfo]] matches the [[System_Settings|sys-setting]], it does the following: | ||
** Uses [[Shared_Database_services|pl:s]] RequestApplicationFunctionAuthorizationByApplicationId with the [[#ApplicationDeliveryInfo]] ApplicationId/ApplicationVersion and ApplicationFunctionAuthorizationId=0x5, handling the Result on failure. | ** Uses [[Shared_Database_services|pl:s]] RequestApplicationFunctionAuthorizationByApplicationId with the [[#ApplicationDeliveryInfo]] ApplicationId/ApplicationVersion and ApplicationFunctionAuthorizationId=0x5, handling the Result on failure. | ||
* When the | * When the platform fields from the input [[#SystemDeliveryInfo]]/[[#ApplicationDeliveryInfo]] match, write 1 to the output bool and return 0. Otherwise: | ||
** When the [[#SystemDeliveryInfo]] SystemDeliveryInfoPlatform is 0x1 (Ounce): *output = | ** When the [[#SystemDeliveryInfo]] SystemDeliveryInfoPlatform is 0x1 (Ounce): *output = [[#ApplicationDeliveryInfo|ContentMetaPlatform]] == 0 && [[#ApplicationDeliveryInfo|ProperProgramExists]] == 0; | ||
** When the [[#SystemDeliveryInfo]] SystemDeliveryInfoPlatform is 0x0 (NX): write 0 to the output bool and return 0. | ** When the [[#SystemDeliveryInfo]] SystemDeliveryInfoPlatform is 0x0 (NX): write 0 to the output bool and return 0. | ||
** Otherwise, Abort. | ** Otherwise, Abort. | ||
Line 1,939: | Line 2,016: | ||
No input, returns an output bool. | No input, returns an output bool. | ||
Various Deliver cmds now | Various Deliver cmds now run essentially the same code as IsLocalContentShareEnabled, with an error being returned when it's not enabled. | ||
==== Cmd4026 ==== | ==== Cmd4026 ==== | ||
Line 2,653: | Line 2,730: | ||
== OpenSystemUpdateControl == | == OpenSystemUpdateControl == | ||
No input, returns an [[#ISystemUpdateControl]]. | No input, returns an [[#ISystemUpdateControl]]. | ||
Only 1 ISystemUpdateControl can be open at a time. | |||
== NotifyExFatDriverRequired == | == NotifyExFatDriverRequired == | ||
Line 2,712: | Line 2,791: | ||
See [[NIM_services|nim]] regarding the input addr/port usage, etc. | See [[NIM_services|nim]] regarding the input addr/port usage, etc. | ||
This validates the [[#SystemDeliveryInfo]] and generates a [[NCM_services#ContentMetaKey|ContentMetaKey]] from that, and creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. Then the thread does: | [11.0.0+] An error is thrown if LocalContentShare is not [[#IsLocalContentShareEnabled|enabled]]. | ||
This validates the [[#SystemDeliveryInfo]] and generates a [[NCM_services#ContentMetaKey|ContentMetaKey]] from that, and creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. | |||
The above validation verifies that the HMAC and SystemDeliveryProtocolVersion are valid. The OldSystemUpdateId ([20.0.0+] SystemUpdateId, SystemUpdateIdFlag ignored) must match the Id for the installed SystemUpdate as returned by [[NCM_services|ncm]]. | |||
Then the thread does: | |||
* Calls a func which does: | * Calls a func which does: | ||
** Uses [[NIM_services|nim]] CreateLocalCommunicationSendSystemUpdateTask, returning the Result on failure. | ** Uses [[NIM_services|nim]] CreateLocalCommunicationSendSystemUpdateTask, returning the Result on failure. | ||
*** The input firmware_variation is from the [[#SystemDeliveryInfo|FirmwareVariationId]]. | |||
** Uses [[NIM_services|nim]] RequestLocalCommunicationSendSystemUpdateTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ** Uses [[NIM_services|nim]] RequestLocalCommunicationSendSystemUpdateTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ||
*** When the Result from Get is an error, a func is called for filling in the [[#IAsyncResult|IAsyncResult]] ErrorContext with Type4. | |||
** Handles cleanup and returns. | ** Handles cleanup and returns. | ||
* Unlike [[#RequestReceiveSystemUpdate]], this doesn't save a SystemPlayReport. | * Unlike [[#RequestReceiveSystemUpdate]], this doesn't save a SystemPlayReport. | ||
Line 2,722: | Line 2,809: | ||
No input, returns an output [[#SystemUpdateProgress]]. | No input, returns an output [[#SystemUpdateProgress]]. | ||
Same as [[#GetReceiveProgress]] except this uses nim ListLocalCommunicationSendSystemUpdateTask and GetLocalCommunicationSendSystemUpdateTaskInfo. | Same as [[#GetReceiveProgress]] except this uses nim ListLocalCommunicationSendSystemUpdateTask and GetLocalCommunicationSendSystemUpdateTaskInfo. The data copied to output is also swapped: u64 nim_out+0x8 is copied to out+0x8, and u64 nim_out+0x10 is copied to out+0x0. | ||
== ISystemUpdateControl == | == ISystemUpdateControl == | ||
Line 2,777: | Line 2,864: | ||
| 22 || [6.0.0+] [[#RequestCheckLatestUpdateIncludesRebootlessUpdate]] | | 22 || [6.0.0+] [[#RequestCheckLatestUpdateIncludesRebootlessUpdate]] | ||
|} | |} | ||
All Card cmds except SetupCardUpdate* require [[#SetupCardUpdate]]/[[#SetupCardUpdateViaSystemUpdater]] to be used previously. [[#GetPreparedCardUpdateEulaDataSize]]/[[#GetPreparedCardUpdateEulaData]] checks a different state flag. | All Card cmds except SetupCardUpdate* require [[#SetupCardUpdate]]/[[#SetupCardUpdateViaSystemUpdater]] to be used previously. [[#GetPreparedCardUpdateEulaDataSize]]/[[#GetPreparedCardUpdateEulaData]] checks a different state flag. | ||
Line 2,891: | Line 2,976: | ||
See [[NIM_services|nim]] regarding the input addr/port usage, etc. | See [[NIM_services|nim]] regarding the input addr/port usage, etc. | ||
This validates the [[#SystemDeliveryInfo]] and generates a [[NCM_services#ContentMetaKey|ContentMetaKey]] from that, and creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. Then the thread does: | This uses the same LocalContentShare check as [[#RequestSendSystemUpdate|RequestSendSystemUpdate]]. | ||
An error is thrown if a state flag is clear. | |||
This validates the [[#SystemDeliveryInfo]] (same as [[#RequestSendSystemUpdate|RequestSendSystemUpdate]]) and generates a [[NCM_services#ContentMetaKey|ContentMetaKey]] from that, and creates the [[#IAsyncResult]] + the async thread which handles the [[#IAsyncResult]] operation. | |||
Then the thread does: | |||
* Calls a func which does: | * Calls a func which does: | ||
Line 2,897: | Line 2,988: | ||
** Checks whether a sysupdate is actually required using the previously generated [[NCM_services#ContentMetaKey|ContentMetaKey]], throwing an error if not. | ** Checks whether a sysupdate is actually required using the previously generated [[NCM_services#ContentMetaKey|ContentMetaKey]], throwing an error if not. | ||
** Uses [[NIM_services|nim]] CreateLocalCommunicationReceiveSystemUpdateTask, returning the Result on failure. | ** Uses [[NIM_services|nim]] CreateLocalCommunicationReceiveSystemUpdateTask, returning the Result on failure. | ||
*** The input firmware_variation is from [[System_Settings|system-setting]] <code>ns.systemupdate!firmware_variation</code> or <code>ns.systemupdate!t_firmware_variation</code>, depending on the [[Settings_services|PlatformRegion]] (value 0xFF is used when the output setting-size is invalid). | |||
*** The input '''unk''' is set to: <code>unk = statefield == 0 ? 0x4 : 0xC</code> ([20.0.0+] uses statefield & 1 == 0). [20.0.0+] Additional data is now ORRed with unk afterwards: <code>unk |= ((statefield>>1) & 0x3) << 8;</code> (same statefield as before) | |||
** Uses [[NIM_services|nim]] RequestLocalCommunicationReceiveSystemUpdateTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ** Uses [[NIM_services|nim]] RequestLocalCommunicationReceiveSystemUpdateTaskRun, returning the Result on failure. Waits for the IAsyncResult operation from this to finish, then uses the Get cmd to get the output Result. | ||
*** When the Result from Get is an error, a func is called for filling in the [[#IAsyncResult|IAsyncResult]] ErrorContext with Type4. | |||
** Handles cleanup and returns. | ** Handles cleanup and returns. | ||
* On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | * On success, this loads various data which is then used for saving a SystemPlayReport when the cached [[System_Settings|system-setting]] "systemreport!enabled" is set. | ||
Line 2,922: | Line 3,016: | ||
=== ApplyReceivedUpdate === | === ApplyReceivedUpdate === | ||
No input/output. | No input/output. | ||
This uses the same LocalContentShare check as [[#RequestSendSystemUpdate|RequestSendSystemUpdate]]. | |||
=== GetReceivedEulaDataSize === | === GetReceivedEulaDataSize === | ||
Line 4,544: | Line 4,640: | ||
This is "nn::ns::SystemDeliveryInfo". This is a 0x100-byte struct. | This is "nn::ns::SystemDeliveryInfo". This is a 0x100-byte struct. | ||
[20.0.0+] The used ( | [20.0.0+] The used (Old)SystemUpdateId as selected by SystemUpdateIdFlag must now match one of the Ids in [[System_Settings|system-setting]] <code>contents_delivery!acceptable_system_update_ids_string</code>. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 4,560: | Line 4,656: | ||
| 0x9 || 0x3 || Reserved. | | 0x9 || 0x3 || Reserved. | ||
|- | |- | ||
| 0xC || 0x4 || | | 0xC || 0x4 || SystemUpdateVersion. | ||
|- | |- | ||
| 0x10 || 0x8 || | | 0x10 || 0x8 || OldSystemUpdateId. [20.0.0+] Always the NX Id: this is loaded from [[System_Settings|system-setting]] <code>contents_delivery!old_system_update_id</code>. | ||
|- | |- | ||
| 0x18 || 0x1 || FirmwareVariationId. Used by [[#RequestSendSystemUpdate]]. This is set to 0xC on S2. | | 0x18 || 0x1 || FirmwareVariationId. Used by [[#RequestSendSystemUpdate]]. This is set to 0xC on S2. | ||
Line 4,572: | Line 4,668: | ||
| 0x1B || 0x1 || [20.0.0+] SystemDeliveryInfoPlatform. Loaded from [[System_Settings|system-setting]] <code>ns.systemupdate!system_delivery_info_platform</code>. Elsewhere this is compared against the sys-setting, etc. | | 0x1B || 0x1 || [20.0.0+] SystemDeliveryInfoPlatform. Loaded from [[System_Settings|system-setting]] <code>ns.systemupdate!system_delivery_info_platform</code>. Elsewhere this is compared against the sys-setting, etc. | ||
|- | |- | ||
| 0x1C || 0x1 || [20.0.0+] | | 0x1C || 0x1 || [20.0.0+] SystemUpdateIdFlag. When non-zero, SystemUpdateId is used instead of OldSystemUpdateId. Always set to 0x1 by [[#GetSystemDeliveryInfo]] with [20.0.0+]. | ||
|- | |- | ||
| 0x1D || 0x3 || Padding | | 0x1D || 0x3 || Padding | ||
|- | |- | ||
| 0x20 || 0x8 || [20.0.0+] | | 0x20 || 0x8 || [20.0.0+] SystemUpdateId. See above. With [20.0.0+] [[#GetSystemDeliveryInfo]] now writes the Id here instead of OldSystemUpdateId (for the installed SystemUpdate). On S2 this is set to the Ounce Id. | ||
|- | |- | ||
| 0x28 || 0xB8 || | | 0x28 || 0xB8 || Reserved | ||
|- | |- | ||
| 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes. | | 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes. | ||
Line 4,592: | Line 4,688: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x4 || ApplicationDeliveryProtocolVersion. | | 0x0 || 0x4 || ApplicationDeliveryProtocolVersion. Loaded from [[System_Settings|system-setting]] <code>contents_delivery!application_delivery_protocol_version</code>. An error is thrown when [[System_Settings|system-setting]] <code>contents_delivery!application_delivery_protocol_version</code> < version, or when [[System_Settings|system-setting]] <code>contents_delivery!acceptable_application_delivery_protocol_version</code> > version. | ||
|- | |- | ||
| 0x4 || 0x4 || | | 0x4 || 0x4 || Padding | ||
|- | |- | ||
| 0x8 || 0x8 || ApplicationId. | | 0x8 || 0x8 || ApplicationId. | ||
Line 4,600: | Line 4,696: | ||
| 0x10 || 0x4 || ApplicationVersion. | | 0x10 || 0x4 || ApplicationVersion. | ||
|- | |- | ||
| 0x14 || 0x4 || | | 0x14 || 0x4 || RequiredApplicationVersion. | ||
|- | |- | ||
| 0x18 || 0x4 || RequiredSystemVersion. | | 0x18 || 0x4 || RequiredSystemVersion. | ||
|- | |- | ||
| 0x1C || 0x4 || | | 0x1C || 0x4 || u32 bitmask <code>nn::ns::ApplicationDeliveryAttributeTag</code>. [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]] sets this to the input u32. Bit30 and bit28 are additionally set, depending on [[NCM_services|ContentMetaType]] == Patch, etc. | ||
|- | |||
| 0x20 || 0x1 || [20.0.0+] [[NCM_services|ContentMetaPlatform]]. Loaded from [[NCM_services|ncm]] IContentMetaDatabase GetPlatform. | |||
|- | |||
| 0x21 || 0x1 || [20.0.0+] ProperProgramExists. Set to whether the bit for ProperProgramExists is set from [[NCM_services|ncm]] IContentMetaDatabase GetAttributes. | |||
|- | |- | ||
| | | 0x22 || 0xBE || Reserved | ||
|- | |- | ||
| 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes. Uses a different key than [[#SystemDeliveryInfo]]. | | 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes. Uses a different key than [[#SystemDeliveryInfo]]. |