NS services: Difference between revisions
No edit summary |
|||
(5 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 ==== | ||
Line 1,706: | Line 1,706: | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | ||
After validating the [[#ApplicationDeliveryInfo]], the output bool is set to | After validating the [[#ApplicationDeliveryInfo]], the output bool is set to [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] & 0x10000002 != 0x2, then this returns 0. | ||
==== CompareApplicationDeliveryInfo ==== | ==== CompareApplicationDeliveryInfo ==== | ||
Line 1,724: | Line 1,724: | ||
This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | This uses the same LocalContentShare check as [[#GetApplicationDeliveryInfo|GetApplicationDeliveryInfo]]. | ||
The second [[#ApplicationDeliveryInfo]] buffer is validated. An error is thrown when | 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 | 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 | When [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (first buffer) bit28 is set (bitmask 0x10000000): | ||
* 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. | ||
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 ==== | ||
Line 1,764: | 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,782: | Line 1,782: | ||
HasApplicationRecord is called with the input [[NCM_services#ApplicationId|ApplicationId]], an error is returned if the record isn't found. | 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,788: | 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. | *** 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. | ||
Line 1,819: | Line 1,819: | ||
An error is thrown if [[NIM_services|nim]] ListApplicationApplyDeltaTask returns a task. | 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,836: | Line 1,836: | ||
* 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. | *** 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. | ||
Line 1,851: | Line 1,851: | ||
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,892: | Line 1,892: | ||
** 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 platform fields from the input [[#SystemDeliveryInfo]]/[[#ApplicationDeliveryInfo]] match, write 1 to the output bool and return 0. Otherwise: | * 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 = [[#ApplicationDeliveryInfo]] | ** 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 2,795: | Line 2,795: | ||
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. | 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 | 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: | 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,986: | 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 4,635: | 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,651: | 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,663: | 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. |