Filesystem services
fsp-ldr
This is "nn::fssrv::sf::IFileSystemProxyForLoader".
Cmd | Name | Arguments | Notes |
---|---|---|---|
0 | OpenCodeFileSystem | u64 TitleId + X descriptor #ContentPath | Returns an #IFileSystem. |
1 | IsArchivedProgram | u64 ProcessId | Returns a bool (1 if code is mounted). |
2 | [4.0.0+] SetCurrentProcess | PID descriptor |
fsp-pr
This is "nn::fssrv::sf::IProgramRegistry".
Cmd | Name | Notes |
---|---|---|
0 | #RegisterProgram | |
1 | #UnregisterProgram | |
2 | [4.0.0+] SetCurrentProcess | |
256 | #SetEnabledProgramVerification |
RegisterProgram
Takes a storageID, a pid, a titleID, a 0x1C type-A buffer for the FS Access Header, and a 0x2C type-A buffer for the FS Access Control
Final FS permissions are stored as (ACI0_perms & ACID_perms). Will panic(svcBreak) when buffer sizes from ipc-rawdata are invalid.
UnregisterProgram
Takes a pid. Removes registered FS permissions for that PID.
SetEnabledProgramVerification
Seems to sets a global flag to inputval & 1.
When the flag is zero, it will set ret=0 instead of ret={error} when verifying the fixed-key NPDM ACID signature fails. This also skips verifying the NCA Header signature using the ACID key. Note that if verifying the fixed-key ACID signature is successful, and verifying the ACID-key NCA header signature fails, it will throw an error and abort.
fsp-srv
This is "nn::fssrv::sf::IFileSystemProxy".
Cmd | Name |
---|---|
0 | [1.0.0] #OpenFileSystem |
1 | #SetCurrentProcess |
2 | OpenDataFileSystemByCurrentProcess |
7 | [2.0.0+] #OpenFileSystemWithPatch |
8 | [2.0.0+] #OpenFileSystemWithId |
9 | [3.0.0+] OpenDataFileSystemByApplicationId |
11 | #OpenBisFileSystem |
12 | #OpenBisStorage |
13 | InvalidateBisCache |
17 | OpenHostFileSystem |
18 | OpenSdCardFileSystem |
19 | [2.0.0+] FormatSdCardFileSystem |
21 | #DeleteSaveDataFileSystem |
22 | #CreateSaveDataFileSystem |
23 | #CreateSaveDataFileSystemBySystemSaveDataId |
24 | RegisterSaveDataFileSystemAtomicDeletion |
25 | [2.0.0+] DeleteSaveDataFileSystemBySaveDataSpaceId |
26 | [2.0.0+] FormatSdCardDryRun |
27 | [2.0.0+] IsExFatSupported |
28 | [4.0.0+] DeleteSaveDataFileSystemBySaveDataAttribute |
30 | #OpenGameCardStorage |
31 | #OpenGameCardFileSystem |
32 | [3.0.0+] ExtendSaveDataFileSystem |
33 | [5.0.0+] DeleteCacheStorage |
34 | [5.0.0+] GetCacheStorageSize |
35 | [6.0.0+] ? (Takes a total of 0xB0-bytes of input, no output) |
51 | #OpenSaveDataFileSystem |
52 | #OpenSaveDataFileSystemBySystemSaveDataId |
53 | [2.0.0+] OpenReadOnlySaveDataFileSystem |
57 | [3.0.0+] ReadSaveDataFileSystemExtraDataBySaveDataSpaceId |
58 | ReadSaveDataFileSystemExtraData |
59 | [2.0.0+] WriteSaveDataFileSystemExtraData |
60 | #OpenSaveDataInfoReader |
61 | #OpenSaveDataInfoReaderBySaveDataSpaceId |
62 | [5.0.0+] OpenCacheStorageList |
64 | [5.0.0+] OpenSaveDataInternalStorageFileSystem |
65 | [5.0.0+] UpdateSaveDataMacForDebug |
66 | [5.0.0+] WriteSaveDataFileSystemExtraData2 |
67 | [6.0.0+] ? (Takes a total of 0x50-bytes of input, returns 8-bytes of output, and a type-0x6 output buffer) |
68 | [6.0.0+] ? (Takes a total of 0x50-bytes of input, returns an #ISaveDataInfoReader) |
80 | OpenSaveDataMetaFile |
81 | [4.0.0+] OpenSaveDataTransferManager (No input, returns an #ISaveDataTransferManager) |
82 | [5.0.0+] OpenSaveDataTransferManagerVersion2 (No input, returns an #ISaveDataTransferManagerWithDivision) |
83 | [6.0.0+] OpenSaveDataTransferProhibiterForCloudBackUp (Takes an input u64, returns an #ISaveDataTransferProhibiter) |
84 | [6.0.0+] ? (Takes a total of 0x10-bytes of input, returns 4-bytes of output, and a type-0x6 output buffer) |
100 | OpenImageDirectoryFileSystem |
110 | #OpenContentStorageFileSystem |
120 | [6.0.0+] ? (Takes 4-bytes of input, returns an #IFileSystem) |
200 | OpenDataStorageByCurrentProcess |
201 | [3.0.0+] OpenDataStorageByProgramId |
202 | #OpenDataStorageByDataId |
203 | OpenPatchDataStorageByCurrentProcess |
400 | #OpenDeviceOperator |
500 | #OpenSdCardDetectionEventNotifier |
501 | #OpenGameCardDetectionEventNotifier |
510 | [5.0.0+] OpenSystemDataUpdateEventNotifier |
511 | [5.0.0+] NotifySystemDataUpdateEvent |
520 | [6.0.0+] ? (Takes a total of 0xC-bytes of input, no output) |
600 | [1.0.0-3.0.2] SetCurrentPosixTime |
601 | QuerySaveDataTotalSize |
602 | #VerifySaveDataFileSystem |
603 | CorruptSaveDataFileSystem |
604 | CreatePaddingFile |
605 | DeleteAllPaddingFiles |
606 | [2.0.0+] GetRightsId |
607 | [2.0.0+] RegisterExternalKey |
608 | [2.0.0+] UnregisterAllExternalKey |
609 | [2.0.0+] GetRightsIdByPath |
610 | [3.0.0+] GetRightsIdAndKeyGenerationByPath |
611 | [4.0.0+] SetCurrentPosixTimeWithTimeDifference |
612 | [4.0.0+] GetFreeSpaceSizeForSaveData |
613 | [4.0.0+] VerifySaveDataFileSystemBySaveDataSpaceId |
614 | [4.0.0+] CorruptSaveDataFileSystemBySaveDataSpaceId |
615 | [5.0.0+] QuerySaveDataInternalStorageTotalSize |
616 | [6.0.0+] #GetSaveDataCommitId |
620 | [2.0.0+] #SetSdCardEncryptionSeed |
630 | [4.0.0+] SetSdCardAccessibility |
631 | [4.0.0+] IsSdCardAccessible |
640 | [4.0.0+] IsSignedSystemPartitionOnSdCardValid |
700 | [5.0.0+] OpenAccessFailureResolver |
701 | [5.0.0+] GetAccessFailureDetectionEvent |
702 | [5.0.0+] IsAccessFailureDetected |
710 | [5.0.0+] ResolveAccessFailure |
720 | [5.0.0+] AbandonAccessFailure |
800 | [2.0.0+] GetAndClearFileSystemProxyErrorInfo |
1000 | SetBisRootForHost |
1001 | SetSaveDataSize |
1002 | SetSaveDataRootPath |
1003 | DisableAutoSaveDataCreation |
1004 | #SetGlobalAccessLogMode |
1005 | #GetGlobalAccessLogMode |
1006 | #OutputAccessLogToSdCard |
1007 | [4.0.0+] RegisterUpdatePartition |
1008 | [4.0.0+] OpenRegisteredUpdatePartition |
1009 | [4.0.0+] GetAndClearMemoryReportInfo |
1010 | [5.1.0+] |
1100 | [4.0.0+] OverrideSaveDataTransferTokenSignVerificationKey |
1200 | [6.0.0+] ? (No input, returns an output #IMultiCommitManager) |
Permissions
Every time permissions are checked, the process registration #fsp-pr is loaded using the session processID. The permission data is populated with data from the NPDM.
If the processID is <= 6 (which happens only for built-in sysmodules), it will use a hardcoded registration data. The default mask in this case is 0x8000000000000000.
Note that the functions check whether or not at least one bit is set in the mask. This means that, you don't need to set 0xFFFFFFFFFFFFFFFF to get all permissions: it suffices to set 0x8000000000000000.
If the code were to request an invalid input type, panic. But this never happens.
RwPermissions
Type(s) | Mask | Name | Value | Used by |
---|---|---|---|---|
0x0 | 0x8000000000000801 | MountLogo | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x1 | 0x8000000000000801 | MountContentMeta | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x2 | 0x8000000000000801 | MountContentControl | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x3 | 0x8000000000000801 | MountContentManual | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x4 | 0x8000000000000801 | MountContentData | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x5 | 0x8000000000000801 | MountApplicationPackage | 1 | #OpenFileSystem, #OpenFileSystemWithPatch, #OpenFileSystemWithId |
0x6 | 0x8000000000000000 | 3 | ||
0x7 | 0x8000000000000800 | ContentStorageAccess | 3 | #OpenContentStorageFileSystem |
0x8 | 0x8000000000001000 | ImageDirectoryAccess | 3 | #OpenImageDirectoryFileSystem |
0x9 | 0x8000000000000084 | OpenBisFileSystemType28, OpenBisFileSystemType32 | 3 | #OpenBisFileSystem |
0xA | 0x8000000000000080 | OpenBisFileSystemType29 | 3 | #OpenBisFileSystem |
0xB | 0x8000000000008080 | OpenBisFileSystemType30 | 3 | #OpenBisFileSystem |
0xC | 0x8000000000008080 | OpenBisFileSystemType31 | 3 | #OpenBisFileSystem |
0xD | 0x8000000000000080 | 3 | ||
0xE | 0x8000000000000080 ([1.0.0-2.3.0] 0xC000000000200000) | OpenBisFileSystemType33 | 3 | #OpenBisFileSystem |
0xF | 0xC000000000200000 ([1.0.0-2.3.0] 0x8000000000000010) | SdCardAccess | 3 | #OpenSdCardFileSystem |
0x10 | 0x8000000000000010 ([1.0.0-2.3.0] 0x8000000000040020) | GameCardUser | 3 | #OpenGameCardFileSystem |
0x11 | 0x8000000000040020 ([1.0.0-2.3.0] 0x8000000000000028) | SaveDataAccess0 | 3 | #OpenSaveDataFileSystem |
0x12 | 0x8000000000000028 ([1.0.0-2.3.0] 0x8000000000000020) | SystemSaveDataAccess0 | 3 | #OpenSaveDataFileSystemBySystemSaveDataId |
0x13 | 0x8000000000000020 | SaveDataAccess1 | 3 | #OpenSaveDataFileSystem |
0x14 | 0x8000000000000020 ([1.0.0-2.3.0] 0x8000000000010082) | SystemSaveDataAccess1 | 3 | #OpenSaveDataFileSystemBySystemSaveDataId |
0x15 | 0x8000000000010082 ([1.0.0-2.3.0] 0x8000000000010080) | BisPartition0 | 3 | #OpenBisStorage |
0x16 | 0x8000000000010080 | BisPartition10 | 3 | #OpenBisStorage |
0x17 | 0x8000000000000080 ([1.0.0-2.3.0] 0x8000000000010080) | BisPartition20 | 3 | #OpenBisStorage |
0x18 | 0x8000000000010080 | BisPartition21 | 3 | #OpenBisStorage |
0x19 | 0x8000000000010080 | BisPartition22 | 3 | #OpenBisStorage |
0x1A | 0x8000000000010080 | BisPartition23 | 3 | #OpenBisStorage |
0x1B | 0x8000000000010080 | BisPartition24 | 3 | #OpenBisStorage |
0x1C | 0x8000000000010080 | BisPartition25 | 3 | #OpenBisStorage |
0x1D | 0x8000000000010080 ([1.0.0-2.3.0] 0x8000000000000084) | BisPartition26 | 3 | #OpenBisStorage |
0x1E | 0x8000000000000084 | BisPartition27 | 3 | #OpenBisStorage |
0x1F | 0x8000000000000084 ([1.0.0-2.3.0] 0x8000000000000080) | BisPartition28 | 3 | #OpenBisStorage |
0x20 | 0x8000000000000080 | BisPartition29 | 3 | #OpenBisStorage |
0x21 | 0x8000000000000080 | BisPartition30 | 3 | #OpenBisStorage |
0x22 | 0x8000000000000080 | BisPartition31 | 3 | #OpenBisStorage |
0x23 | 0x8000000000000080 ([1.0.0-2.3.0] 0xC000000000200000) | BisPartition32 | 3 | #OpenBisStorage |
0x24 | 0x8000000000000080 ([1.0.0-2.3.0] 0x8000000000000100) | BisPartition33 | 3 | #OpenBisStorage |
0x25 | 0xC000000000200000 ([1.0.0-2.3.0] 0x8000000000100008) | |||
0x26 | 0x8000000000000100 ([1.0.0-2.3.0] 0xC000000000400000) | GameCard_System | 3 | #OpenGameCardStorage, #EraseGameCard (bit1), #WriteToGameCard (bit1), #GetGameCardErrorInfo (bit1), #EraseAndWriteParamDirectly (bit1), #ReadParamDirectly (bit1), #ForceEraseGameCard (bit1) |
[3.0.0+] 0x27 | 0x8000000000100008 | MountContent_System | 1 | #OpenFileSystem, #OpenDataStorageByDataId |
[3.0.0+] 0x28 | 0xC000000000400000 | HostAccess | 3 | #OpenHostFileSystem |
[4.0.0+] 0x29 | 0x8000000000010000 | RegisteredUpdatePartitionAccess | 1 | #OpenRegisteredUpdatePartition |
[5.0.0+] 0x2A | 0x8000000000000000 | SaveDataInternalStorageAccess | 3 | #OpenSaveDataInternalStorageFileSystem |
BoolPermissions
Type(s) | Mask | Name | Used by |
---|---|---|---|
0x0 | 0x8000000000000080 | BisCache | #InvalidateBisCache |
0x1 | 0x8000000000000080 | EraseMmc | #EraseMmc |
0x2 | 0x8000000000000010 | GameCardCertificate | #GetGameCardDeviceCertificate |
0x3 | 0x8000000000000010 | GameCardIdSet | #GetGameCardIdSet |
0x4 | 0x8000000000000200 | GameCardDriver | #FinalizeGameCardDriver |
0x5 | 0x8000000000000200 | GameCardAsic | #GetGameCardAsicInfo |
0x6 | 0x8000000000002020 | SaveDataCreate | #CreateSaveDataFileSystem |
0x7 | 0x8000000000000060 | SaveDataDelete0 | #DeleteSaveDataFileSystem, #RegisterSaveDataFileSystemAtomicDeletion |
0x8 | 0x8000000000000028 | SystemSaveDataCreate0 | #CreateSaveDataFileSystemBySystemSaveDataId |
0x9 | 0x8000000000000020 | SystemSaveDataCreate1 | #CreateSaveDataFileSystemBySystemSaveDataId |
0xA | 0x8000000000004028 | SaveDataDelete1 | #DeleteSaveDataFileSystem, #RegisterSaveDataFileSystemAtomicDeletion |
0xB | 0x8000000000000060 | SaveDataInfoReader0 | #OpenSaveDataInfoReaderBySaveDataSpaceId, #OpenSaveDataInfoReader |
0xC | 0x8000000000004020 | SaveDataInfoReader1 | #OpenSaveDataInfoReaderBySaveDataSpaceId, #OpenSaveDataInfoReader |
0xD | 0x8000000000020000 | SaveDataMeta | #OpenSaveDataMetaFile |
0xE | 0x8000000000000400 | PosixTime | #SetCurrentPosixTime, #SetCurrentPosixTimeWithTimeDifference |
0xF | 0x8000000000004060 | SaveDataExtraData_Read | #ReadSaveDataFileSystemExtraData |
0x10 | 0x8000000000080000 | GlobalAccessMode | #SetGlobalAccessMode |
0x11 | 0x8000000000080000 | SpeedEmulationMode | #SetSpeedEmulationMode |
0x12 | Invalid | ||
0x13 | 0xC000000000800000 | PaddingFiles | #CreatePaddingFile, #DeleteAllPaddingFiles |
0x14 | 0xC000000001000000 | SaveDataCorrupt0 | #CorruptSaveDataFileSystem, #CorruptSaveDataFileSystemBySaveDataSpaceId |
0x15 | 0x8000000001000060 ([1.0.0-4.1.0] 0xC000000002000000) | SaveDataCorrupt1 | #CorruptSaveDataFileSystem, #CorruptSaveDataFileSystemBySaveDataSpaceId |
[2.0.0+] 0x16 | 0x8000000000000060 ([1.0.0-4.1.0] 0x8000000004000000) | SaveDataVerify | #VerifySaveDataFileSystem, #VerifySaveDataFileSystemBySaveDataSpaceId |
[2.0.0+] 0x17 | 0xC000000002000000 ([1.0.0-4.1.0] 0x8000000008000000) | SaveData_SystemManagement | #CreateSaveDataFileSystem, #OpenSaveDataFileSystem, #SetSaveDataRootPath |
[2.0.0+] 0x18 | 0x8000000004000000 ([1.0.0-4.1.0] 0x8000000010000000) | SdCardFormat | #FormatSdCardFileSystem |
[2.0.0+] 0x19 | 0x8000000008000000 ([1.0.0-4.1.0] 0x8000000000000800) | RightsId | #GetRightsId, #GetRightsIdAndKeyGenerationByPath, #GetRightsIdByPath |
[2.0.0+] 0x1A | 0x8000000010000000 ([1.0.0-4.1.0] 0x8000000000004020) | ExternalKey | #RegisterExternalKey, #UnregisterAllExternalKey |
[3.0.0+] 0x1B | 0x8000000000000800 ([1.0.0-4.1.0] 0x8000000000002020) | SdCardEncryptionSeed | #SetSdCardEncryptionSeed |
[3.0.0+] 0x1C | 0x8000000000004020 ([1.0.0-4.1.0] 0x8000000000000028) | SaveDataExtraData_Write0 | #WriteSaveDataFileSystemExtraData, #WriteSaveDataFileSystemExtraData2 |
[4.0.0+] 0x1D | 0x8000000000000000 ([1.0.0-4.1.0] 0x8000000020000000) | SaveDataExtraData_Write1 | #WriteSaveDataFileSystemExtraData, #WriteSaveDataFileSystemExtraData2 |
[4.0.0+] 0x1E | 0x8000000000002020 ([1.0.0-4.1.0] 0x8000000040000000) | SaveDataExtend0 | #ExtendSaveDataFileSystem |
[4.0.0+] 0x1F | 0x8000000000000028 ([1.0.0-4.1.0] 0x8000000000000000) | SaveDataExtend1 | #ExtendSaveDataFileSystem |
[4.0.0+] 0x20 | 0x8000000020000000 ([1.0.0-4.1.0] 0x8000000000000000) | UpdatePartitionRegister | #RegisterUpdatePartition |
[5.0.0+] 0x21 | 0x8000000040000000 | SaveDataTransfer | #OpenSaveDataTransferManager |
[5.0.0+] 0x22 | 0x0000000080000002 | SaveDataTransferVersion2 | #OpenSaveDataTransferManagerVersion2 |
[5.0.0+] 0x23 | 0x8000000000000000 | MmcPatrol | #SuspendMmcPatrol, #ResumeMmcPatrol |
[5.0.0+] 0x24 | 0x8000000000000000 | SaveDataTransferKey | #OverrideSaveDataTransferTokenSignVerificationKey |
[5.0.0+] 0x25 | 0x8000000080200000 | SdCardDetectionEventNotifier | #OpenSdCardDetectionEventNotifier |
[5.0.0+] 0x26 | 0x8000000080000110 | GameCardDetectionEventNotifier | #OpenGameCardDetectionEventNotifier |
[5.0.0+] 0x27 | 0x8000000000100008 | SystemDataUpdateEventNotifier | #OpenSystemDataUpdateEventNotifier |
[5.0.0+] 0x28 | 0x8000000080010000 | SystemDataUpdateEventNotify | #NotifySystemDataUpdateEvent |
[5.0.0+] 0x29 | 0x0000000080000001 | AccessFailureResolver | #OpenAccessFailureResolver |
[5.0.0+] 0x2A | 0x0000000080000001 | AccessFailureDetectionEvent | #GetAccessFailureDetectionEvent |
[5.0.0+] 0x2B | 0x0000000080000001 | AccessFailureDetected | #IsAccessFailureDetected |
[5.0.0+] 0x2C | 0x0000000080000001 | AccessFailureResolve | #ResolveAccessFailure |
[5.0.0+] 0x2D | 0x0000000080000001 | AccessFailureAbandon | #AbandonAccessFailure |
[5.0.0+] 0x2E | 0x8000000040000000 | SaveDataInternalStorageTotalSize | #QuerySaveDataInternalStorageTotalSize |
[5.0.0+] 0x2F | 0x8000000080200000 | SdCardAccessibility | #SetSdCardAccessibility |
[5.1.0+] 0x30 | 0x8000000080080000 |
OpenFileSystem
Takes a type-0x19 input buffer (ContentPath) and a #FileSystemType as parameters. Returns an #IFileSystem.
[2.0.0+] This function was removed.
SetCurrentProcess
Takes a pid-descriptor.
OpenFileSystemWithPatch
Takes an input #FileSystemType and an u64 title-id. Returns an #IFileSystem.
Web-applet loads the #FileSystemType (which must be ContentManual) from u32_table[inparam].
Note: web-applet strings refer to both this cmd and #OpenFileSystemWithId as "MountContent", but official nn_sf_sync symbols use "OpenXX" names.
OpenFileSystemWithId
Takes a type-0x19 input buffer, an #FileSystemType and an u64 title-id. Returns an #IFileSystem.
The #IFileSystem must be ContentMeta if the NCA type is 0 (control).
The input buffer is the output string path from GetApplicationContentPath.
May return errors when attempting to access NCA-paths for an update-title with a gamecard, when the gamecard isn't inserted. May return error 0x7D402 in some cases with update-titles. Non-val2 in32 values with NCA-type1 are unusable, even for normal titles.
The official "MountApplicationPackage" func uses this with in64=0 and #FileSystemType ApplicationPackage.
After the #FileSystemType specific permissions are checked, it then gets the func retval for permissions-type 0x25 and func0.
When #FileSystemType is ContentMeta, it uses in64=0xffffffffffffffff internally, otherwise it checks if in64 is set to 0xffffffffffffffff then throws an error if so. When the in64 used internally is not 0xffffffffffffffff, it's compared with the NCA titleID, then an error is thrown on mismatch.
OpenBisFileSystem
Takes a type-0x19 input buffer string and a u32 Bis partitionID. Official user-process code sets instr[0] = 0 normally. Returns an #IFileSystem.
Only partitionIDs for FAT partitions are usable with this, otherwise error 0x2EE202 is returned. Seems to be about the same as #OpenBisStorage except this mounts the partition filesystem instead of allowing direct access to the partition sectors.
OpenBisStorage
Takes a u32 partition ID, returns 0x2EE202 for partitions which do not exist, 0x320002 for partitions which cannot be opened and a valid #IStorage handle otherwise.
InvalidateBisCache
Seems to invalidate the Bis cache for MBR/GPT after overwriting that data via the OpenBisStorage IStorage. Used by SystemInitializer.
DeleteSaveDataFileSystem
Takes an input u64.
CreateSaveDataFileSystem
Takes a 0x40-byte Save-struct entry, a 0x40-byte SaveCreate-struct entry, and a 0x10-byte input struct.
Only the first 0x5-bytes in the 0x10-byte struct are initialized: all-zero when automatically creating savedata during savecommon mount by official user-processes. In the dedicated save-creation code in official user-processes: +0 u32 = 0x40060, +4 u8 = 1.
Creates regular savedata.
CreateSaveDataFileSystemBySystemSaveDataId
Takes a 0x40-byte Save-struct entry and a 0x40-byte SaveCreate-struct entry.
Creates savedata in the SYSTEM NAND partition.
OpenGameCardStorage
Takes two input u32s (gamecard handle, partition ID), and returns an #IStorage for the partition.
OpenGameCardFileSystem
Takes two input u32s, with the second u32 located at +4 in rawdata after the first u32. Returns an #IFileSystem.
Mounts a gamecard partition.
OpenSaveDataFileSystem
Takes an input u8 #SaveDataSpaceId and a 0x40-byte Save-struct entry. Official user-process code is only known to use value 1 for the u8.
Returns an #IFileSystem.
Permissions aren't checked until the specified save is successfully found.
Only one process (specifically only one #IFileSystem session) can mount a given savedata at any given time (this includes SystemSaveData).
OpenSaveDataFileSystemBySystemSaveDataId
Takes an input u8 #SaveDataSpaceId and a 0x40-byte Save-struct entry. Web-applet only uses value0 for the input u8.
Returns an #IFileSystem.
Mounts savedata in the SYSTEM NAND partition.
OpenSaveDataInfoReader
No input, returns an output #ISaveDataInfoReader.
OpenSaveDataInfoReaderBySaveDataSpaceId
Takes an input u8 #SaveDataSpaceId, returns an output #ISaveDataInfoReader.
OpenContentStorageFileSystem
Takes a #ContentStorageId. Invalid values return 0x2EE202.
Returns an #IFileSystem with NCA files. The read data from these files is identical to the data read by Content_Manager_services#ReadEntryRaw.
OpenDataStorageByDataId
Takes a #StorageId and a TitleID.
Returns a domain object ID implementing the #IStorage interface for data archives.
OpenDeviceOperator
This command returns a session to a port implementing the #IDeviceOperator interface.
OpenSdCardDetectionEventNotifier
This command returns a session to a port implementing the #IEventNotifier interface.
OpenGameCardDetectionEventNotifier
This command returns a session to a port implementing the #IEventNotifier interface.
VerifySaveDataFileSystem
Takes an unknown input u64 and a type-0x6 output buffer.
The input u64 high-byte must be non-zero, otherwise an error is returned(0xE02).
GetSaveDataCommitId
Takes an input u8 and u64, returns an output u64.
SetSdCardEncryptionSeed
Takes in the 0x10 byte SD card encryption seed, and loads it into FS-module state.
NS-module reads the 0x10 bytes from SdCard:/Nintendo/Contents/private, and compares them to the first 0x10 bytes of the ns_appman:/private (in system savedata 0x8000000000000043). If they match, NS calls this command using bytes 0x10-0x20 from ns_appman:/private. The rest of this file (0x1F0 bytes total) is (usually/always?) all-zero.
SetGlobalAccessLogMode
Takes an input u32.
GetGlobalAccessLogMode
Returns an output u32.
GlobalAccessLogMode is normally 0.
OutputAccessLogToSdCard
Takes a type-0x5 input buffer.
The input buffer is the string to output to the log. User-processes normally include a newline at the end.
User-processes only use this when the value previously loaded from #GetGlobalAccessLogMode has bit1 set.
When bit1 in GlobalAccessLogMode is clear, FS-module will just return 0 for OutputAccessLogToSdCard. However even with that set the log doesn't show up SD, unknown why.
The input buffer is written to the "$FsAccessLog:/FsAccessLog.txt" file, where "$FsAccessLog" is the SD-card mount-name. It's written to the current end of the file(appended).
IStorage
This is "nn::fssrv::sf::IStorage".
This is the interface for a raw device, usually a block device.
Cmd | Name | Arguments |
---|---|---|
0 | Read | Takes a type-0x46 buffer, an offset and length |
1 | Write | Takes a type-0x45 buffer, an offset and length |
2 | Flush | None |
3 | SetSize | Takes a size |
4 | GetSize | None |
5 | [4.0.0+] OperateRange |
IFileSystem
This is "nn::fssrv::sf::IFileSystem".
There are two main implementations of this interface:
- RomFS: Filesystem implementation statically linked in the binary. Uses an #IStorage interface as underlying raw device.
- IPC proxy: Used for all non-RomFS filesystems. In this case, actual filesystem implementation is in the FS process.
Cmd | Name |
---|---|
0 | CreateFile |
1 | DeleteFile |
2 | CreateDirectory |
3 | DeleteDirectory |
4 | DeleteDirectoryRecursively |
5 | RenameFile |
6 | RenameDirectory |
7 | #GetEntryType |
8 | #OpenFile |
9 | #OpenDirectory |
10 | #Commit |
11 | #GetFreeSpaceSize |
12 | #GetTotalSpaceSize |
13 | [3.0.0+] #CleanDirectoryRecursively |
14 | [3.0.0+] GetFileTimeStampRaw |
15 | [4.0.0+] QueryEntry |
GetEntryType
Takes a type-0x9 input buffer for the path and returns #DirectoryEntryType as an output u32.
OpenFile
Takes a type-0x19 input buffer for the path, and an u32 mode. mode controls how the file is opened, based on which bits are set:
- When bit 0 is set, the file is Readable: you can use the Read operation.
- When bit 1 is set, the file is Writable: you can use the Write operation.
- When bit 2 is set, the file is Appendable: unless this bit is set, you will not be able to write beyond the end of a file (such writes will result in an error 0x307202)
OpenDirectory
Takes a type-0x9 input buffer for the path and an u64 filter_flags. filter_flags controls what type of entries are read by the #IDirectory: bitmask 0x1 = directories, bitmask 0x2 = files.
Commit
Like 3DS, this has to be used after writing to savedata for the changes to take affect.
GetFreeSpaceSize
Takes a type-0x9 input buffer for the path and returns an output byte-size u64 for the total free space with this FS.
GetTotalSpaceSize
Takes a type-0x9 input buffer for the path and returns an output byte-size u64 for the total space available with this FS(free+used).
CleanDirectoryRecursively
Takes a type-0x9 input buffer for the path and clears the contents of the directory specified in the path.
IDirectory
This is "nn::fssrv::sf::IDirectory".
Cmd | Name |
---|---|
0 | #Read |
1 | #GetEntryCount |
Read
Takes a type-0x6 output buffer. Returns an output u64(?) for the total number of read entries, this is 0 when no more entries are available.
The output buffer contains the read array of #DirectoryEntry. This doesn't include entries for "." and "..".
GetEntryCount
Returns an u64 for the total number of readable entries.
DirectoryEntry
Offset | Size | Description |
---|---|---|
0x0 | 0x300 | Path |
0x300 | 0x4 | ? |
0x304 | 0x1 | #DirectoryEntryType |
0x305 | 0x3 | Padding? |
0x308 | 0x8? | Filesize, 0 for directories. |
DirectoryEntryType
s8 type: 0 = directory, 1 = file.
IFile
This is "nn::fssrv::sf::IFile".
Cmd | Name |
---|---|
0 | Read |
1 | Write |
2 | Flush |
3 | SetSize |
4 | GetSize |
5 | [4.0.0+] OperateRange |
ISaveDataInfoReader
This is "nn::fssrv::sf::ISaveDataInfoReader".
Cmd | Name |
---|---|
0 | #ReadSaveDataInfo |
ReadSaveDataInfo
Takes a type-0x6 output buffer. Returns an output u64 for total output entries. This buffer contains an array of #SaveDataInfo.
This is used to get #SaveDataInfo for all savedata on the system (or all savedata for the current #SaveDataSpaceId). When used multiple times, it will resume reading where it left off, until no more entries are available (in that case the out u64 is value 0).
IDeviceOperator
This is "nn::fssrv::sf::IDeviceOperator".
Cmd | Name |
---|---|
0 | IsSdCardInserted |
1 | GetSdCardSpeedMode |
2 | [2.0.0+] GetSdCardCid |
3 | [2.0.0+] GetSdCardUserAreaSize |
4 | [2.0.0+] GetSdCardProtectedAreaSize |
5 | [2.0.0+] GetAndClearSdCardErrorInfo |
100 | GetMmcCid |
101 | GetMmcSpeedMode |
110 | EraseMmc |
111 | GetMmcPartitionSize |
112 | [2.0.0+] GetMmcPatrolCount |
113 | [2.0.0+] GetAndClearMmcErrorInfo |
114 | [2.0.0+] GetMmcExtendedCsd |
115 | [4.0.0+] SuspendMmcPatrol |
116 | [4.0.0+] ResumeMmcPatrol |
200 | IsGameCardInserted |
201 | EraseGameCard |
202 | GetGameCardHandle |
203 | #GetGameCardUpdatePartitionInfo |
204 | FinalizeGameCardDriver |
205 | GetGameCardAttribute |
206 | GetGameCardDeviceCertificate |
207 | GetGameCardAsicInfo |
208 | GetGameCardIdSet |
209 | WriteToGameCard |
210 | SetVerifyWriteEnalbleFlag |
211 | GetGameCardImageHash |
212 | [2.0.0+] GetGameCardErrorInfo |
213 | [2.0.0+] EraseAndWriteParamDirectly |
214 | [2.0.0+] ReadParamDirectly |
215 | [2.0.0+] ForceEraseGameCard |
216 | [2.0.0+] GetGameCardErrorInfo2 |
217 | [2.1.0+] GetGameCardErrorReportInfo |
218 | [3.0.0+] GetGameCardDeviceId |
300 | SetSpeedEmulationMode |
301 | GetSpeedEmulationMode |
400 | [5.0.0+] SuspendSdmmcControl |
401 | [5.0.0+] ResumeSdmmcControl |
402 | [6.0.0+] ? (Takes a total of 4-bytes of input, returns a total of 8-bytes of output) |
500 | [6.0.0+] ? (Takes a total of 0x14-bytes of input, no output) |
501 | [6.0.0+] ? (Takes a total of 4-bytes of input, no output) |
ISaveDataTransferProhibiter
This doesn't seem to handle any commands (?).
GetGameCardUpdatePartitionInfo
Returns a titleID and the title-version for it.
- Output u32 with ARMS-gamecard: title-version v131162. This is the title-version for 2.1.0, which is the sysupdate included with this gamecard. Launch-day gamecards return title-version v450.
- Output u64 with ARMS-gamecard: titleID 0100000000000816.
NS appears to only use this with Content_Manager_services#GetTitleIdInfo and Content_Manager_services#GetUpdateTitleList with storageid=nandsys, for checking whether a sysupdate is required.
IEventNotifier
This is "nn::fssrv::sf::IEventNotifier".
Cmd | Name |
---|---|
0 | GetEventHandle |
IUnknown1
Cmd | Name |
---|---|
1 | ? (Takes an input #IFilesystem, no output) |
2 | ? (No input/output) |
This was added with 6.0.0.
FileSystemType
Value | Name |
---|---|
0 | Invalid |
1 | Invalid |
2 | Logo |
3 | ContentControl |
4 | ContentManual |
5 | ContentMeta |
6 | ContentData |
7 | ApplicationPackage |
StorageId
Value | Name |
---|---|
0 | None |
1 | Host |
2 | GameCard |
3 | NandSystem |
4 | NandUser |
5 | SdCard |
ContentStorageId
Value | Name |
---|---|
0 | NandSystem |
1 | NandUser |
2 | SdCard |
SaveDataSpaceId
Value | Name |
---|---|
0 | NandSystem |
1 | NandUser |
2 | SdCard |
3 | [3.0.0+] TemporaryStorage |
Determines the storage where the savedata is stored.
SaveDataType
Value | Name |
---|---|
0 | SystemSaveData |
1 | SaveData |
2 | BcatDeliveryCacheStorage |
3 | DeviceSaveData |
4 | [3.0.0+] TemporaryStorage |
5 | [3.0.0+] CacheStorage |
ContentPath
These are the 0x300 paths to NCA files for the various filesystems FS can access, beginning with @. They're passed via X descriptors, and returned via various ncm/lr commands.
Path | Notes |
---|---|
@SystemContent | |
@UserContent | |
@SdCardContent | |
@CalibFile | |
@Safe | |
@User | |
@System | |
@Sdcard | |
@Host | |
@GcApp | Gamecard App partition (Partition 2) |
@GcS00000001 | Gamecard Contents. |
@upp | Gamecard update partition (Partition 0) |
[4.0.0+] @RegUpdate | Registered update partition |
Save Struct
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | 0 for SystemSaveData. SaveData: 0 can be used for accessing the savedata associated with the current FS session titleID, otherwise when set this is the titleID associated with the savedata to access. |
0x8 | 0x10 | userID for user-specific savedata(saveuser) when set, otherwise when zero this indicates the common savedata(savecommon). This is loaded from Account_services. |
0x18 | 0x8 | u64 saveID. 0 for SaveData. |
0x20 | 0x1 | #SaveDataType |
0x21 | 0x7 | Padding |
0x28 | 0x8 | 0 for SystemSaveData/SaveData. |
0x30 | 0x8 | 0 for SystemSaveData/SaveData. |
0x38 | 0x8 | 0 for SystemSaveData/SaveData. |
Total size is 0x40-bytes.
For DeviceSaveData, this struct is all-zero except for the #SaveDataType field.
SaveCreate Struct
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | IVFC level4 size? |
0x8 | 0x8 | Same as offset 0x0 normally? Hard-coded to 0x80000 for BcatSaveData. |
0x10 | 0x8 | 0x4000 for SystemSaveData/SaveData/DeviceSaveData/BcatSaveData. IVFC level4 block-size in bytes? |
0x18 | 0x8 | Official user-processes only uses 0 here for SystemSaveData/SaveData. For the dedicated save-creation code with SaveData/DeviceSaveData, this value comes from an input param with official user-processes. For BcatSaveData, this is the hard-coded titleID of the bcat-sysmodule. |
0x20 | 0x4 | Written using an input param for official user-processes. Hard-coded 0 for BcatSaveData. |
0x24 | 0x1 | Official user-processes only uses 0 here for SystemSaveData, 1 for SaveData/DeviceSaveData/BcatSaveData. |
0x25 | 0x1 | 0 for SystemSaveData/SaveData. |
0x26 | 0x1A | Not initialized for SystemSaveData/SaveData. |
Total size is 0x40-bytes.
DeviceSaveData
This is accessed using the same commands for SaveData with the same input u8, the only difference compared to SaveData is the Save-struct.
BcatSaveData
This is accessed using the same commands for SaveData with the same input u8. The Save-struct is the same as DeviceSaveData, except that the titleID field is set to <input titleID>. See above regarding SaveCreate-struct.
The 0x10-byte struct passed to #CreateSaveDataFileSystem has the first 0x5-bytes set to all-zero.
SaveDataInfo
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | Unknown saveID |
0x8 | 0x1 | #SaveDataSpaceId |
0x9 | 0x1 | #SaveDataType |
0xA | 0x6 | Padding? |
0x10 | 0x10 | userID |
0x20 | 0x8 | saveID, 0 for regular SaveData. |
0x28 | 0x8 | Application titleID, for regular SaveData. |
0x30 | 0x8 | Raw saveimage size |
0x38 | 0x28 | Unknown. Usually zeros? |
This is a 0x60-byte struct.