Filesystem services


Filesystem service "fs:USER"

You can at most have 32 FS archive handles.

Command Header Available since system version Description Required exheader access info bitmask
0x000100C6 ? Dummy1 None
0x040100C4 ? Control None
0x08010002 ? Initialize None
0x080201C2 ? OpenFile None
0x08030204 ? OpenFileDirectly None
0x08040142 ? DeleteFile None
0x08050244 ? RenameFile None
0x08060142 ? DeleteDirectory None
0x08070142 ? DeleteDirectoryRecursively None
0x08080202 ? CreateFile None
0x08090182 ? CreateDirectory None
0x080A0244 ? RenameDirectory None
0x080B0102 ? OpenDirectory None
0x080C00C2 ? OpenArchive Each archive ID code has separate access info bitmasks, if it has any
0x080D0144 ? ControlArchive None
0x080E0080 ? CloseArchive None
0x080F0180 ? Obsoleted_2_0_FormatThisUserSaveData None
0x08100200 ? Obsoleted_3_0_CreateSystemSaveData 0x4, for when the input saveID doesn't match the exheader saveID
0x08110040 ? Obsoleted_3_0_DeleteSystemSaveData 0x1004, for when the input saveID doesn't match the exheader saveID
0x08120080 ? GetFreeBytes None
0x08130000 ? GetCardType 0x1017
0x08140000 ? GetSdmcArchiveResource None
0x08150000 ? GetNandArchiveResource 0x1007
0x08160000 ? GetSdmcFatfsError 0x2
0x08170000 ? IsSdmcDetected None
0x08180000 ? IsSdmcWritable None
0x08190042 ? GetSdmcCid 0x2
0x081A0042 ? GetNandCid 0x2
0x081B0000 ? GetSdmcSpeedInfo 0x2
0x081C0000 ? GetNandSpeedInfo 0x2
0x081D0042 ? GetSdmcLog 0x2
0x081E0042 ? GetNandLog 0x2
0x081F0000 ? ClearSdmcLog 0x2
0x08200000 ? ClearNandLog 0x2
0x08210000 ? CardSlotIsInserted 0x1017
0x08220000 ? CardSlotPowerOn 0x2
0x08230000 ? CardSlotPowerOff 0x2
0x08240000 ? CardSlotGetCardIFPowerStatus 0x2
0x08250040 ? CardNorDirectCommand 0x2
0x08260080 ? CardNorDirectCommandWithAddress 0x2
0x08270082 ? CardNorDirectRead 0x2
0x082800C2 ? CardNorDirectReadWithAddress 0x2
0x08290082 ? CardNorDirectWrite 0x2
0x082A00C2 ? CardNorDirectWriteWithAddress 0x2
0x082B00C2 ? CardNorDirectRead_4xIO 0x2
0x082C0082 ? CardNorDirectCpuWriteWithoutVerify 0x2
0x082D0040 ? CardNorDirectSectorEraseWithoutVerify 0x2
0x082E0040 ? GetProductInfo 0x1005
0x082F0040 ? GetProgramLaunchInfo 0x1005
0x08300182 ? Obsoleted_3_0_CreateExtSaveData 0xC, for when the input extdataID doesn't match the exheader extdataID
0x08310180 ? Obsoleted_3_0_CreateSharedExtSaveData 0x1005
0x08320102 ? Obsoleted_3_0_ReadExtSaveDataIcon 0x100D, for when the input extdataID doesn't match the exheader extdataID
0x08330082 ? Obsoleted_3_0_EnumerateExtSaveData 0x1005
0x08340082 ? Obsoleted_3_0_EnumerateSharedExtSaveData 0x1005
0x08350080 ? Obsoleted_3_0_DeleteExtSaveData 0x100D, for when the input extdataID doesn't match the exheader extdataID
0x08360080 ? Obsoleted_3_0_DeleteSharedExtSaveData 0x1005
0x08370040 ? SetCardSpiBaudRate 0x2
0x08380040 ? SetCardSpiBusMode 0x2
0x08390000 ? SendInitializeInfoTo9 None
0x083A0100 ? GetSpecialContentIndex 0x1005
0x083B00C2 ? GetLegacyRomHeader 0x1015
0x083C00C2 ? GetLegacyBannerData 0x1015
0x083D0100 ? CheckAuthorityToAccessExtSaveData 0x44
0x083E00C2 ? QueryTotalQuotaSize None
0x083F00C0 ? Obsoleted_3_0_GetExtDataBlockSize None
0x08400040 ? AbnegateAccessRight ?
0x08410000 ? DeleteSdmcRoot 0x1005
0x08420040 ? DeleteAllExtSaveDataOnNand 0x1005
0x08430000 ? InitializeCtrFileSystem None
0x08440000 ? CreateSeed 0x2
0x084500C2 ? GetFormatInfo ?
0x08460102 ? GetLegacyRomHeader2 0x1015
0x08470180 ? Obsoleted_2_0_FormatCtrCardUserSaveData 0x6
0x08480042 ? GetSdmcCtrRootPath 0x100D
0x08490040 ? GetArchiveResource ?
0x084A0002 ? ExportIntegrityVerificationSeed 0x4000
0x084B0002 ? ImportIntegrityVerificationSeed 0x4000
0x084C0242 ? FormatSaveData 0x6, in some cases this write isn't needed however
0x084D0102 ? GetLegacySubBannerData 0x1015
0x084E0342 ? UpdateSha256Context 0x5
0x084F0102 ? ReadSpecialFile None
0x08500040 ? GetSpecialFileSize None
0x08510242 3.0.0-5 CreateExtSaveData Shared extdata: 0x101005. Regular extdata in certain cases: 0xC
0x08520100 3.0.0-5 DeleteExtSaveData Shared extdata: 0x101005. Regular extdata in certain cases: 0x10100D
0x08530142 3.0.0-5 ReadExtSaveDataIcon 0x10100D (this doesn't apply in certain cases, however)
0x085400C0 3.0.0-5 GetExtDataBlockSize 0x10100D (this doesn't apply in certain cases, however)
0x08550102 3.0.0-5 EnumerateExtSaveData 0x101005
0x08560200 3.0.0-5 CreateSystemSaveData 0x4 (this doesn't apply in certain cases, however)
0x08570080 3.0.0-5 DeleteSystemSaveData 0x1004 (this doesn't apply in certain cases, however)
0x08580000 3.0.0-5 StartDeviceMoveAsSource 0x2004
0x08590200 3.0.0-5 StartDeviceMoveAsDestination 0x2004
0x085A00C0 3.0.0-5 SetArchivePriority None
0x085B0080 3.0.0-5 GetArchivePriority None
0x085C00C0 3.0.0-5 SetCtrCardLatencyParameter 0xE
0x085D01C0 3.0.0-5 SetFsCompatibilityInfo 0x100001
0x085E0040 3.0.0-5 ResetCardCompatibilityParameter 0xE
0x085F0040 3.0.0-5 SwitchCleanupInvalidSaveData 0x12004
0x08600042 3.0.0-5 EnumerateSystemSaveData 0x2004
0x08610042 3.0.0-5 InitializeWithSdkVersion None
0x08620040 3.0.0-5 SetPriority None
0x08630000 3.0.0-5 GetPriority None
0x08640000 3.0.0-5 Obsoleted_4_0_GetNandInfo Stubbed, this returns an error
0x08650140 4.0.0-7 SetSaveDataSecureValue 0x121004 (in certain cases this doesn't apply, however)
0x086600C0 4.0.0-7 GetSaveDataSecureValue 0x121004 (in certain cases this doesn't apply, however)
0x086700C4 4.0.0-7 ControlSecureSave 0x121004
0x08680000 4.0.0-7 GetMediaType None
0x08690000 4.0.0-7 Obsoleted_4_0_GetNandEraseCount Stubbed, this returns an error.
0x086A0082 4.0.0-7 ReadNandReport None
0x086B00C2 ? ? 00121004
0x086C00C2 ? ? 00121004
0x086D0040 ? ? 00020004
0x086E00C0 ? ? None?
0x086F0040 ? ? 0xE
0x087000C2 ? ? None?
0x08710100 ? ? 0xC
0x087201C0 ? ? 00080004
0x087300C0 ? ? 00080004
0x08740000 ? ? 00080004
0x08750140 ? ? None?
0x087600C0 ? ? None?
0x08770100 ? ? ?
0x087800C0 ? ? ?
0x087900C2 ? Same as GetLegacyBannerData, except for the last parameter this passes u8 value 0x1 instead of 0x0, for the FSPXI command. 0x00101015
0x087A.... 9.6.0-X ? 0x00200000
0x087B.... 9.6.0-X Wrapper for the code internally used for command <0x087A....>. 0x00200000
0x087C.... 9.6.0-X Eventually calls same code as command <0x087A....>. 0x00200000
0x087D0000 9.6.0-X Writes an u32 from state to cmdreply[2]. Probably the total number of titles in the SEEDDB? 0x00200000
0x087E0042 9.6.0-X Eventually calls same code as command <0x087A....>. Writes a list of titleIDs to the outbuf, this is for titles with content-lock-seed(s) stored in SEEDDB. (u32 total_titleids_probably, ((Size<<4) | 12), outbufptr) 0x00200000
0x087F.... 9.6.0-X ? 0x00200000
0x0880.... 9.6.0-X Eventually calls same code as command <0x087A....>. 0x00200000
0x0881.... 9.6.0-X Eventually calls same code as command <0x087A....>. 0x00200000
0x0882.... 9.6.0-X Eventually calls same code as command <0x087A....>. 0x00200000
0x08830000 9.6.0-X Writes an output value to cmdreply[2]. 0x00200000
0x08840042 9.6.0-X Eventually calls same code as command <0x087A....>. 0x00200000
0x0885.... 9.6.0-X ? 0x00200000

Note: The question marks from Dummy1 to GetSpecialFileSize on the "available since system version" field are mainly there because I think that most of these are necessary for the main system to function, so theoretically that would mean that since the creation of the 3DS these were available, or since launch if that makes more sense. But because of the peculiar nature of some of the functions, they will remain question marks until they can be confirmed 100%.

When access rights are required for a command, at least one of the bits in the process access info specified in the above table for the command must be set. Error 0xD9004676 is returned when a process attempts to use a command which it doesn't have access rights for the command. The exheader access info field is all zero's for most applications. Note that the permissions listed in the above table is for system-version v2.x, therefore permission bit(s) added with newer FIRM may be missing from this.

Each session for fs:USER has separate permissions, initially these are set to all zero's for new fs:USER sessions. The permissions/etc for fs:USER sessions are initialized via FS:Initialize(loaded from the user process exheader).

File service

Command Header Description
0x000100C6 Dummy1
0x040100C4 Control
0x08010100 OpenSubFile
0x080200C2 Read
0x08030102 Write
0x08040000 GetSize
0x08050080 SetSize
0x08060000 GetAttributes
0x08070040 SetAttributes
0x08080000 Close
0x08090000 Flush
0x080A0040 SetPriority
0x080B0000 GetPriority
0x080C0000 OpenLinkFile
0x0C010100 ? (takes two u64(?), outputs u64)

Directory service

Command Header Available since system version Description
0x000100C6 1.0.0-0 Dummy1
0x040100C4 1.0.0-0 Control
0x08010042 1.0.0-0 Read
0x08020000 1.0.0-0 Close
0x08030040 ? SetPriority
0x08040000 ? GetPriority

Filesystem service "fs:LDR"

This service is identical to fs:USER, except FS:OpenArchive archive 0x2345678E can only be accessed with fs:LDR.

ProgramRegistry service "fs:REG"

Command Header Description
0x000100C6 Dummy1
0x040103C0 Register
0x04020040 Unregister
0x040300C0 GetProgramInfo
0x04040100 LoadProgram
0x04050080 UnloadProgram
0x04060080 CheckHostLoadId

Only one session can be opened for this service at a time, hence no other processes can use this due to pm-module using this.

SEEDDB

With 9.6.0-X new System_SaveData with saveID 0001000F was added, this seems to be handled by FS-module itself, probably via the new service-cmds added to fsuser. Home Menu and NIM module have access to those commands.

The SEEDDB savedata contains the title-unique seed-data used for the new NCCH keyY generation added with FIRM 9.6.0-X.

Common Types

MediaType

Value Description
0 NAND
1 SD
2 Game Card

OpenFlags

Bit Description
0 Read
1 Write
2 Create

Attributes

Offset Size Description
0x0 0x1 Is Directory
0x1 0x1 Is Hidden
0x2 0x1 Is Archive
0x3 0x1 Is Read-Only

WriteOption

Offset Size Description
0x0 0x1 Flush
0x1 0x1 Update Time Stamp
0x2 0x1 Reserved
0x3 0x1 Reserved

DirectoryEntry

Offset Size Description
0x0 0x20C UTF-16 Entry Name
0x20C 0xA 8.3 short filename name
0x216 0x4 8.3 short filename extension
0x21A 0x1 Always 1
0x21B 0x1 Reserved
0x21C 0x4 Attributes
0x220 0x8 Entry Size

ArchiveResource

Offset Size Description
0x0 0x4 Sector byte-size
0x4 0x4 Cluster byte-size
0x8 0x4 Partition capacity in clusters
0xC 0x4 Available free space in clusters

ArchiveId

Idcode Description Accessible via FS Accessible via FSPXI Requires binary Lowpath
0x00000003 Application RomFS Yes No No
0x00000004 SaveData (the saveID/mediatype for this is loaded from data originally from the user process' exheader) Yes No No
0x00000006 ExtSaveData Yes No Yes
0x00000007 Shared ExtSaveData Yes No Yes
0x00000008 SystemSaveData Yes No Yes
0x00000009 SDMC Yes Yes No
0x0000000A SDMC Write-Only Yes No No
0x12345678 ExtSaveData for BOSS Yes No Yes
0x12345679 CARD SPI FS Yes Yes No
0x1234567B ExtSaveData, and ExtSaveData for BOSS No Yes Yes
0x1234567C SystemSaveData No Yes Yes
0x1234567D NAND RW Yes Yes No
0x1234567E NAND RO Yes Yes No
0x1234567F NAND RO Write FS No Yes No
0x12345680 Unknown. There's code for this in spider v9.9, but that code isn't actually used. Yes ? Yes
0x12345682 Unknown. There's code for this in spider v9.9, but that code isn't actually used. Yes ? Yes
0x2345678A User/GameCard SaveData (for check), and other uses (FS can only mount the latter; includes ExeFS and RomFS) (lo hi mediatype reserved) Yes Yes Yes
0x2345678B ? No No Yes
0x2345678C ? No No Yes
0x2345678D ? No No No
0x2345678E FSPXI: Similar to archive 0x2345678A. For fs:LDR(used by the "loader" FIRM ARM11-process), only ExeFS. Not accessible with fs:USER. Yes Yes Yes
0x567890AB NAND CTR FS No Yes No
0x567890AC TWL PHOTO Yes Yes No
0x567890AD ? No Yes No
0x567890AE NAND TWL FS Yes Yes No
0x567890AF NAND W FS Yes Yes No
0x567890B0 ? No Yes No
0x567890B1 Gamecard SaveData (for check). This is a wrapper for UserSaveDataForCheck: the OpenArchive code for that is called with archive-lowpath TID=0/mediatype=2(gamecard). Yes No No
0x567890B2 UserSaveData (for check). This is the same as the regular SaveData archive, except with this the savedata ID and mediatype is loaded from the input archive lowpath. Yes No Yes
0x567890B4 ? SaveData from Demo Version of Retail Game Yes No No

Archives listed as not requiring a binary lowpath, use lowpath type empty.

Archives CTR NAND, NAND RO Write FS, TWL NAND, NAND W FS, and CARD SPI FS require the corresponding process exheader access control mount flag to be set, in the exheader for any of the currently running ARM11 processes, for FSPXI. The access rights checked by FS module for archive mounting with fs:USER, are stored in the process' exheader accessinfo.

The CARDSPI archive allows access to the gamecard CARD1 raw savedata flash(aka "cardspi:/" in Process9), the file lowpath must be WCHAR "/". The "NAND W FS" archive allows access to the raw NAND image(aka "wnand:/" in Process9), the file lowpath must be WCHAR "/".

PathType

Value Description
0x0 INVALID - Specifies an invalid path.
0x1 EMPTY - Specifies an empty path.
0x2 BINARY - Non-text based path. Meaning is per-archive.
0x3 CHAR - Text-based path with 8-bit characters.
0x4 WCHAR - Text-based path with 16-bit characters.

Binary LowPath

The format of the data that a binary LowPath points to is custom per archive.

SystemSaveData Archive Path Data Format

FS
Index word Description
0 Mediatype (must be zero for NAND)
1 saveid

The file/directory lowpath is a text lowpath in the savegame filesystem.

FSPXI
Index word Description
0 u8 Mediatype (must be zero for NAND)

The file lowpath is a binary lowpath containing the u64 saveid, however the high word of the saveid is always zero. The mounted file is the cleartext savegame image. Up to 32 SystemSaveData image files can be opened under a single mounted FSPXI archive.

UserSaveDataForCheck Archive Path Data Format

Index word Description
0 Mediatype (must be non-zero)
1 Lower word saveid
2 Upper word saveid

The file/directory lowpath for this FS archive is a text path in the savegame filesystem.

ExtSaveData Archive Path Data Format

Index word Description
0 Mediatype
1 Lower word saveid
2 Upper word saveid

For FS, the file/directory lowpath is a text path in the extdata filesystem. For FSPXI, the file lowpath is a text path relative to the "/extdata/<ExtdataIDHigh>/<ExtdataIDLow>" directory on SD/NAND, for the cleartext extdata image to mount.

RomFS

The raw FS image for the main CXI RomFS(for the current app this is accessible via archiveid 0x3) can be accessed via an all-zero 0xc-byte binary file-lowpath. The update RomFS for the current app can be accessed with the first u32 in the binary file-lowpath being set to 0x5. This allows access to the raw level-3 IVFC image: the user process must handle parsing the filesystem used in this image itself.

In this scenario, OpenFile returns a handle to the RomFS archive.

ProgramInfo

Offset Size Description
0x0 0x8 Program ID
0x8 0x1 Media Type
0x9 0x7 Padding

ProductInfo

Offset Size Description
0x0 0x10 Product Code
0x10 0x2 Company Code
0x12 0x2 Remaster Version

IntegrityVerificationSeed

Offset Size Description
0x0 0x10 AES-CBC MAC over a SHA256 hash, which hashes the first 0x110-bytes of the cleartext SEED.
0x10 0x120 The nand/private/movable.sed, encrypted with AES-CTR using the above MAC for the counter.

ExtSaveDataInfo

Offset Size Description
0x0 0x1 Media Type
0x1 0x1 Unknown
0x2 0x2 Reserved
0x4 0x8 Save ID
0xC 0x4 Reserved

SystemSaveDataInfo

Offset Size Description
0x0 0x1 Media Type
0x1 0x1 Unknown
0x2 0x2 Reserved
0x4 0x4 Save ID

SecureValueSlot

Value Description
0x1000 SD Application

CardSpiBaudRate

Value Description
0x0 512KHz
0x1 1MHz
0x2 2MHz
0x3 4MHz
0x4 8MHz
0x5 16MHz

CardSpiBusMode

Value Description
0x0 1-bit
0x1 4-bit

SpecialContentType

Value Description
0x1 Update
0x2 Manual
0x3 DLP Child

DeviceMoveContext

Offset Size Description
0x0 0x10 IVs
0x10 0x10 Encrypt Parameter

Errors

See Filesystem_services_PXI.