Shared Database services: Difference between revisions
(142 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
= pl:s = | |||
This is "nn::pl::detail::IPlatformServiceManagerForSystem". With [16.0.0+] "pl:u" was moved from here to [[Glue_services|glue]]. | |||
"pl:s" has max_sessions 2 (5 with [16.0.0+]). | |||
The Function cmds (including GetRequiredApplicationVersion) uses data parsed from [[#FunctionBlackList|FunctionBlackList]]. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 7: | Line 10: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || [[#RequestLoad]] | | 0 || [1.0.0-15.0.1] [[#RequestLoad]] | ||
|- | |||
| 1 || [1.0.0-15.0.1] [[#GetLoadState]] | |||
|- | |||
| 2 || [1.0.0-15.0.1] [[#GetSize]] | |||
|- | |||
| 3 || [1.0.0-15.0.1] [[#GetSharedMemoryAddressOffset]] | |||
|- | |||
| 4 || [1.0.0-15.0.1] [[#GetSharedMemoryNativeHandle]] | |||
|- | |||
| 5 || [1.0.0-15.0.1] [[#GetSharedFontInOrderOfPriority]] | |||
|- | |||
| 6 || [4.0.0-15.0.1] GetSharedFontInOrderOfPriorityForSystem | |||
|- | |- | ||
| | | 100 || [8.0.0+] [[#RequestApplicationFunctionAuthorization|RequestApplicationFunctionAuthorization]] | ||
|- | |- | ||
| | | 101 || [8.0.0+] [[#RequestApplicationFunctionAuthorizationByProcessId|RequestApplicationFunctionAuthorizationByProcessId]] | ||
|- | |- | ||
| | | 102 || [10.0.0+] [[#RequestApplicationFunctionAuthorizationByApplicationId|RequestApplicationFunctionAuthorizationByApplicationId]] | ||
|- | |- | ||
| | | 103 || [11.0.0+] [[#RefreshApplicationFunctionBlackListDebugRecord|RefreshApplicationFunctionBlackListDebugRecord]] | ||
|- | |- | ||
| | | 104 || [11.0.0+] [[#RequestApplicationFunctionAuthorizationByProgramId|RequestApplicationFunctionAuthorizationByProgramId]] | ||
|- | |||
| 105 || [11.0.0+] [[#GetFunctionBlackListSystemVersionToAuthorize|GetFunctionBlackListSystemVersionToAuthorize]] | |||
|- | |||
| 106 || [11.0.0+] [[#GetFunctionBlackListVersion|GetFunctionBlackListVersion]] | |||
|- | |||
| 107 || [17.0.0+] [[#RequestApplicationFunctionAuthorizationByApplicationIdAndProgramId|RequestApplicationFunctionAuthorizationByApplicationIdAndProgramId]] | |||
|- | |||
| 108 || [20.0.0+] [[#GetRequiredApplicationVersion|GetRequiredApplicationVersion]] | |||
|- | |||
| 1000 || [9.0.0+] LoadNgWordDataForPlatformRegionChina | |||
|- | |||
| 1001 || [9.0.0+] GetNgWordDataSizeForPlatformRegionChina | |||
|} | |} | ||
== RequestLoad == | == RequestLoad == | ||
Takes a [[#SharedFontType]] (uint32), no output. | Takes a [[#SharedFontType]] (uint32), no output. | ||
== GetLoadState == | == GetLoadState == | ||
Takes a [[#SharedFontType]] (uint32), returns the [[#LoadState]] (uint32). | Takes a [[#SharedFontType]] (uint32), returns the [[#LoadState]] (uint32). | ||
=== LoadState === | === LoadState === | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 40: | Line 64: | ||
== GetSize == | == GetSize == | ||
Takes a [[#SharedFontType]] (uint32), returns the Font Size (uint32). | Takes a [[#SharedFontType]] (uint32), returns the Font Size (uint32). | ||
== GetSharedMemoryAddressOffset == | == GetSharedMemoryAddressOffset == | ||
Takes a [[#SharedFontType]] (uint32), returns the offset (uint32) to the Font Address. | Takes a [[#SharedFontType]] (uint32), returns the offset (uint32) to the Font Address. | ||
Line 52: | Line 74: | ||
User-processes map this SharedMemory with size=0x1100000 and permissions=R--. | User-processes map this SharedMemory with size=0x1100000 and permissions=R--. | ||
Font data is TTF, located at the offset returned by #GetSharedMemoryAddressOffset. | Font data is TTF, located at the offset returned by [[#GetSharedMemoryAddressOffset]]. | ||
== GetSharedFontInOrderOfPriority == | == GetSharedFontInOrderOfPriority == | ||
Takes an input u64 [[Settings_services#LanguageCode|LanguageCode]] and 3 type-0x6 output buffers, returns an output u8 and u32. | Takes an input u64 [[Settings_services#LanguageCode|LanguageCode]] and 3 type-0x6 output buffers, returns an output u8 and u32. The u8 is a bool to specify if the fonts are loaded or not and the u32 is the font count. | ||
The first buffer contains a list of [[#SharedFontType|Shared font types]], the second buffer contains the font offsets and the final buffer contains the font sizes. | |||
The buffers are an array of u32s which specify information about a specific font. Buffer1[n] is related to Buffer2[n] and Buffer3[n]. | |||
Example: Font index 0s offset is at Buffer2[0], size is at Buffer3[0]. | |||
The fonts are relative to the shared memory created by [[#GetSharedFontSharedMemoryHandle]] | |||
== SharedFontType == | == SharedFontType == | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 75: | Line 100: | ||
| 0x05 || Nintendo Extended | | 0x05 || Nintendo Extended | ||
|} | |} | ||
* Nintendo Extended: Contains Nintendo-specific characters, including HID buttons, HID controller styles, applet icons, Wii(U) icons, etc. | |||
== RequestApplicationFunctionAuthorization == | |||
Takes a PID, an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an u64 pid_reserved, no output. | |||
== RequestApplicationFunctionAuthorizationByProcessId == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an u64 "nn::os::ProcessId", no output. | |||
Uses the same cmd impl func as [[#RequestApplicationFunctionAuthorization|RequestApplicationFunctionAuthorization]]. | |||
== RequestApplicationFunctionAuthorizationByApplicationId == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an u32, an [[NCM_services#ApplicationId|ApplicationId]], no output. | |||
== RefreshApplicationFunctionBlackListDebugRecord == | |||
No input/output. | |||
== RequestApplicationFunctionAuthorizationByProgramId == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an [[NCM_services#ProgramId|ProgramId]], no output. | |||
== GetFunctionBlackListSystemVersionToAuthorize == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an [[NCM_services#ApplicationId|ApplicationId]], returns an [[#FunctionBlackListSystemVersion|FunctionBlackListSystemVersion]]. | |||
== GetFunctionBlackListVersion == | |||
No input, returns an output u32. | |||
== RequestApplicationFunctionAuthorizationByApplicationIdAndProgramId == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an u32, an [[NCM_services#ApplicationId|ApplicationId]], an [[NCM_services#ProgramId|ProgramId]], no output. | |||
== GetRequiredApplicationVersion == | |||
Takes an u8 [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]], an [[NCM_services#ApplicationId|ApplicationId]], returns an u32. | |||
= mii:u, mii:e = | = mii:u, mii:e = | ||
This is "nn::mii::detail::IStaticService". | This is "nn::mii::detail::IStaticService". | ||
These were moved from [[NS_services|ns]] with [3.0.0+]. | |||
These are only available when the output from [[Process_Manager_services|pm:bm]] GetBootMode is not Maintenance. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || GetDatabaseService | |||
|} | |||
== IDatabaseService == | |||
This is "nn::mii::detail::IDatabaseService". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || IsUpdated | |||
|- | |||
| 1 || IsFullDatabase | |||
|- | |||
| 2 || GetCount | |||
|- | |||
| 3 || Get | |||
|- | |||
| 4 || Get1 | |||
|- | |||
| 5 || UpdateLatest | |||
|- | |||
| 6 || BuildRandom | |||
|- | |||
| 7 || BuildDefault | |||
|- | |||
| 8 || Get2 | |||
|- | |||
| 9 || Get3 | |||
|- | |||
| 10 || UpdateLatest1 | |||
|- | |||
| 11 || FindIndex | |||
|- | |||
| 12 || Move | |||
|- | |||
| 13 || AddOrReplace | |||
|- | |||
| 14 || Delete | |||
|- | |||
| 15 || DestroyFile | |||
|- | |||
| 16 || DeleteFile | |||
|- | |||
| 17 || Format | |||
|- | |||
| 18 || Import | |||
|- | |||
| 19 || Export | |||
|- | |||
| 20 || IsBrokenDatabaseWithClearFlag | |||
|- | |||
| 21 || GetIndex | |||
|- | |||
| 22 || [5.0.0+] SetInterfaceVersion | |||
|- | |||
| 23 || [5.0.0+] Convert | |||
|- | |||
| 24 || [7.0.0+] ConvertCoreDataToCharInfo | |||
|- | |||
| 25 || [7.0.0+] ConvertCharInfoToCoreData | |||
|- | |||
| 26 || [10.2.0+] Append | |||
|- | |||
| 27 || [19.0.0-19.0.1] ImportMigrationData | |||
|} | |||
= miiimg = | |||
This is "nn::mii::detail::IImageDatabaseService". | |||
This was added with [5.0.0+]. | |||
This is only available when the output from [[Process_Manager_services|pm:bm]] GetBootMode is not Maintenance. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || Initialize | |||
|- | |||
| 10 || Reload | |||
|- | |||
| 11 || GetCount | |||
|- | |||
| 12 || IsEmpty | |||
|- | |||
| 13 || IsFull | |||
|- | |||
| 14 || GetAttribute | |||
|- | |||
| 15 || LoadImage | |||
|- | |||
| 16 || AddOrUpdateImage | |||
|- | |||
| 17 || DeleteImages | |||
|- | |||
| 18 || [19.0.0+] AddImageForMigration | |||
|- | |||
| 19 || [20.0.0+] ClearHeaderForMigration | |||
|- | |||
| 20 || [20.0.0+] SaveHeaderForMigration | |||
|- | |||
| 100 || DeleteFile | |||
|- | |||
| 101 || DestroyFile | |||
|- | |||
| 102 || ImportFile | |||
|- | |||
| 103 || ExportFile | |||
|- | |||
| 104 || ForceInitialize | |||
|} | |||
= pdm:ntfy = | |||
This is "nn::pdm::detail::INotifyService". | |||
This was moved from [[NS_services|ns]] with [3.0.0+]. | |||
This is only available when the output from [[Process_Manager_services|pm:bm]] GetBootMode is not Maintenance. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 83: | Line 267: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || | | 0 || [[#NotifyAppletEvent]] | ||
|- | |||
| 2 || [[#NotifyOperationModeChangeEvent]] | |||
|- | |||
| 3 || [[#NotifyPowerStateChangeEvent]] | |||
|- | |||
| 4 || [[#NotifyClearAllEvent]] | |||
|- | |||
| 5 || [2.0.0+] [[#NotifyEventForDebug]] | |||
|- | |||
| 6 || [4.0.0+] SuspendUserAccountEventService | |||
|- | |||
| 7 || [4.0.0+] ResumeUserAccountEventService | |||
|- | |||
| 8 || [6.0.0+] | |||
|- | |||
| 9 || [8.0.0+] | |||
|- | |||
| 20 || [20.0.0+] | |||
|- | |||
| 100 || [20.0.0+] | |||
|- | |||
| 101 || [20.0.0+] | |||
|} | |||
== NotifyAppletEvent == | |||
Takes an input u8 [[#AppletEventType]], an u8 [[Applet_Manager_services#AppletId|AppletId]], an u8 [[Filesystem_services#StorageId|StorageId]], an u8 [[#PlayLogPolicy]], an u32 '''event_x8''', and an u64 '''ProgramId'''. Returns no output. | |||
When [[#PlayLogPolicy]] is 2 ("None") this will immediately return 0. | |||
Logs a new [[#PlayEvent]] with the following data: | |||
* Clears the 0x10-bytes at +0x10. | |||
* u8 +0xF = [[#AppletEventType]]. | |||
* Sets the 3 timestamps. | |||
* Converts '''ProgramId''' and writes it to +0x0. | |||
* u32 +0x8 = '''event_x8'''. | |||
* u8 +0xC = [[Applet_Manager_services#AppletId|AppletId]], u8 +0xD = [[Filesystem_services#StorageId|StorageId]], and u8 +0xE = [[#PlayLogPolicy]]. | |||
After the initial logging, additional code runs with some of the above input params. | |||
== NotifyOperationModeChangeEvent == | |||
Takes an input u8 '''inval''', no output. | |||
Logs a new [[#PlayEvent]] with the following data: clears the 0x20-bytes at +0x0, u8 +0x1C = 0x3, u8 +0x0 = '''inval''', and sets the 3 timestamps. | |||
== NotifyPowerStateChangeEvent == | |||
Takes an input u8 '''inval''', no output. | |||
Logs a new [[#PlayEvent]] with the following data: clears the 0x20-bytes at +0x0, u8 +0x1C = 0x2, u8 +0x0 = '''inval''', and sets the 3 timestamps. | |||
After the initial logging, additional code runs which uses '''inval'''. | |||
== NotifyClearAllEvent == | |||
No input/output. | |||
== NotifyEventForDebug == | |||
Takes an input type-0x5 buffer containing an array of [[#PlayEvent]], no output. | |||
Gets the [[System_Settings|system-setting]] <code>pdm!is_production</code>, the size must be 1 and the value must be 0, otherwise an error is returned. | |||
Each [[#PlayEvent]] entry is validated, throwing an error on failure. After an entry is successfully validated, it is written to the log. | |||
== Cmd8 == | |||
Takes an input u8 [[#AppletEventType]], an u8 [[Applet_Manager_services#LibraryAppletMode|LibraryAppletMode]], an u8 [[Applet_Manager_services#AppletId|AppletId]], an u8 [[Filesystem_services#StorageId|StorageId]], an u8 [[#PlayLogPolicy]], and an u64 '''ProgramId'''. Returns no output. | |||
This is similar to [[#NotifyAppletEvent]]. | |||
When [[#PlayLogPolicy]] is 2 ("None") this will immediately return 0. | |||
Logs a new [[#PlayEvent]] with the following data: | |||
* Clears the 0x20-bytes at +0x0. | |||
* u8 +0xF = [[#AppletEventType]]. | |||
* Sets the 3 timestamps. | |||
* Converts '''ProgramId''' and writes it to +0x0. | |||
* u8 +0x9 = [[Applet_Manager_services#LibraryAppletMode|LibraryAppletMode]]. | |||
* u8 +0x8 = 1. | |||
* u8 +0xC = [[Applet_Manager_services#AppletId|AppletId]], u8 +0xD = [[Filesystem_services#StorageId|StorageId]], and u8 +0xE = [[#PlayLogPolicy]]. | |||
After the initial logging, additional code runs with some of the above input params. This is handled the same as [[#NotifyAppletEvent]], except that the value passed for '''event_x8''' is value 0 here. | |||
== Cmd9 == | |||
Takes an input u8 [[#AppletEventType]], an u8 [[Applet_Manager_services#AppletId|AppletId]], an u8 [[Filesystem_services#StorageId|StorageId]], an 0x20-byte struct, an u8 bool flag, an u8 [[#PlayLogPolicy]], an u32 '''event_x8''', and an u64 '''program_id'''. Returns no output. | |||
[10.0.0+] This now takes an additional input u64, new_program_id. At the very beginning a new func is now called, with params: ({constant value}, &[[#AppletEventType]], &program_id, &new_program_id, &StorageId). Afterwards, where it would originally use program_id, it now uses new_program_id instead. The called func eventually writes the input to a buffer using msgpack, with the output from that being added to a list in state. | |||
This is identical to [[#NotifyAppletEvent]] except for the additional struct/flag params. | |||
After the initial logging, additional code runs with some of the above input params. This is handled the same as [[#NotifyAppletEvent]], except that when the u8 bool flag is set the input struct is used with this. | |||
[10.0.0+] New code at the very end of this func was added. When [[Applet_Manager_services#AppletId|AppletId]] is 0x1, or 0x1F-0x20, the following runs: | |||
* If [[#AppletEventType]] is 1, 5, or 6, func1 is called with param &program_id. This runs msgpack code similar to the above, then does {other things}. | |||
* Otherwise, if [[#AppletEventType]] is 0, func0 is called with param &program_id. | |||
** This calls the same msgpack func at the start as func1. [[Glue_services#GetApplicationLaunchProperty|GetApplicationLaunchProperty]] is used, with the output being copied to state on success, otherwise the output Result is used with other msgpack code. | |||
* If [[#AppletEventType]] doesn't match any of these, nothing is done. | |||
= pdm:qry = | |||
This is "nn::pdm::detail::IQueryService". | |||
This was moved from [[NS_services|ns]] with [3.0.0+]. | |||
This is only available when the output from [[Process_Manager_services|pm:bm]] GetBootMode is not Maintenance. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || [[#QueryAppletEvent]] ([1.0.0-7.0.1] QueryApplicationEvent) | |||
|- | |||
| 1 || [1.0.0-6.2.0] [[#QueryPlayStatistics]] | |||
|- | |||
| 2 || [1.0.0-6.2.0] [[#QueryPlayStatisticsByUserAccountId]] | |||
|- | |||
| 3 || [1.0.0-6.2.0] [[#QueryPlayStatisticsByNetworkServiceAccountId]] | |||
|- | |||
| 4 || [[#QueryPlayStatisticsByApplicationId]] | |||
|- | |||
| 5 || [[#QueryPlayStatisticsByApplicationIdAndUserAccountId]] | |||
|- | |||
| 6 || [1.0.0-6.2.0] [[#QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId]] | |||
|- | |||
| 7 || [10.0.0-14.1.2] [[#QueryLastPlayTimeV0]] ([1.0.0-9.2.0] QueryLastPlayTime) | |||
|- | |||
| 8 || [[#QueryPlayEvent]] | |||
|- | |||
| 9 || [[#GetAvailablePlayEventRange]] | |||
|- | |||
| 10 || [3.0.0+] [[#QueryAccountEvent]] | |||
|- | |||
| 11 || [4.0.0+] [[#QueryAccountPlayEvent]] | |||
|- | |||
| 12 || [4.0.0+] [[#GetAvailableAccountPlayEventRange]] | |||
|- | |||
| 13 || [10.0.0-14.1.2] [[#QueryApplicationPlayStatisticsForSystemV0]] ([5.0.0-9.2.0] QueryApplicationPlayStatisticsForSystem) | |||
|- | |||
| 14 || [6.0.0-14.1.2] [[#QueryRecentlyPlayedApplication]] | |||
|- | |||
| 15 || [6.0.0-14.1.2] [[#GetRecentlyPlayedApplicationUpdateEvent]] | |||
|- | |||
| 16 || [10.0.0-14.1.2] [[#QueryApplicationPlayStatisticsByUserAccountIdForSystemV0]] ([6.0.0-9.2.0] QueryApplicationPlayStatisticsByUserAccountIdForSystem) | |||
|- | |||
| 17 || [10.0.0+] [[#QueryLastPlayTime]] | |||
|- | |||
| 18 || [10.0.0+] [[#QueryApplicationPlayStatisticsForSystem]] | |||
|- | |||
| 19 || [10.0.0+] [[#QueryApplicationPlayStatisticsByUserAccountIdForSystem]] | |||
|- | |||
| 100 || [20.0.0+] | |||
|- | |||
| 110 || [20.0.0+] | |||
|- | |||
| 118 || [20.0.0+] | |||
|- | |||
| 119 || [20.0.0+] | |||
|} | |||
== QueryAppletEvent == | |||
Takes ([10.0.0+] an input u8 bool), an input s32 entry_index, a type-0x6 output buffer containing an array of [[#AppletEvent]], and returns an output s32 for actual total output entries. | |||
== QueryPlayStatistics == | |||
Takes a type-0x6 output buffer containing an array of [[#PlayStatistics]] and returns an output s32 for actual total output entries. | |||
[6.2.0+] This command was removed. | |||
== QueryPlayStatisticsByUserAccountId == | |||
Takes an input u128 '''Uid''', a type-0x6 output buffer containing an array of [[#PlayStatistics]] and returns an output s32 for actual total output entries. | |||
[6.2.0+] This command was removed. | |||
== QueryPlayStatisticsByNetworkServiceAccountId == | |||
Takes an input u64 '''NetworkServiceAccountId''', a type-0x6 output buffer containing an array of [[#PlayStatistics]] and returns an output s32 for actual total output entries. | |||
[6.2.0+] This command was removed. | |||
== QueryPlayStatisticsByApplicationId == | |||
Takes ([10.0.0+] an input u8 bool), an input u64 '''ApplicationId''' and returns an output [[#PlayStatistics]]. | |||
== QueryPlayStatisticsByApplicationIdAndUserAccountId == | |||
Takes ([10.0.0+] an input u8 bool), an input u64 '''ApplicationId''', an input u128 '''Uid''' and returns an output [[#PlayStatistics]]. | |||
== QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId == | |||
Takes an input u64 '''ApplicationId''', an input u64 '''NetworkServiceAccountId''' and returns an output [[#PlayStatistics]]. | |||
[6.2.0+] This command was removed. | |||
== QueryLastPlayTimeV0 == | |||
Takes a type-0x6 output buffer containing an array of [[#LastPlayTime]], and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
[10.0.0+] This now calls the impl func for [[#QueryLastPlayTime]] with flag=0. | |||
== QueryPlayEvent == | |||
Takes an input s32 entry_index, a type-0x6 output buffer containing an array of [[#PlayEvent]], and returns an output s32 for actual total output entries. | |||
== GetAvailablePlayEventRange == | |||
No input, returns 3 output s32s: total_entries, start_entry_index, and end_entry_index. | |||
== QueryAccountEvent == | |||
Takes an input s32 entry_index, a type-0x6 output buffer containing an array of [[#AccountEvent]], and returns an output s32 for actual total output entries. | |||
== QueryAccountPlayEvent == | |||
Takes an input s32 entry_offset, an input u128 '''Uid''', a type-0x6 output buffer containing an array of [[#AccountPlayEvent]], and returns an output s32 for actual total output entries. | |||
== GetAvailableAccountPlayEventRange == | |||
Takes an input u128 '''Uid''' and returns 3 output s32s: total_entries, start_entry_index, and end_entry_index. | |||
== QueryApplicationPlayStatisticsForSystemV0 == | |||
Takes a type-0x6 output buffer containing an array of [[#ApplicationPlayStatistics]] and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
The number of entries in each array is the same. | |||
[10.0.0+] This now calls the impl func for [[#QueryApplicationPlayStatisticsForSystem]] with flag=0. | |||
== QueryRecentlyPlayedApplication == | |||
Takes ([10.0.0+] an input u8 bool), an input u128 '''Uid''', a type-0x6 output buffer containing an array of u64 '''ApplicationId''', and returns an output s32 for actual total output entries. | |||
Returns a list of applications played by the specified user. | |||
== GetRecentlyPlayedApplicationUpdateEvent == | |||
No input, returns an output Event handle with autoclear=false. | |||
This is signaled when logging a new [[#PlayEvent]] which would be available via [[#QueryAccountEvent]], where [[#PlayEvent]] +0x18 is 0. | |||
== QueryApplicationPlayStatisticsByUserAccountIdForSystemV0 == | |||
Takes an [[Account_services#Uid|Uid]], a type-0x6 output buffer containing an array of [[#ApplicationPlayStatistics]] and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
Same as [[#QueryApplicationPlayStatisticsForSystemV0]] except this gets playstats specific to '''Uid'''. | |||
[10.0.0+] This now calls the impl func for [[#QueryApplicationPlayStatisticsByUserAccountIdForSystem]] with flag=0. | |||
== QueryLastPlayTime == | |||
Takes an input u8 bool, a type-0x6 output buffer containing an array of [[#LastPlayTime]], and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
== QueryApplicationPlayStatisticsForSystem == | |||
Takes an input u8 bool, a type-0x6 output buffer containing an array of [[#ApplicationPlayStatistics]] and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
The number of entries in each array is the same. | |||
== QueryApplicationPlayStatisticsByUserAccountIdForSystem == | |||
Takes an input u8 bool, an [[Account_services#Uid|Uid]], a type-0x6 output buffer containing an array of [[#ApplicationPlayStatistics]] and a type-0x5 input buffer containing an array of u64 '''ApplicationId'''. Returns an output s32 for actual total output entries. | |||
Same as [[#QueryApplicationPlayStatisticsForSystem]] except this gets playstats specific to '''Uid'''. | |||
= avm = | |||
This is "nn::avm::srv::IAvmService". | |||
This was added with [6.0.0+]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 100 || [[#GetHighestAvailableVersion]] | |||
|- | |||
| 101 || [[#GetHighestRequiredVersion]] | |||
|- | |||
| 102 || [[#GetVersionListEntry]] | |||
|- | |||
| 103 || [[#GetVersionListImporter]] | |||
|- | |||
| 200 || [[#GetLaunchRequiredVersion]] | |||
|- | |||
| 202 || [[#UpgradeLaunchRequiredVersion]] | |||
|- | |||
| 1000 || [[#PushLaunchVersion]] | |||
|- | |||
| 1001 || [[#ListVersionList]] | |||
|- | |||
| 1002 || [[#ListRequiredVersion]] | |||
|} | |||
=== GetHighestAvailableVersion === | |||
Takes two u64 title ids. Returns the highest available version of both. | |||
Unused by official software. | |||
=== GetHighestRequiredVersion === | |||
Takes two u64 title ids. Returns the highest available version of both. | |||
Official software calls this with the id of an application and its update. | |||
=== GetVersionListEntry === | |||
Takes an input u64 title id. Returns associated [[#VersionListEntry]]. | |||
=== GetVersionListImporter === | |||
No input, returns an [[#IVersionListImporter]]. | |||
=== GetLaunchRequiredVersion === | |||
Takes an input u64 title id. Return the required launch version. | |||
=== UpgradeLaunchRequiredVersion === | |||
Takes a u32 launch version and a u64 title id. | |||
Version has to be greater the result of GetLaunchRequiredVersion. | |||
=== PushLaunchVersion === | |||
Takes a u32 launch version and a u64 title id. | |||
=== ListVersionList === | |||
No input, returns a type 6 buffer of [[#VersionListEntry]] and a u32 count. | |||
=== ListRequiredVersion === | |||
No input, returns a type 6 buffer of [[#RequiredVersionEntry]] and a u32 count. | |||
== IVersionListImporter == | |||
This is "nn::avm::srv::IVersionListImporter". | |||
This was added with [6.0.0+]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || [[#SetTimestamp]] | |||
|- | |||
| 1 || [[#PushEntries]] | |||
|- | |||
| 2 || [[#Flush]] | |||
|} | |||
=== SetTimestamp === | |||
Takes an input u64 unix timestamp, no output. | |||
=== PushEntries === | |||
Takes an input type-6 buffer [[#VersionListEntry]], no output. | |||
=== Flush === | |||
No input, no output. Flushed the commited data to its safe. | |||
= ApplicationFunctionAuthorizationId = | |||
This is "nn::pl::ApplicationFunctionAuthorizationId". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| 0 || Invalid | |||
|- | |||
| 1 || LocalNetworkMode | |||
|- | |||
| 2 || SecureLdnLocalCommunication | |||
|- | |||
| 3 || SecureLp2pLocalCommunication | |||
|- | |||
| 4 || InsecureLp2pLocalCommunication | |||
|- | |||
| 5 || Launch | |||
|} | |||
= FunctionBlackListSystemVersion = | |||
This is "nn::pl::FunctionBlackListSystemVersion". This is a 0x4-byte struct. | |||
= VersionListEntry = | |||
This is a 0x10-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || Update Id. | |||
|- | |||
| 0x8 || 0x4 || Available version. | |||
|- | |||
| 0xC || 0x4 || Required version. | |||
|} | |||
= RequiredVersionEntry = | |||
This is a 0x10-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || Id. | |||
|- | |||
| 0x8 || 0x4 || Required version. | |||
|- | |||
| 0xC || 0x4 || Padding. | |||
|} | |||
= AppletEvent = | |||
This is "nn::pdm::AppletEvent" ([1.0.0-7.0.1] "nn::pdm::ApplicationEvent"). | |||
This is a 0x28-byte ([1.0.0-15.0.1] 0x18-byte) struct. | |||
Pre-16.0.0: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ProgramId | |||
|- | |||
| 0x8 || 0x4 || entryindex | |||
|- | |||
| 0xC || 0x4 || timestamp0 | |||
|- | |||
| 0x10 || 0x4 || timestamp1 | |||
|- | |||
| 0x14 || 0x1 || [[#PlayEvent]] +0xF | |||
|- | |||
| 0x15 || 0x3 || Padding | |||
|} | |||
Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00. | |||
[16.0.0+]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ProgramId | |||
|- | |||
| 0x8 || 0x4 || entryindex | |||
|- | |||
| 0xC || 0x4 || Padding | |||
|- | |||
| 0x10 || 0x8 || timestamp0 in PosixTime | |||
|- | |||
| 0x18 || 0x8 || timestamp1 in PosixTime | |||
|- | |||
| 0x20 || 0x1 || [[#PlayEvent]] +0xF | |||
|- | |||
| 0x21 || 0x7 || Padding | |||
|} | |||
= PlayStatistics = | |||
This is "nn::pdm::PlayStatistics". | |||
This is a 0x48-byte ([1.0.0-15.0.1] 0x28-byte) struct. | |||
Pre-16.0.0: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ProgramId | |||
|- | |||
| 0x8 || 0x4 || First entryindex | |||
|- | |||
| 0xC || 0x4 || First timestamp0. Same as the first [[#AppletEvent]] timestamp. | |||
|- | |||
| 0x10 || 0x4 || First timestamp1. Same as the second [[#AppletEvent]] timestamp. | |||
|- | |||
| 0x14 || 0x4 || Last entryindex | |||
|- | |||
| 0x18 || 0x4 || Last timestamp0. Same as the first [[#AppletEvent]] timestamp. | |||
|- | |||
| 0x1C || 0x4 || Last timestamp1. Same as the second [[#AppletEvent]] timestamp. | |||
|- | |||
| 0x20 || 0x4 || Total play-time in minutes. | |||
|- | |||
| 0x24 || 0x4 || Total times the program was launched. | |||
|} | |||
[16.0.0+]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ProgramId | |||
|- | |||
| 0x8 || 0x4 || First entryindex | |||
|- | |||
| 0xC || 0x4 || Padding | |||
|- | |||
| 0x10 || 0x8 || First timestamp0. Same as the first [[#AppletEvent]] timestamp except in PosixTime. | |||
|- | |||
| 0x18 || 0x8 || First timestamp1. Same as the second [[#AppletEvent]] timestamp except in PosixTime. | |||
|- | |||
| 0x20 || 0x4 || Last entryindex | |||
|- | |||
| 0x24 || 0x4 || Padding | |||
|- | |||
| 0x28 || 0x8 || Last timestamp0. Same as the first [[#AppletEvent]] timestamp except in PosixTime. | |||
|- | |||
| 0x30 || 0x8 || Last timestamp1. Same as the second [[#AppletEvent]] timestamp except in PosixTime. | |||
|- | |||
| 0x38 || 0x8 || Total play-time in nanoseconds. | |||
|- | |||
| 0x40 || 0x4 || Total times the program was launched. | |||
|- | |||
| 0x44 || 0x4 || Padding | |||
|} | |||
= LastPlayTime = | |||
This is "nn::pdm::LastPlayTime". | |||
This is a 0x18-byte struct and contains data from the last time the program was played. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ApplicationId | |||
|- | |||
| 0x8 || 0x4 || Same as the first [[#AppletEvent]] timestamp. | |||
|- | |||
| 0xC || 0x4 || Same as the second [[#AppletEvent]] timestamp. | |||
|- | |||
| 0x10 || 0x4 || Total minutes since the program was last played. | |||
|- | |||
| 0x14 || 0x1 || Flag indicating whether the above field is set. | |||
|- | |||
| 0x15 || 0x3 || Padding | |||
|} | |||
= PlayEventType = | |||
This is an enum for [[#PlayEvent]] +0x1C, which indicates the type of [[#PlayEvent]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| 0 || Applet | |||
|- | |||
| 1 || Account | |||
|- | |||
| 2 || PowerStateChange | |||
|- | |||
| 3 || OperationModeChange | |||
|- | |||
| 4 || Initialize. Used for the very first [[#PlayEvent]] entry in the log. | |||
|} | |} | ||
= AppletEventType = | |||
This is an enum for [[#PlayEvent]] +0xF with [[#PlayEventType]] = Applet, this indicates the type of the Applet event. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| 0 || "launch" | |||
|- | |||
| 1 || "exit" | |||
|- | |||
| 2 || "in_focus" | |||
|- | |||
| 3 || "out_of_focus" | |||
|- | |||
| 4 || "out_of_focus" | |||
|- | |||
| 5 || "exit" | |||
|- | |||
| 6 || "exit" | |||
|} | |||
= PlayLogPolicy = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Meaning | |||
! Description | |||
|- | |||
| 0 || All || All pdm:qry cmds which require [[#PlayEventType]] = Applet and AppletId = Application will only return the entry when PlayLogPolicy matches this value. | |||
|- | |||
| 1 || LogOnly || The above commands will filter out the entry with this. | |||
|- | |||
| 2 || None || pdm:ntfy [[#NotifyAppletEvent]], [[#Cmd8]], and [[#Cmd9]] will immediately return 0 when the input param matches this value. | |||
|- | |||
| 3 || || [10.0.0+] The cmds which require PlayLogPolicy == All, now also allow value 3 if the cmd input flag is set. | |||
|} | |||
This is an enum for [[#PlayEvent]] +0xE with [[#PlayEventType]] = Applet. This is set via the above commands, which uses this as an input param. | |||
= PlayEvent = | |||
This is "nn::pdm::PlayEvent". | |||
This is a 0x38-byte struct and is the raw entry struct directly read from FS, without any entry filtering. The other structs are extracted+converted from this one, with filtering. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x1C || 0x1 || [[#PlayEventType]] | |||
|- | |||
| 0x1D || 0x3 || Padding | |||
|- | |||
| 0x20 || 0x8 || PosixTime timestamp from [[PCV_services|StandardUserSystemClock]]. | |||
|- | |||
| 0x28 || 0x8 || PosixTime timestamp from [[PCV_services|StandardNetworkSystemClock]]. | |||
|- | |||
| 0x30 || 0x8 || Timestamp in seconds derived from [[PCV_services|StandardSteadyClock]]. | |||
|} | |||
Filtering: | |||
* [[#QueryAppletEvent]], [[#QueryLastPlayTime]], and [[#QueryApplicationPlayStatisticsForSystem]]: PlayEvent +0x1C must be 0, and [[#PlayLogPolicy]] must be 0. [10.0.0+] These will also allow [[#PlayLogPolicy]] value 3, if the input flag is set. | |||
** With [[#QueryLastPlayTime]]/[[#QueryApplicationPlayStatisticsForSystem]] the [[Applet_Manager_services#AppletId|AppletId]] must be 1. [10.0.0+] These now also allow [[Applet_Manager_services#AppletId|AppletId]] 0x1F/0x20. | |||
* [[#QueryPlayStatisticsByApplicationId]]: PlayEvent +0x1C must be 0, +0xC must be 1 ([10.0.0+] or 0x1F/0x20), and the ProgramId must match. [10.0.0+] [[#PlayLogPolicy]] must be 0. Value 3 is allowed if the input flag is set. | |||
* [[#QueryAccountEvent]]: PlayEvent +0x1C must be 1 and PlayEvent +0x18 must be <=1. | |||
* [[#QueryApplicationPlayStatisticsForSystem]]: In addition to the above, this also handles [[#PlayEventType]] PowerStateChange, where PlayEvent +0x0 is value 0 or 1. | |||
The structure of the first 0x1C-bytes are determined by [[#PlayEventType]]. For ProgramIds/userIDs, the low/high u32 in each u64 is swapped. | |||
Applet: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ProgramId | |||
|- | |||
| 0x8 || 0x4 || Title version, set by pdm:ntfy [[#NotifyAppletEvent]] and [[#Cmd9]]. | |||
|- | |||
| 0x8 || 0x1 || When set to u8 0x1 by pdm:ntfy [[#Cmd8]], this indicates that +0x9 is set. Only used for non-applications. | |||
|- | |||
| 0x9 || 0x1 || See above. [[Applet_Manager_services#LibraryAppletMode|LibraryAppletMode]] | |||
|- | |||
| 0xC || 0x1 || [[Applet_Manager_services#AppletId|AppletId]] | |||
|- | |||
| 0xD || 0x1 || [[Filesystem_services#StorageId|StorageId]] | |||
|- | |||
| 0xE || 0x1 || [[#PlayLogPolicy]] | |||
|- | |||
| 0xF || 0x1 || [[#AppletEventType]] | |||
|- | |||
| 0x10 || 0xC || Unused | |||
|} | |||
Account: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x10 || userID | |||
|- | |||
| 0x10 || 0x8 || ProgramId, when u8 +0x18 = 2. | |||
|- | |||
| 0x18 || 0x1 || Type. 0-1 to be listed by [[#QueryAccountEvent]], or 2 to include the above ProgramId. | |||
|- | |||
| 0x19 || 0x3 || Padding | |||
|} | |||
PlayEventType PowerStateChange/OperationModeChange: u8 +0x0 is the input value from [[#NotifyOperationModeChangeEvent]]/[[#NotifyPowerStateChangeEvent]], the rest is unused. | |||
= AccountEvent = | |||
This is "nn::pdm::AccountEvent". | |||
This is a 0x38-byte ([10.0.0-15.0.1] 0x40-byte [3.0.0-9.2.0] 0x38-byte) struct. | |||
This was added with [3.0.0+]. | |||
[3.0.0-9.2.0]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x10 || userID | |||
|- | |||
| 0x10 || 0x4 || entryindex | |||
|- | |||
| 0x14 || 0x4 || Padding | |||
|- | |||
| 0x18 || 0x8 || [[#PlayEvent]] +0x20 | |||
|- | |||
| 0x20 || 0x8 || [[#PlayEvent]] +0x28 | |||
|- | |||
| 0x28 || 0x8 || [[#PlayEvent]] +0x30 | |||
|- | |||
| 0x30 || 0x1 || [[#PlayEvent]] +0x18 | |||
|- | |||
| 0x31 || 0x7 || Padding | |||
|} | |||
[10.0.0-15.0.1]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x10 || userID | |||
|- | |||
| 0x10 || 0x8 || ProgramId | |||
|- | |||
| 0x18 || 0x4 || entryindex | |||
|- | |||
| 0x1C || 0x4 || Padding | |||
|- | |||
| 0x20 || 0x8 || [[#PlayEvent]] +0x20 | |||
|- | |||
| 0x28 || 0x8 || [[#PlayEvent]] +0x28 | |||
|- | |||
| 0x30 || 0x8 || [[#PlayEvent]] +0x30 | |||
|- | |||
| 0x38 || 0x1 || [[#PlayEvent]] +0x18 | |||
|- | |||
| 0x39 || 0x7 || Padding | |||
|} | |||
[16.0.0+]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x10 || userID | |||
|- | |||
| 0x10 || 0x8 || ProgramId | |||
|- | |||
| 0x18 || 0x4 || entryindex | |||
|- | |||
| 0x1C || 0x4 || Padding | |||
|- | |||
| 0x20 || 0x8 || [[#PlayEvent]] +0x20 | |||
|- | |||
| 0x28 || 0x8 || [[#PlayEvent]] +0x28 | |||
|- | |||
| 0x30 || 0x1 || [[#PlayEvent]] +0x18 | |||
|- | |||
| 0x31 || 0x7 || Padding | |||
|} | |||
= AccountPlayEvent = | |||
This is "nn::pdm::AccountPlayEvent". | |||
This is a 0x28-byte struct and is the raw entry struct directly read from FS, without any entry filtering. This is separate from [[#PlayEvent]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || ? | |||
|- | |||
| 0x4 || 0x8 || ProgramId, with the u32 low/high words swapped. | |||
|- | |||
| 0xC || 0xC || ? | |||
|- | |||
| 0x18 || 0x8 || POSIX timestamp | |||
|- | |||
| 0x20 || 0x8 || POSIX timestamp | |||
|} | |||
= ApplicationPlayStatistics = | |||
This is "nn::pdm::ApplicationPlayStatistics". | |||
This is a 0x18-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x8 || ApplicationId | |||
|- | |||
| 0x8 || 0x8 || Total play-time in nanoseconds. | |||
|- | |||
| 0x10 || 0x8 || Total times the program was launched. | |||
|} | |||
= Notes = | |||
Various services are only available depending on the output of [[Process_Manager_services|pm:bm]] GetBootMode, see above. | |||
The func which initializes pl:* services calls a func, which then uses [[Process_Manager_services|pm:bm]] GetBootMode. This checks for BootMode Normal - the functionality here has no affect on whether pl:* services are available however. | |||
= FunctionBlackList = | |||
The FunctionBlackList SystemData contains "blacklist.json", which has the following structure (used by [[#pl:s|pl:s]]): | |||
* "compatibility_version": <number> (must be within 32bits) | |||
* "version": <number> (must be within 32bits) | |||
* "records": Array, each object entry can then contain: | |||
** "program_id" or "application_id": "0x<hex id>" (lowercase) | |||
** "function_id": "<function>", where <function> is the same as [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]] ("LocalNetworkMode", etc). | |||
** "function_id_raw": <number>, directly sets the [[#ApplicationFunctionAuthorizationId|ApplicationFunctionAuthorizationId]] value. | |||
** "type": "ApplicationUpdateRequired", "Prohibited", or "SystemUpdateRequired" | |||
** "type_raw": <number>, directly sets the value for the above "type". | |||
** "application": This object can contain: | |||
*** "version": <number> (must be within 32bits) | |||
** "system": This object can contain: | |||
*** "major": <number> (must be <=0xFF) | |||
*** "minor": <number> (must be <=0xFF) | |||
*** "micro": <number> (must be <=0xFF) | |||
The "blacklist.json" "compatibility_version" field is value 1, "version" is value 1, and the "records" array is empty. | |||
[S2] [20.1.0+] The "blacklist.json" "version" field is now value 4, and the "records" array is now filled in with entries for Applications ([19.0.0] same as NX). All records currently only have "function_id" = "Launch". There's currently no records with fields "program_id", or "*_raw". The "application" object in not present in records with "type" = "Prohibited". There's currently no records with "type" = "SystemUpdateRequired", and the "system" object is not present. | |||
The "application" "version" is the Patch [[CNMT|Version]]. | |||
There's records for both S1 and S2 Applications. The S2 Applications all have "function_id" = "Launch", "type" = "ApplicationUpdateRequired", "application" "version" = 0 (likewise with some S1 Applications). | |||
Note that in some cases there's records with ApplicationIds where the S2 Application is not (yet?) available on eShop. | |||
[[Category:Services]] |