Difference between revisions of "Shared Database services"
(129 intermediate revisions by 7 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+]). | |
− | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 7: | Line 8: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
− | | 0 || [[#RequestLoad]] | + | | 0 || [1.0.0-15.0.1] [[#RequestLoad]] |
|- | |- | ||
− | | 1 || [[#GetLoadState]] | + | | 1 || [1.0.0-15.0.1] [[#GetLoadState]] |
|- | |- | ||
− | | 2 || [[#GetSize]] | + | | 2 || [1.0.0-15.0.1] [[#GetSize]] |
|- | |- | ||
− | | 3 || [[#GetSharedMemoryAddressOffset]] | + | | 3 || [1.0.0-15.0.1] [[#GetSharedMemoryAddressOffset]] |
|- | |- | ||
− | | 4 || [[#GetSharedMemoryNativeHandle]] | + | | 4 || [1.0.0-15.0.1] [[#GetSharedMemoryNativeHandle]] |
|- | |- | ||
− | | 5 || [[#GetSharedFontInOrderOfPriority]] | + | | 5 || [1.0.0-15.0.1] [[#GetSharedFontInOrderOfPriority]] |
+ | |- | ||
+ | | 6 || [4.0.0-15.0.1] GetSharedFontInOrderOfPriorityForSystem | ||
+ | |- | ||
+ | | 100 || [8.0.0+] RequestApplicationFunctionAuthorization | ||
+ | |- | ||
+ | | 101 || [8.0.0+] RequestApplicationFunctionAuthorizationByProcessId | ||
+ | |- | ||
+ | | 102 || [10.0.0+] RequestApplicationFunctionAuthorizationByApplicationId | ||
+ | |- | ||
+ | | 103 || [11.0.0+] RefreshApplicationFunctionBlackListDebugRecord | ||
+ | |- | ||
+ | | 104 || [11.0.0+] RequestApplicationFunctionAuthorizationByProgramId | ||
+ | |- | ||
+ | | 105 || [11.0.0+] GetFunctionBlackListSystemVersionToAuthorize | ||
+ | |- | ||
+ | | 106 || [11.0.0+] GetFunctionBlackListVersion | ||
+ | |- | ||
+ | | 107 || [17.0.0+] RequestApplicationFunctionAuthorizationByApplicationIdAndProgramId | ||
+ | |- | ||
+ | | 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 60: | ||
== 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 55: | Line 73: | ||
== 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 96: | ||
| 0x05 || Nintendo Extended | | 0x05 || Nintendo Extended | ||
|} | |} | ||
+ | |||
+ | * Nintendo Extended: Contains Nintendo-specific characters, including HID buttons, HID controller styles, applet icons, Wii(U) icons, etc. | ||
= 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+] 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" | {| class="wikitable" border="1" | ||
Line 83: | Line 188: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
− | | 0 || | + | | 0 || Initialize |
+ | |- | ||
+ | | 10 || Reload | ||
+ | |- | ||
+ | | 11 || GetCount | ||
+ | |- | ||
+ | | 12 || IsEmpty | ||
+ | |- | ||
+ | | 13 || IsFull | ||
+ | |- | ||
+ | | 14 || GetAttribute | ||
+ | |- | ||
+ | | 15 || LoadImage | ||
+ | |- | ||
+ | | 16 || AddOrUpdateImage | ||
+ | |- | ||
+ | | 17 || DeleteImages | ||
+ | |- | ||
+ | | 18 || [19.0.0+] AddImageForMigration | ||
+ | |- | ||
+ | | 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" | ||
+ | |- | ||
+ | ! Cmd || Name | ||
+ | |- | ||
+ | | 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+] | ||
+ | |} | ||
+ | |||
+ | == 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]] | ||
+ | |} | ||
+ | |||
+ | == 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. | ||
+ | |||
+ | = 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. | ||
+ | |||
+ | [[Category:Services]] |
Latest revision as of 20:23, 8 October 2024
pl:s
This is "nn::pl::detail::IPlatformServiceManagerForSystem". With [16.0.0+] "pl:u" was moved from here to glue.
"pl:s" has max_sessions 2 (5 with [16.0.0+]).
Cmd | Name |
---|---|
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 |
101 | [8.0.0+] RequestApplicationFunctionAuthorizationByProcessId |
102 | [10.0.0+] RequestApplicationFunctionAuthorizationByApplicationId |
103 | [11.0.0+] RefreshApplicationFunctionBlackListDebugRecord |
104 | [11.0.0+] RequestApplicationFunctionAuthorizationByProgramId |
105 | [11.0.0+] GetFunctionBlackListSystemVersionToAuthorize |
106 | [11.0.0+] GetFunctionBlackListVersion |
107 | [17.0.0+] RequestApplicationFunctionAuthorizationByApplicationIdAndProgramId |
1000 | [9.0.0+] LoadNgWordDataForPlatformRegionChina |
1001 | [9.0.0+] GetNgWordDataSizeForPlatformRegionChina |
RequestLoad
Takes a #SharedFontType (uint32), no output.
GetLoadState
Takes a #SharedFontType (uint32), returns the #LoadState (uint32).
LoadState
Value | Description |
---|---|
0x00 | Loading |
0x01 | Loaded |
GetSize
Takes a #SharedFontType (uint32), returns the Font Size (uint32).
Takes a #SharedFontType (uint32), returns the offset (uint32) to the Font Address.
No input, returns an output SharedMemory handle.
User-processes map this SharedMemory with size=0x1100000 and permissions=R--.
Font data is TTF, located at the offset returned by #GetSharedMemoryAddressOffset.
Takes an input u64 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 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
Value | Description |
---|---|
0x00 | Japan, US and Europe (Standard) |
0x01 | Chinese Simplified |
0x02 | Extended Chinese Simplified |
0x03 | Chinese Traditional |
0x04 | Korean (Hangul) |
0x05 | Nintendo Extended |
- Nintendo Extended: Contains Nintendo-specific characters, including HID buttons, HID controller styles, applet icons, Wii(U) icons, etc.
mii:u, mii:e
This is "nn::mii::detail::IStaticService".
These were moved from ns with [3.0.0+].
These are only available when the output from pm:bm GetBootMode is not Maintenance.
Cmd | Name |
---|---|
0 | GetDatabaseService |
IDatabaseService
This is "nn::mii::detail::IDatabaseService".
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+] ImportMigrationData |
miiimg
This is "nn::mii::detail::IImageDatabaseService".
This was added with [5.0.0+].
This is only available when the output from pm:bm GetBootMode is not Maintenance.
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 |
100 | DeleteFile |
101 | DestroyFile |
102 | ImportFile |
103 | ExportFile |
104 | ForceInitialize |
pdm:ntfy
This is "nn::pdm::detail::INotifyService".
This was moved from ns with [3.0.0+].
This is only available when the output from pm:bm GetBootMode is not Maintenance.
Cmd | Name |
---|---|
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+] |
NotifyAppletEvent
Takes an input u8 #AppletEventType, an u8 AppletId, an u8 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 = AppletId, u8 +0xD = 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-setting pdm!is_production
, 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 LibraryAppletMode, an u8 AppletId, an u8 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 = LibraryAppletMode.
- u8 +0x8 = 1.
- u8 +0xC = AppletId, u8 +0xD = 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 AppletId, an u8 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 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. 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 with [3.0.0+].
This is only available when the output from pm:bm GetBootMode is not Maintenance.
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 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 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+].
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+].
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.
VersionListEntry
This is a 0x10-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | Update Id. |
0x8 | 0x4 | Available version. |
0xC | 0x4 | Required version. |
RequiredVersionEntry
This is a 0x10-byte struct.
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:
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+]:
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:
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+]:
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.
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.
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.
Value | Description |
---|---|
0 | "launch" |
1 | "exit" |
2 | "in_focus" |
3 | "out_of_focus" |
4 | "out_of_focus" |
5 | "exit" |
6 | "exit" |
PlayLogPolicy
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.
Offset | Size | Description |
---|---|---|
0x1C | 0x1 | #PlayEventType |
0x1D | 0x3 | Padding |
0x20 | 0x8 | PosixTime timestamp from StandardUserSystemClock. |
0x28 | 0x8 | PosixTime timestamp from StandardNetworkSystemClock. |
0x30 | 0x8 | Timestamp in seconds derived from 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 AppletId must be 1. [10.0.0+] These now also allow 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:
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. LibraryAppletMode |
0xC | 0x1 | AppletId |
0xD | 0x1 | StorageId |
0xE | 0x1 | #PlayLogPolicy |
0xF | 0x1 | #AppletEventType |
0x10 | 0xC | Unused |
Account:
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]:
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]:
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+]:
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.
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.
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 pm:bm GetBootMode, see above.
The func which initializes pl:* services calls a func, which then uses pm:bm GetBootMode. This checks for BootMode Normal - the functionality here has no affect on whether pl:* services are available however.