Filesystem services
fsp-ldr
| Cmd | Name | 
|---|---|
| 0 | MountCode | 
| 1 | IsCodeMounted | 
fsp-pr
| Cmd | Name | 
|---|---|
| 0 | SetFsPermissions | 
| 1 | ClearFsPermissions | 
fsp-srv
| Cmd | Name | 
|---|---|
| 0 | MountApplicationPackage | 
| 1 | #Initialize | 
| 2 | MountRomFs | 
| 7 | #MountContent7 | 
| 8 | #MountContent | 
| 11 | #MountBis | 
| 12 | #OpenBisPartition | 
| 13 | InvalidateBisCache | 
| 17 | OpenHostFileSystemImpl | 
| 18 | MountSdCard | 
| 19 | FormatSdCard | 
| 21 | #DeleteSaveData | 
| 22 | #CreateSaveData | 
| 23 | #CreateSystemSaveData | 
| 24 | RegisterSaveDataAtomicDeletion | 
| 25 | |
| 26 | FormatSdCardDryRun | 
| 27 | |
| 30 | OpenGameCardPartition | 
| 31 | #MountGameCardPartition | 
| 51 | #MountSaveData | 
| 52 | #MountSystemSaveData | 
| 53 | Returns an #IFileSystem. | 
| 58 | ReadSaveDataFileSystemExtraData | 
| 59 | |
| 60 | OpenSaveDataInfoReader | 
| 61 | OpenSaveDataIterator | 
| 80 | OpenSaveDataThumbnailFile | 
| 100 | MountImageDirectory | 
| 110 | #MountContentStorage | 
| 200 | OpenHost | 
| 202 | OpenDataStorageByDataId | 
| 203 | Returns an #IStorage. | 
| 400 | #OpenDeviceOperator | 
| 500 | #OpenSdCardDetectionEventNotifier | 
| 501 | #OpenGameCardDetectionEventNotifier | 
| 600 | SetCurrentPosixTime | 
| 601 | QuerySaveDataTotalSize | 
| 602 | #VerifySaveData | 
| 603 | CorruptSaveDataForDebug | 
| 604 | CreatePaddingFile | 
| 605 | DeleteAllPaddingFiles | 
| 606 | |
| 607 | RegisterExternalKey | 
| 608 | UnregisterExternalKey | 
| 609 | |
| 620 | |
| 800 | |
| 1000 | SetBisRootForHost | 
| 1001 | |
| 1002 | SetSaveDataRootPath | 
| 1003 | DisableAutoSaveDataCreation | 
| 1004 | SetGlobalAccessLogMode | 
| 1005 | GetGlobalAccessLogMode | 
| 1006 | OutputAccessLogToSdCard | 
MountApplicationPackage
Presumably about the same as MountContent except this uses the titleID associated with the FS session?
Initialize
| Word | Value | 
|---|---|
| 0 | 0x00000004 | 
| 1 | 0x8000000E | 
| 2 | 0x00000001 | 
| 0-1 | Pid | 
| 0 | Always. 0x18000001 | 
| 1 | Always. 0 | 
| 2 | "SCFI" | 
| 3 | 0x00000001 | 
| 4 | Always 0. | 
MountContent7
Takes an input u32 (NCA-type) and an u64 title-id. Web-applet loads the u32 from u32_table[inparam]. Only type4 is usable with this?
Returns an #IFileSystem.
Note: web-applet strings refer to both this cmd and the below "MountContent" as "MountContent".
MountContent
Takes a type-0x19 input buffer, an in32, and an input title-id.
The in32 must be 5 if the NCA type is 0 (control).
The input buffer is the output string path from nsam GetContentNcaPath.
Returns an #IFileSystem.
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.
MountBis
Takes a type-0x19 input buffer string and a u32 Bis partitionID(see below). 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 #OpenBisPartition except this mounts the partition filesystem instead of allowing direct access to the partition sectors.
OpenBisPartition
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.
DeleteSaveData
Takes an input u64.
CreateSaveData
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.
CreateSystemSaveData
Takes a 0x40-byte Save-struct entry and a 0x40-byte SaveCreate-struct entry.
Creates savedata in the SYSTEM NAND partition.
MountGameCardPartition
Takes two input u32s, with the second u32 located at +4 in rawdata after the first u32.
Returns an #IFileSystem.
MountSaveData
Takes an input u8 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.
MountSystemSaveData
Takes an input u8 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.
MountContentStorage
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.
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.
VerifySaveData
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).
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 | |
| 2 | Flush | |
| 3 | SetSize | |
| 4 | GetSize | None | 
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 | 
Commit
Like 3DS, this has to be used after writing to savedata for the changes to take affect.
IDirectory
| Cmd | Name | 
|---|---|
| 0 | Read | 
| 1 | GetEntryCount | 
IFile
| Cmd | Name | 
|---|---|
| 0 | Read | 
| 1 | Write | 
| 2 | Flush | 
| 3 | SetSize | 
| 4 | GetSize | 
ISaveDataInfoReader
IDeviceOperator
| Cmd | Name | 
|---|---|
| 0 | IsSdCardInserted | 
| 1 | GetSdCardSpeedMode | 
| 2 | GetSdCardCid | 
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 100 | GetMmcCid | 
| 101 | GetMmcSpeedMode | 
| 110 | EraseMmc | 
| 111 | GetMmcPartitionSize | 
| 112 | |
| 113 | |
| 114 | |
| 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 | |
| 213 | |
| 214 | |
| 215 | |
| 216 | |
| 300 | SetSpeedEmulationMode | 
| 301 | GetSpeedEmulationMode | 
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
| Cmd | Name | 
|---|---|
| 0 | BindEvent | 
StorageId
| Value | Name | 
|---|---|
| 0 | None | 
| 1 | Host | 
| 2 | GameCard | 
| 3 | NandSystem | 
| 4 | NandUser | 
| 5 | SdCard | 
ContentStorageId
| Value | Name | 
|---|---|
| 0 | NandSystem | 
| 1 | NandUser | 
| 2 | SdCard | 
BisPartitionID
- 0: Raw NAND sectors access for MMC boot partition 0.
- 10: Raw NAND sectors access for MMC boot partition 1.
- Rest: see here.
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 | 0x8 | ContentStorageId? 0 for SystemSaveData. 1 for SaveData. 2 for DeviceSaveData(with official user-processes all other fields are 0 for DeviceSaveData). | 
| 0x28 | 0x8 | 0 for SystemSaveData/SaveData. | 
| 0x30 | 0x8 | 0 for SystemSaveData/SaveData. | 
| 0x38 | 0x8 | 0 for SystemSaveData/SaveData. | 
Total size is 0x40-bytes.
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 #CreateSaveData has the first 0x5-bytes set to all-zero.