Shared Database services: Difference between revisions

No edit summary
 
(38 intermediate revisions by 3 users not shown)
Line 1: Line 1:
= pl:u, pl:s =
= pl:s =
These are "nn::pl::detail::IPlatformServiceManager".
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 6: 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+] GetSharedFontInOrderOfPriorityForSystem
| 6 || [4.0.0-15.0.1] GetSharedFontInOrderOfPriorityForSystem
|-
|-
| 100 || [8.0.0+] RequestApplicationFunctionAuthorization
| 100 || [8.0.0+] RequestApplicationFunctionAuthorization
Line 25: Line 27:
|-
|-
| 102 || [10.0.0+] RequestApplicationFunctionAuthorizationByApplicationId
| 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
|-
| 108 || [20.0.0+] GetRequiredApplicationVersion
|-
|-
| 1000 || [9.0.0+] LoadNgWordDataForPlatformRegionChina
| 1000 || [9.0.0+] LoadNgWordDataForPlatformRegionChina
Line 58: Line 72:
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 [[#GetSharedFontAddress]].
Font data is TTF, located at the offset returned by [[#GetSharedMemoryAddressOffset]].


== GetSharedFontInOrderOfPriority ==
== GetSharedFontInOrderOfPriority ==
Line 89: Line 103:
= 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"
{| class="wikitable" border="1"
Line 155: Line 173:
|-
|-
| 25 || [7.0.0+] ConvertCharInfoToCoreData
| 25 || [7.0.0+] ConvertCharInfoToCoreData
|-
| 26 || [10.2.0+] Append
|-
| 27 || [19.0.0-19.0.1] ImportMigrationData
|}
|}


Line 161: Line 183:


This was added with [5.0.0+].
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 183: Line 207:
|-
|-
| 17 || DeleteImages
| 17 || DeleteImages
|-
| 18 || [19.0.0+] AddImageForMigration
|-
| 19 || [20.0.0+] ClearHeaderForMigration
|-
| 20 || [20.0.0+] SaveHeaderForMigration
|-
|-
| 100 || DeleteFile
| 100 || DeleteFile
Line 197: Line 227:
= pdm:ntfy =
= pdm:ntfy =
This is "nn::pdm::detail::INotifyService".
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 210: Line 244:
| 4 || [[#NotifyClearAllEvent]]
| 4 || [[#NotifyClearAllEvent]]
|-
|-
| 5 || [[#NotifyEventForDebug]]
| 5 || [2.0.0+] [[#NotifyEventForDebug]]
|-
|-
| 6 || [4.0.0+] SuspendUserAccountEventService
| 6 || [4.0.0+] SuspendUserAccountEventService
Line 219: Line 253:
|-
|-
| 9 || [8.0.0+]
| 9 || [8.0.0+]
|-
| 20 || [20.0.0+]
|-
| 100 || [20.0.0+]
|-
| 101 || [20.0.0+]
|}
|}


== NotifyAppletEvent ==
== 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 '''titleID'''. Returns no output.
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.
When [[#PlayLogPolicy]] is 2 ("None") this will immediately return 0.
Line 230: Line 270:
* u8 +0xF = [[#AppletEventType]].
* u8 +0xF = [[#AppletEventType]].
* Sets the 3 timestamps.
* Sets the 3 timestamps.
* Converts '''titleID''' and writes it to +0x0.
* Converts '''ProgramId''' and writes it to +0x0.
* u32 +0x8 = '''event_x8'''.
* u32 +0x8 = '''event_x8'''.
* u8 +0xC = [[Applet_Manager_services#AppletId|AppletId]], u8 +0xD = [[Filesystem_services#StorageId|StorageId]], and u8 +0xE = [[#PlayLogPolicy]].
* u8 +0xC = [[Applet_Manager_services#AppletId|AppletId]], u8 +0xD = [[Filesystem_services#StorageId|StorageId]], and u8 +0xE = [[#PlayLogPolicy]].
Line 259: Line 299:


== Cmd8 ==
== 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 '''titleID'''. Returns no output.
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]].
This is similar to [[#NotifyAppletEvent]].
Line 269: Line 309:
* u8 +0xF = [[#AppletEventType]].
* u8 +0xF = [[#AppletEventType]].
* Sets the 3 timestamps.
* Sets the 3 timestamps.
* Converts '''titleID''' and writes it to +0x0.
* Converts '''ProgramId''' and writes it to +0x0.
* u8 +0x9 = [[Applet_Manager_services#LibraryAppletMode|LibraryAppletMode]].
* u8 +0x9 = [[Applet_Manager_services#LibraryAppletMode|LibraryAppletMode]].
* u8 +0x8 = 1.
* u8 +0x8 = 1.
Line 279: Line 319:
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.
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.
[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.
This is identical to [[#NotifyAppletEvent]] except for the additional struct/flag params.
Line 286: Line 326:


[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:
[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.
* 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.
* 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.
* If [[#AppletEventType]] doesn't match any of these, nothing is done.


= pdm:qry =
= pdm:qry =
This is "nn::pdm::detail::IQueryService".
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"
{| class="wikitable" border="1"
Line 311: Line 356:
| 6 || [1.0.0-6.2.0] [[#QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId]]
| 6 || [1.0.0-6.2.0] [[#QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId]]
|-
|-
| 7 || [10.0.0+] [[#QueryLastPlayTimeV0]] ([1.0.0-9.2.0] QueryLastPlayTime)
| 7 || [10.0.0-14.1.2] [[#QueryLastPlayTimeV0]] ([1.0.0-9.2.0] QueryLastPlayTime)
|-
|-
| 8 || [[#QueryPlayEvent]]
| 8 || [[#QueryPlayEvent]]
Line 317: Line 362:
| 9 || [[#GetAvailablePlayEventRange]]
| 9 || [[#GetAvailablePlayEventRange]]
|-
|-
| 10 || [[#QueryAccountEvent]]
| 10 || [3.0.0+] [[#QueryAccountEvent]]
|-
|-
| 11 || [4.0.0+] [[#QueryAccountPlayEvent]]
| 11 || [4.0.0+] [[#QueryAccountPlayEvent]]
Line 323: Line 368:
| 12 || [4.0.0+] [[#GetAvailableAccountPlayEventRange]]
| 12 || [4.0.0+] [[#GetAvailableAccountPlayEventRange]]
|-
|-
| 13 || [10.0.0+] [[#QueryApplicationPlayStatisticsForSystemV0]] ([5.0.0-9.2.0] QueryApplicationPlayStatisticsForSystem)
| 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]]
|-
|-
| 14 || [6.0.0+] [[#QueryRecentlyPlayedApplication]]
| 18 || [10.0.0+] [[#QueryApplicationPlayStatisticsForSystem]]
|-
|-
| 15 || [6.0.0+] [[#GetRecentlyPlayedApplicationUpdateEvent]]
| 19 || [10.0.0+] [[#QueryApplicationPlayStatisticsByUserAccountIdForSystem]]
|-
|-
| 16 || [10.0.0+] [[#QueryApplicationPlayStatisticsByUserAccountIdForSystemV0]] ([6.0.0-9.2.0] QueryApplicationPlayStatisticsByUserAccountIdForSystem)
| 100 || [20.0.0+]
|-
|-
| 17 || [10.0.0+] QueryLastPlayTime
| 110 || [20.0.0+]
|-
|-
| 18 || [10.0.0+] QueryApplicationPlayStatisticsForSystem
| 118 || [20.0.0+]
|-
|-
| 19 || [10.0.0+] QueryApplicationPlayStatisticsByUserAccountIdForSystem
| 119 || [20.0.0+]
|}
|}


== QueryAppletEvent ==
== QueryAppletEvent ==
Takes 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.
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.
 
[10.0.0+] This now takes an additional 4-bytes of input.


== QueryPlayStatistics ==
== QueryPlayStatistics ==
Line 359: Line 410:


== QueryPlayStatisticsByApplicationId ==
== QueryPlayStatisticsByApplicationId ==
Takes an input u64 '''ApplicationId''' and returns an output [[#PlayStatistics]].
Takes ([10.0.0+] an input u8 bool), an input u64 '''ApplicationId''' and returns an output [[#PlayStatistics]].
 
[10.0.0+] This now takes an additional 8-bytes of input.


== QueryPlayStatisticsByApplicationIdAndUserAccountId ==
== QueryPlayStatisticsByApplicationIdAndUserAccountId ==
Takes an input u64 '''ApplicationId''', an input u128 '''Uid''' and returns an output [[#PlayStatistics]].
Takes ([10.0.0+] an input u8 bool), an input u64 '''ApplicationId''', an input u128 '''Uid''' and returns an output [[#PlayStatistics]].
 
[10.0.0+] This now takes an additional 8-bytes of input.


== QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId ==
== QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId ==
Line 375: Line 422:
== QueryLastPlayTimeV0 ==
== 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.
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 ==
== QueryPlayEvent ==
Line 395: Line 444:


The number of entries in each array is the same.
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 ==
== QueryRecentlyPlayedApplication ==
Takes 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.
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.


[10.0.0+] This now takes an additional 8-bytes of input.
Returns a list of applications played by the specified user.
 
Returns a list of titles played by the specified user.


== GetRecentlyPlayedApplicationUpdateEvent ==
== GetRecentlyPlayedApplicationUpdateEvent ==
Line 409: Line 458:


== QueryApplicationPlayStatisticsByUserAccountIdForSystemV0 ==
== QueryApplicationPlayStatisticsByUserAccountIdForSystemV0 ==
Takes a u128 '''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.
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'''.
Same as [[#QueryApplicationPlayStatisticsForSystem]] except this gets playstats specific to '''Uid'''.
Line 422: Line 486:
! Cmd || Name
! Cmd || Name
|-
|-
| 100 ||  
| 100 || [[#GetHighestAvailableVersion]]
|-
|-
| 101 ||  
| 101 || [[#GetHighestRequiredVersion]]
|-
|-
| 102 ||  
| 102 || [[#GetVersionListEntry]]
|-
|-
| 103 || No input, returns an [[#IVersionListImporter]].
| 103 || [[#GetVersionListImporter]]
|-
|-
| 200 ||  
| 200 || [[#GetLaunchRequiredVersion]]
|-
|-
| 202 ||  
| 202 || [[#UpgradeLaunchRequiredVersion]]
|-
|-
| 1000 ||  
| 1000 || [[#PushLaunchVersion]]
|-
|-
| 1001 ||  
| 1001 || [[#ListVersionList]]
|-
|-
| 1002 ||  
| 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 ==
== IVersionListImporter ==
Line 450: Line 547:
! Cmd || Name
! Cmd || Name
|-
|-
| 0 ||  
| 0 || [[#SetTimestamp]]
|-
|-
| 1 ||  
| 1 || [[#PushEntries]]
|-
|-
| 2 ||  
| 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.
|}
|}


Line 460: Line 598:
This is "nn::pdm::AppletEvent" ([1.0.0-7.0.1] "nn::pdm::ApplicationEvent").
This is "nn::pdm::AppletEvent" ([1.0.0-7.0.1] "nn::pdm::ApplicationEvent").


This is a 0x18-byte struct.
This is a 0x28-byte ([1.0.0-15.0.1] 0x18-byte) struct.  
 
Pre-16.0.0:


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 468: Line 608:
! Description
! Description
|-
|-
| 0x0 || 0x8 || titleID
| 0x0 || 0x8 || ProgramId
|-
|-
| 0x8 || 0x4 || entryindex
| 0x8 || 0x4 || entryindex
Line 482: Line 622:


Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00.
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 =
= PlayStatistics =
This is "nn::pdm::PlayStatistics".
This is "nn::pdm::PlayStatistics".


This is a 0x28-byte struct.
This is a 0x48-byte ([1.0.0-15.0.1] 0x28-byte) struct.
 
Pre-16.0.0:


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 494: Line 659:
! Description
! Description
|-
|-
| 0x0 || 0x8 || titleID
| 0x0 || 0x8 || ProgramId
|-
|-
| 0x8 || 0x4 || First entryindex
| 0x8 || 0x4 || First entryindex
Line 510: Line 675:
| 0x20 || 0x4 || Total play-time in minutes.
| 0x20 || 0x4 || Total play-time in minutes.
|-
|-
| 0x24 || 0x4 || Total times the application title was launched.
| 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
|}
|}


Line 516: Line 714:
This is "nn::pdm::LastPlayTime".
This is "nn::pdm::LastPlayTime".


This is a 0x18-byte struct and contains data from the last time the title was played.
This is a 0x18-byte struct and contains data from the last time the program was played.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 524: Line 722:
! Description
! Description
|-
|-
| 0x0 || 0x8 || titleID
| 0x0 || 0x8 || ApplicationId
|-
|-
| 0x8 || 0x4 || Same as the first [[#AppletEvent]] timestamp.
| 0x8 || 0x4 || Same as the first [[#AppletEvent]] timestamp.
Line 530: Line 728:
| 0xC || 0x4 || Same as the second [[#AppletEvent]] timestamp.
| 0xC || 0x4 || Same as the second [[#AppletEvent]] timestamp.
|-
|-
| 0x10 || 0x4 || Total minutes since the title was last played.
| 0x10 || 0x4 || Total minutes since the program was last played.
|-
|-
| 0x14 || 0x1 || Flag indicating whether the above field is set.
| 0x14 || 0x1 || Flag indicating whether the above field is set.
Line 591: Line 789:
|-
|-
| 2 || None || pdm:ntfy [[#NotifyAppletEvent]], [[#Cmd8]], and [[#Cmd9]] will immediately return 0 when the input param matches this value.
| 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.
|}
|}


Line 618: Line 818:


Filtering:
Filtering:
* [[#QueryAppletEvent]], [[#QueryLastPlayTime]], and [[#QueryApplicationPlayStatisticsForSystem]]: PlayEvent +0x1C must be 0, +0xC must be 1, and +0xE must be 0.
* [[#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.
* [[#QueryPlayStatisticsByApplicationId]]: PlayEvent +0x1C must be 0, +0xC must be 1, and the titleID must match.
** 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.
* [[#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.
* [[#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 titleIDs/userIDs, the low/high u32 in each u64 is swapped.
The structure of the first 0x1C-bytes are determined by [[#PlayEventType]]. For ProgramIds/userIDs, the low/high u32 in each u64 is swapped.


Applet:
Applet:
Line 632: Line 833:
! Description
! Description
|-
|-
| 0x0 || 0x8 || titleID
| 0x0 || 0x8 || ProgramId
|-
|-
| 0x8 || 0x4 || Title version, set by pdm:ntfy [[#NotifyAppletEvent]] and [[#Cmd9]].
| 0x8 || 0x4 || Title version, set by pdm:ntfy [[#NotifyAppletEvent]] and [[#Cmd9]].
Line 660: Line 861:
| 0x0 || 0x10 || userID
| 0x0 || 0x10 || userID
|-
|-
| 0x10 || 0x8 || titleID, when u8 +0x18 = 2.
| 0x10 || 0x8 || ProgramId, when u8 +0x18 = 2.
|-
|-
| 0x18 || 0x1 || Type. 0-1 to be listed by [[#QueryAccountEvent]], or 2 to include the above titleID.
| 0x18 || 0x1 || Type. 0-1 to be listed by [[#QueryAccountEvent]], or 2 to include the above ProgramId.
|-
|-
| 0x19 || 0x3 || Padding
| 0x19 || 0x3 || Padding
Line 672: Line 873:
This is "nn::pdm::AccountEvent".
This is "nn::pdm::AccountEvent".


This is a 0x38-byte struct.
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"
{| class="wikitable" border="1"
Line 691: Line 896:
|-
|-
| 0x28 || 0x8 || [[#PlayEvent]] +0x30
| 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
| 0x30 || 0x1 || [[#PlayEvent]] +0x18
Line 710: Line 967:
| 0x0 || 0x4 || ?
| 0x0 || 0x4 || ?
|-
|-
| 0x4 || 0x8 || titleID, with the u32 low/high words swapped.
| 0x4 || 0x8 || ProgramId, with the u32 low/high words swapped.
|-
|-
| 0xC || 0xC || ?
| 0xC || 0xC || ?
Line 730: Line 987:
! Description
! Description
|-
|-
| 0x0 || 0x8 || titleID
| 0x0 || 0x8 || ApplicationId
|-
|-
| 0x8 || 0x8 || Total play-time in nanoseconds.
| 0x8 || 0x8 || Total play-time in nanoseconds.
|-
|-
| 0x10 || 0x8 || Total times the application title was launched.
| 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]]
[[Category:Services]]