/dev/wfsi
WFSI is a high level library that is responsible for WFS title management (import, deletions, patches). It interacts with WFSSRV for modifying the filesystem and with ES for various tasks, including getting the active title and decrypting contents.
This resource manager is only present in IOS59, along with WFSSRV.
Commands
Only IOS_OPEN, IOS_CLOSE and IOS_IOCTL are valid commands. The other commands immediately return IPC_EINVAL (-4).
Developers and readers that are familiar with ES will notice that the title import functionality is modeled after ES.
WFSI adds the concept of profiles (.ini/.ppcini files). They are handled by special ioctls that internally call the content import functions. Their purpose is unknown.
Buffer sizes aren't checked. WFSI expects to be able to read all information it wants from the input buffer, and also assumes the output buffer will be large enough to write anything it needs to. If the buffers aren't large enough, bad things are going to happen. If parts of the input/ouput buffers are unknown, they will be marked with ???.
Ioctl | Name | Input | Output | Notes |
---|---|---|---|---|
2 | WFSI_ImportTitleInit |
0-4: TMD pointer 4-8: TMD size 32-36: Import/Patch type (0 for TITLE, 1 for PATCH, 2 for PATCH_2) 36-40: Continue import (non-zero for true) -- if false, contents that haven't finished being imported will be deleted. |
None | Initialises ES and WFSSRV in order to prepare for a title import. A TMD for the title to import should be passed. The ticket for that title should already be imported prior to calling this. |
3 | WFSI_ImportContentBegin |
0-8: Title ID (must match the TMD passed to ImportTitleInit) 8-12: Content ID |
None | |
4 | WFSI_ImportContent |
12-16: Content ID (must match the CID passed to ImportContentBegin) 16-20: Pointer to data 20-24: Data size |
None | |
5 | WFSI_ImportContentEnd |
12-16: Content ID (must match the CID passed to ImportContentBegin) |
None | Just like ES, content hashes are checked. If they don't match, WFS_CORRUPTION (-10023) will be returned. The failure doesn't appear to be fatal, though, other than causing a temporary file not to be deleted. It's not even checked on ImportTitleEnd. |
6 | WFSI_ImportTitleDone | None | None | Finalise a title import. This makes sure a few directories are created, contents are put in the right location, etc. |
23 | WFSI_DeleteTitle (?) | ? | ? | ? |
24 | ? | ? | ? | ? |
25 | ? | ? | ? | Calls wfssrv ioctl 0x9 |
26 | ? | ? | ? | "Write[s] title information to NAND" |
27 | WFSI_GetVersion (?) | None | 0-4: Version | Writes 0x00000020 to the output buffer unconditionally. |
47 | WFSI_ImportTitleCancel | 0-4: Continue install (non-zero for true) | None | |
0x81 | WFSI_InitLib | None | None | Initialises the WFSI resource manager. Can only be called once (unless CloseLib is called). WFSI gets the current active title ID from ES. |
0x82 | WFSI_SetDeviceName (?) | Any length: New device name | None | All WFS files are in a directory of the form /vol/NAME ; this IOCTL sets NAME.
|
0x84 | ? | ? | ? | Calls wfssrv ioctl 0x7 |
0x85 | WFSI_CheckTitleInstalled (?) | ? | ? | ? |
0x86 | WFSI_ImportProfileBegin | ? | ? | Wrapper for WFSI_ImportContentBegin |
0x87 | WFSI_ImportProfile | ? | ? | Wrapper for WFSI_ImportContent |
0x88 | WFSI_ImportProfileEnd | ? | ? | Wrapper for WFSI_ImportContentEnd |
0x89 | WFSI_ApplyTitleProfile | ? | ? | ? |
0x8a | WFSI_GetTmdForCurrentTitle | ? | ? | Wrapper for WFSI_GetTmd |
0x8b | WFSI_GetTmd | ? | ? | ? |
0x8c | WFSI_CloseLib | ? | ? | ? |
0x8e | WFSI_SetFstBuffer | ? | ? | Lets the PPC offer more RAM to WFSI. |
0x8f | ? | None | None | Noop. Always and directly returns 0. |
0x90 | WFSI_LoadDol | ? | ? | ? |
0x91 | WFSI_ImportTitleFlush | ? | ? | Does part of ImportTitleDone: move contents to their final directory. This only has effects for patches; if the import type is TITLE, this returns IPC_SUCCESS immediately. |
0x92 | ? | ? | ? | ? |
0x93 | ? | ? | ? | ? |
0x94 | ? | ? | ? | unknown, calls CheckTitleRegistration |
0x95 | WFSI_CheckHasSpace (?) | ? | ? | Calls WFSISrvGetFreeBlkNum with a path that depends on the import type, then performs some calculation on the returned data. Returns 0 if an error occurred or if there's not enough space, 1 otherwise. |
0x97 | WFSI_GetFreeBlkNum | ? | ? | Wrapper around the same WFS ioctl |
0x98 | ? | ? | ? | unknown, AllocDecryptBufferAddress |
0x99 | ? | ? | ? | unknown, calls wfssrv set permission 0x24 and 0x27 |
Errors
All error codes are shared with WFSSRV. Errors can be returned either directly by WFSI or indirectly via calls to WFSSRV, ES, and IOSC.