NS services: Difference between revisions

No edit summary
 
(3 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 SystemUpdateMetaVersion 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>).
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 u32 [[#ApplicationDeliveryInfo]]+0x1C & 0x10000002 != 0x2, then this returns 0.
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 u32 [[#ApplicationDeliveryInfo]] (second buffer) +0x1C & 0x3 != 0x2, likewise when bit28 is clear in this field (bitmask 0x10000000).
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 u32 [[#ApplicationDeliveryInfo]] (first buffer) +0x1C bit1 is clear or bit0 set. An error is thrown when u32 [[#ApplicationDeliveryInfo]] (second buffer) +0x1C bit1 is clear.
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 u32 [[#ApplicationDeliveryInfo]] (first or second buffer) +0x14 is higher than [[#ApplicationDeliveryInfo]] (second buffer) ApplicationVersion, this will return 0 with the output bool set to 0.
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 u32 [[#ApplicationDeliveryInfo]] (first buffer) +0x1C bit28 is set (bitmask 0x10000000):
When [[#ApplicationDeliveryInfo|ApplicationDeliveryAttributeTag]] (first buffer) bit28 is set (bitmask 0x10000000):
* When [[#ApplicationDeliveryInfo]] (first buffer) ApplicationVersion >= [[#ApplicationDeliveryInfo]] (second buffer) ApplicationVersion, write 0 to the output bool, otherwise write 1. Then return 0.
* 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) ApplicationVersion > [[#ApplicationDeliveryInfo]] (second buffer) ApplicationVersion, write 0 to the output bool, otherwise write 1. Then return 0.
* 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]] SystemUpdateMetaVersion (only the upper 16bits are used from the SystemUpdateMetaVersion).
* 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]] cmd53, max entries is 0x12.
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]] cmd53, returning the Result on failure.
** Uses [[NIM_services|nim]] CreateLocalCommunicationReceiveApplicationTask, returning the Result on failure.
** Uses [[NIM_services|nim]] cmd56, 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]] 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]] cmd67, throwing an error if no task is returned. Then [[NIM_services|nim]] cmd57 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.
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]] cmd60, returning the Result on failure.
** Uses [[NIM_services|nim]] CreateLocalCommunicationSendApplicationTask, returning the Result on failure.
** Uses [[NIM_services|nim]] cmd61, 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]] 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]] cmd68/cmd63 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.
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]] ContentMetaPlatform == 0 && [[#ApplicationDeliveryInfo]] ProperProgramExists == 0;
** 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 SystemUpdateMetaId ([20.0.0+] NewSystemUpdateMetaId, NewSystemUpdateMetaIdFlag ignored) must match the Id for the installed SystemUpdate as returned by [[NCM_services|ncm]].
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:
Line 2,989: Line 2,989:
** 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 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.
*** When the Result from Get is an error, a func is called for filling in the [[#IAsyncResult|IAsyncResult]] ErrorContext with Type4.
Line 4,639: 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 (New)SystemUpdateMetaId as selected by NewSystemUpdateMetaIdFlag must now match one of the Ids in [[System_Settings|system-setting]] <code>contents_delivery!acceptable_system_update_ids_string</code>.
[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,655: Line 4,656:
| 0x9 || 0x3 || Reserved.
| 0x9 || 0x3 || Reserved.
|-
|-
| 0xC || 0x4 || SystemUpdateMetaVersion.
| 0xC || 0x4 || SystemUpdateVersion.
|-
|-
| 0x10 || 0x8 || SystemUpdateMetaId. [20.0.0+] Always the NX Id: this is loaded from [[System_Settings|system-setting]] <code>contents_delivery!old_system_update_id</code>.
| 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,667: 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+] NewSystemUpdateMetaIdFlag. When non-zero, NewSystemUpdateMetaId is used instead of SystemUpdateMetaId. Always set to 0x1 by [[#GetSystemDeliveryInfo]] with [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+] NewSystemUpdateMetaId. See above. With [20.0.0+] [[#GetSystemDeliveryInfo]] now writes the Id here instead of SystemUpdateMetaId. On S2 this is set to the Ounce Id.
| 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 || Unused by [[#RequestSendSystemUpdate]]/[[#RequestReceiveSystemUpdate]], besides HMAC validation.
| 0x28 || 0xB8 || Reserved
|-
|-
| 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes.
| 0xE0 || 0x20 || HMAC-SHA256 over the previous 0xE0-bytes.