m (typo) |
|||
(56 intermediate revisions by 14 users not shown) | |||
Line 1: | Line 1: | ||
− | + | __FORCETOC__ | |
+ | |||
+ | '''ES''' (E-Ticket Services) is the [[IOS]] module that is notably responsible for [[title]] management, bootstrapping the [[Hardware/Broadway|Broadway]], and giving it access to title contents. | ||
+ | |||
+ | This module is always part of the main, bootable binary, along with the IOS kernel, crypto code (IOSC) and the flash filesystem driver (FFS). It runs with more privileges than any other process and has access to most syscalls. | ||
+ | |||
+ | Along with the rest of IOS, this is generally considered a "private interface" -- game developers never call any of these functions directly. | ||
+ | |||
+ | Most of these are now implemented in [http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/libogc/libogc/es.c?view=log libogc]. Please feel free to submit patches to implement the remaining functions. | ||
+ | |||
+ | ES generally does not launch PPC titles with ES_LaunchTitle; instead, it writes the title information to [[:/sys/launch.sys]], then reloads into the requested IOS (even if it is the same IOS), and the new IOS sees /sys/launch.sys when it boots and launches the title, deleting the file and replacing it with [[:/sys/space.sys]]. | ||
+ | |||
+ | ES is also notable for having the most [[Wii system flaws#IOS|IOS exploits]], some directly affecting title installation, and others allowing for arbitrary code execution. | ||
− | + | == Commands == | |
+ | {| class="wikitable" | ||
+ | ! Command !! Name !! Notes | ||
+ | |- | ||
+ | | 0x1 || Open || ES keeps track of three contexts, one per active handle, so only three handles can be opened at once. -1016 will be returned if the maximum amount of handles is exceeded. | ||
+ | |- | ||
+ | | 0x2 || Close || - | ||
+ | |- | ||
+ | | 0x3 || Read || Not supported; returns IPC_EINVAL (-4). | ||
+ | |- | ||
+ | | 0x4 || Write || Not supported; returns IPC_EINVAL (-4). | ||
+ | |- | ||
+ | | 0x5 || Seek || Not supported; returns IPC_EINVAL (-4). | ||
+ | |- | ||
+ | | 0x6 || Ioctl || Not supported; returns IPC_EINVAL (-4). | ||
+ | |- | ||
+ | | 0x7 || Ioctlv || Up to 0x45 ioctlvs available depending on the version. | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | == Known ES Functions == | ||
− | ios_ioctlv( fd, 0x01, | + | ios_ioctlv( fd, 0x01, 3, 0, vec); // ES_AddTicket(const signed_blob *stik, u32 stik_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) |
ios_ioctlv( fd, 0x02, 4, 0, vec); // ES_AddTitleStart(const signed_blob *stmd, u32 tmd_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) | ios_ioctlv( fd, 0x02, 4, 0, vec); // ES_AddTitleStart(const signed_blob *stmd, u32 tmd_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) | ||
ios_ioctlv( fd, 0x03, 2, 0, vec); // ES_AddContentStart(u64 titleID, u32 cid) | ios_ioctlv( fd, 0x03, 2, 0, vec); // ES_AddContentStart(u64 titleID, u32 cid) | ||
Line 9: | Line 41: | ||
ios_ioctlv( fd, 0x05, 1, 0, vec); // ES_AddContentFinish(u32 cid) | ios_ioctlv( fd, 0x05, 1, 0, vec); // ES_AddContentFinish(u32 cid) | ||
ios_ioctlv( fd, 0x06, 0, 0, vec); // ES_AddTitleFinish(void) | ios_ioctlv( fd, 0x06, 0, 0, vec); // ES_AddTitleFinish(void) | ||
− | ios_ioctlv( fd, 0x07, 0, 1, vec); // ES_GetDeviceID | + | ios_ioctlv( fd, 0x07, 0, 1, vec); // ES_GetDeviceID(u32 *id) |
− | ios_ioctlvReboot(fd, | + | ios_ioctlvReboot(fd, 0x08, 2, 0, vec); // ES_LaunchTitle(u64 titleID, const tikview *view) |
ios_ioctlv( fd, 0x09, 1, 0, vec); // ES_OpenContent(u16 index) | ios_ioctlv( fd, 0x09, 1, 0, vec); // ES_OpenContent(u16 index) | ||
ios_ioctlv( fd, 0x0A, 1, 1, vec); // ES_ReadContent(s32 cfd, u8 *data, u32 data_size) | ios_ioctlv( fd, 0x0A, 1, 1, vec); // ES_ReadContent(s32 cfd, u8 *data, u32 data_size) | ||
ios_ioctlv( fd, 0x0B, 1, 0, vec); // ES_CloseContent(s32 cfd) | ios_ioctlv( fd, 0x0B, 1, 0, vec); // ES_CloseContent(s32 cfd) | ||
− | ios_ioctlv( fd, 0x0C, 0, 1, vec); // ES_GetOwnedTitlesCount | + | ios_ioctlv( fd, 0x0C, 0, 1, vec); // ES_GetOwnedTitlesCount(u32 *count) |
− | ios_ioctlv( fd, 0x0D, 1, 1, vec); // ES_GetOwnedTitles | + | ios_ioctlv( fd, 0x0D, 1, 1, vec); // ES_GetOwnedTitles(u64 *titles, u32 count) |
− | ios_ioctlv( fd, 0x0E, 0, 1, vec); // ES_GetTitlesCount | + | ios_ioctlv( fd, 0x0E, 0, 1, vec); // ES_GetTitlesCount(u32 *count) |
− | ios_ioctlv( fd, 0x0F, 1, 1, vec); // ES_GetTitles | + | ios_ioctlv( fd, 0x0F, 1, 1, vec); // ES_GetTitles(u64 *titles) |
− | ios_ioctlv( fd, 0x10, | + | ios_ioctlv( fd, 0x10, 1, 1, vec); // ES_GetTitleContentsCount(u64 titleID, u32 *count) |
− | ios_ioctlv( fd, 0x11, 2, 1, vec); // ES_GetTitleContent | + | ios_ioctlv( fd, 0x11, 2, 1, vec); // ES_GetTitleContent(u64 titleID, u32 *contents, u32 count) |
ios_ioctlv( fd, 0x12, 1, 1, vec); // ES_GetNumTicketViews(u64 titleID, u32 *cnt) | ios_ioctlv( fd, 0x12, 1, 1, vec); // ES_GetNumTicketViews(u64 titleID, u32 *cnt) | ||
− | ios_ioctlv( fd, 0x13, | + | ios_ioctlv( fd, 0x13, 2, 1, vec); // ES_GetTicketViews(u64 titleID, tikview *views, u32 cnt) |
− | ios_ioctlv( fd, 0x14, 1, 1, vec); // ES_GetTmdViewSize | + | ios_ioctlv( fd, 0x14, 1, 1, vec); // ES_GetTmdViewSize(u64 titleID, u32 *size) |
− | ios_ioctlv( fd, 0x15, 2, 1, vec); // ES_GetTmdView | + | ios_ioctlv( fd, 0x15, 2, 1, vec); // ES_GetTmdView(u64 titleID, tmdview *view, u32 size) |
− | ios_ioctlv( fd, 0x16, 1, 2, vec); // ES_GetConsumption | + | ios_ioctlv( fd, 0x16, 1, 2, vec); // ES_GetConsumption(u64 ticketID, tiklimit *limits, u32 *cnt); |
− | ios_ioctlv( fd, 0x17, 1, | + | ios_ioctlv( fd, 0x17, 1, 0, vec); // ES_DeleteTitle(u64 titleID) |
− | ios_ioctlv( fd, 0x18, 1, | + | ios_ioctlv( fd, 0x18, 1, 0, vec); // ES_DeleteTicket(const tikview *view) |
− | ios_ioctlv( fd, 0x19, 1, 1, vec); // ES_DIGetTmdViewSize( | + | ios_ioctlv( fd, 0x19, 1, 1, vec); // ES_DIGetTmdViewSize(const TMD *tmd, u32 *size) |
− | ios_ioctlv( fd, 0x1A, 2, 1, vec); // ES_DiGetTmdView | + | ios_ioctlv( fd, 0x1A, 2, 1, vec); // ES_DiGetTmdView(const TMD *tmd, tmdview *view, u32 size) |
− | ios_ioctlv( fd, 0x1B, 1, 1, vec); // ES_DiGetTicketView | + | ios_ioctlv( fd, 0x1B, 1, 1, vec); // ES_DiGetTicketView(const Ticket *ticket, tikview *view) |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x1C, 4, 2, vec); // ES_DiVerify(const signed_blob *certificates, u32 certificates_size, const void *crl, u32 crl_size, const Ticket *ticket, const TMD *tmd, u32 tmd_size, u32 *key_handle, sha1 *hashes); |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x1D, 1, 1, vec); // ES_GetDataDir(u64 titleID, char *out) |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x1E, 0, 1, vec); // ES_GetDeviceCert(signed_blob *out) |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x1F, 6, 0, vec); // ES_ImportBoot(const signed_blob *tik, u32 tik_size, const signed_blob *tik_certs, u32 tik_certs_size, const signed_blob *tmd, u32 tmd_size, const signed_blob *tmd_certs, u32 tmd_certs_size, const u8 *content, u32 content_size) |
− | ios_ioctlv( fd, 0x20, 0, 1, vec); // ES_GetTitleId | + | ios_ioctlv( fd, 0x20, 0, 1, vec); // ES_GetTitleId(u64 *out) |
− | ios_ioctlv( fd, 0x21, 1, 0, vec); // ES_SetUid | + | ios_ioctlv( fd, 0x21, 1, 0, vec); // ES_SetUid(u64 titleID) |
− | ios_ioctlv( fd, 0x22, 1, 0, vec); // | + | ios_ioctlv( fd, 0x22, 1, 0, vec); // ES_DeleteTitleContents(u64 titleID) - deletes all files containing 'app' in a /title/xxxxxxxx/yyyyyyyy/content |
− | ios_ioctlv( fd, 0x23, 3, 0, vec); // ES_SeekContent | + | ios_ioctlv( fd, 0x23, 3, 0, vec); // ES_SeekContent(int cfd, int where, int whence) |
ios_ioctlv( fd, 0x24, 3, 0, vec); // ES_OpenTitleContent(u64 titleID, const tikview *view, u16 index) | ios_ioctlv( fd, 0x24, 3, 0, vec); // ES_OpenTitleContent(u64 titleID, const tikview *view, u16 index) | ||
ios_ioctlv( fd, 0x25, 0, 0, vec); // ES_LaunchBC(void) | ios_ioctlv( fd, 0x25, 0, 0, vec); // ES_LaunchBC(void) | ||
− | ios_ioctlv( fd, 0x26, 1, 1, vec); // ES_ExportTitleInit | + | ios_ioctlv( fd, 0x26, 1, 1, vec); // ES_ExportTitleInit(TMD *tmd_out, u32 tmd_size) |
− | ios_ioctlv( fd, 0x27, 2, 0, vec); // ES_ExportContentBegin | + | ios_ioctlv( fd, 0x27, 2, 0, vec); // ES_ExportContentBegin(u64 titleID, u32 cid) |
− | ios_ioctlv( fd, 0x28, 1, 1, vec); // ES_ExportContentData | + | ios_ioctlv( fd, 0x28, 1, 1, vec); // ES_ExportContentData(s32 cfd, void *data, u32 data_size) |
− | ios_ioctlv( fd, 0x29, 1, 0, vec); // ES_ExportContentEnd | + | ios_ioctlv( fd, 0x29, 1, 0, vec); // ES_ExportContentEnd(s32 cfd) |
ios_ioctlv( fd, 0x2A, 0, 0, vec); // ES_ExportTitleDone(void) | ios_ioctlv( fd, 0x2A, 0, 0, vec); // ES_ExportTitleDone(void) | ||
− | ios_ioctlv( fd, 0x2B, 1, 0, vec); // | + | ios_ioctlv( fd, 0x2B, 1, 0, vec); // ES_ReimportTitleInit(const TMD *tmd, u32 tmd_size) |
− | ios_ioctlv( fd, 0x2C, 3, 2, vec); // ES_Encrypt(u32 keynum, | + | ios_ioctlv( fd, 0x2C, 3, 2, vec); // ES_Encrypt(u32 keynum, u32 *iv, const void *source, u32 size, void *dest) |
− | ios_ioctlv( fd, 0x2D, 3, 2, vec); // ES_Decrypt(u32 keynum, | + | ios_ioctlv( fd, 0x2D, 3, 2, vec); // ES_Decrypt(u32 keynum, u32 *iv, const void *source, u32 size, void *dest) |
ios_ioctlv( fd, 0x2E, 0, 1, vec); // ES_GetBoot2Version(u32 *version) | ios_ioctlv( fd, 0x2E, 0, 1, vec); // ES_GetBoot2Version(u32 *version) | ||
ios_ioctlv( fd, 0x2F, 0, 0, vec); // ES_AddTitleCancel(void) | ios_ioctlv( fd, 0x2F, 0, 0, vec); // ES_AddTitleCancel(void) | ||
− | ios_ioctlv( fd, 0x30, 1, 2, vec); // ES_Sign( | + | ios_ioctlv( fd, 0x30, 1, 2, vec); // ES_Sign(const void *data, u32 size, u8 *ap_signature, u8 *ap_certificate) |
− | ios_ioctlv( fd, 0x31, 3, 0, vec); // ES_VerifySign | + | ios_ioctlv( fd, 0x31, 3, 0, vec); // ES_VerifySign(const void *data, u32 size, const u8 *ap_signature, const signed_blob* certificates, u32 certificates_size) |
// the following functions are only available in IOS28+ | // the following functions are only available in IOS28+ | ||
− | ios_ioctlv( fd, 0x32, | + | ios_ioctlv( fd, 0x32, 1, 1, vec); // ES_GetStoredContentCount(const TMD *tmd, u32 *count) |
− | ios_ioctlv( fd, 0x33, | + | ios_ioctlv( fd, 0x33, 2, 1, vec); // ES_GetStoredContent(const TMD* tmd, u32 *contents, u32 count) |
− | ios_ioctlv( fd, 0x34, | + | ios_ioctlv( fd, 0x34, 1, 1, vec); // ES_GetStoredTmdSize(u64 titleID, u32 *size) |
− | ios_ioctlv( fd, 0x35, | + | ios_ioctlv( fd, 0x35, 2, 1, vec); // ES_GetStoredTmd(u64 titlteID, TMD *tmd, u32 size); |
− | ios_ioctlv( fd, 0x36, 0, 1, vec); // ES_GetSharedContentCount | + | ios_ioctlv( fd, 0x36, 0, 1, vec); // ES_GetSharedContentCount(u32 *count) |
− | ios_ioctlv( fd, 0x37, | + | ios_ioctlv( fd, 0x37, 1, 1, vec); // ES_GetSharedContents(sha1 *contents, u32 count) |
− | ios_ioctlv( fd, 0x38, | + | ios_ioctlv( fd, 0x38, 1, 0, vec); // ES_DeleteSharedContent(sha1 hash) |
− | ios_ioctlv( fd, 0x39, 0, 1, vec); // ES_GetDiTmdSize | + | ios_ioctlv( fd, 0x39, 0, 1, vec); // ES_GetDiTmdSize(u32 *size) |
− | ios_ioctlv( fd, 0x3A, 1, 1, vec); // ES_GetDiTmd | + | ios_ioctlv( fd, 0x3A, 1, 1, vec); // ES_GetDiTmd(TMD *tmd, u32 size) |
− | ios_ioctlv( fd, 0x3B, 0, 1, vec); // | + | ios_ioctlv( fd, 0x3B, 4, 2, vec); // ES_DiVerifyWithTicketView(const signed_blob *certificates, u32 certificates_size, const void *crl, u32 crl_size, const tikview *view, const TMD *tmd, u32 tmd_size, u32 *key_handle, sha1 *hashes) |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x3C, 2, 1, vec); // ES_SetupStreamKey(const tikview *ticket_view, const TMD *tmd, u32 tmd_size, u32 *key_handle) (WFS only, only usable for some title types and UIDs) |
− | ios_ioctlv( fd, | + | ios_ioctlv( fd, 0x3D, 0, 1, vec); // ES_DeleteStreamKey(u32 *key_handle) (calls IOSC_DeleteObject, without any second thought...?) |
+ | // the following functions are only available in IOS37+ but not in IOS38 | ||
+ | ios_ioctlv( fd, 0x3E, 2, 0, vec); // ES_DeleteTitleContent(u64 titleID, u32 cid) | ||
+ | // the following functions are only available in IOS37v3609+ but not in IOS38 | ||
+ | ios_ioctlv( fd, 0x3F, ?, ?, vec); // non-existant ioctl why? ... because. | ||
+ | ios_ioctlv( fd, 0x40, 1, 1, vec); // ES_GetV0TicketFromView(const tikview* ticket_view, Ticket* ticket) | ||
+ | // the following functions are only available in IOS56+ | ||
+ | ios_ioctlv( fd, 0x41, 1, 1, vec); // forwarder for GetProcessPriorities (syscall 0x79) | ||
+ | ios_ioctlv( fd, 0x42, 2, 0, vec); // forwarder for SetProcessPriorities (syscall 0x78) | ||
+ | // the following functions are only available in IOS56v5405+/IOS57v5661+/IOS61v5405+/IOS70+ Please check (I thought it was a rule never add new functions existing IOS) | ||
+ | ios_ioctlv( fd, 0x43, 1, 1, vec); // ES_GetTicketSizeFromView(const tikview* view, u32* ticket_size) -- used to get the ticket size from a view (internally called with ticket = nullptr) | ||
+ | ios_ioctlv( fd, 0x44, 2, 1, vec); // ES_GetTicketFromView(const tikview* view, Ticket *ticket, u32 ticket_size) -- used to get a ticket from a view | ||
+ | ios_ioctlv( fd, 0x45, 0, 0, vec); // "ES_CheckHasKoreanKey" | ||
== /dev/es IOS_Ioctlv == | == /dev/es IOS_Ioctlv == | ||
+ | {{stub}} | ||
{| class="wikitable" style="margin: 1em auto 1em auto" | {| class="wikitable" style="margin: 1em auto 1em auto" | ||
! style="vertical-align: top;" |number | ! style="vertical-align: top;" |number | ||
Line 79: | Line 124: | ||
| style="vertical-align: top;"|0x00 | | style="vertical-align: top;"|0x00 | ||
| style="vertical-align: top;"|? | | style="vertical-align: top;"|? | ||
− | |||
− | |||
− | |||
− | |||
| style="vertical-align: top;"|? | | style="vertical-align: top;"|? | ||
− | | style="vertical-align: top;"| | + | | style="vertical-align: top;"|? |
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|Returns -1017 non-existant ioctl. | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" rowspan="3" |0x01 | | style="vertical-align: top;" rowspan="3" |0x01 | ||
− | | style="vertical-align: top;" rowspan="3" | | + | | style="vertical-align: top;" rowspan="3" |ES_ImportTicket |
| style="vertical-align: top;" rowspan="3" |3 | | style="vertical-align: top;" rowspan="3" |3 | ||
| style="vertical-align: top;" rowspan="3" |0 | | style="vertical-align: top;" rowspan="3" |0 | ||
Line 102: | Line 147: | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="4" |0x02 | | style="vertical-align: top;" rowspan="4" |0x02 | ||
− | | style="vertical-align: top;" rowspan="4" | | + | | style="vertical-align: top;" rowspan="4" |ES_ImportTitleInit |
| style="vertical-align: top;" rowspan="4" |4 | | style="vertical-align: top;" rowspan="4" |4 | ||
| style="vertical-align: top;" rowspan="4" |0 | | style="vertical-align: top;" rowspan="4" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
− | | style="vertical-align: top;" rowspan="4" | | + | | style="vertical-align: top;" rowspan="4" |ES_AddTitleStart(const signed_blob *stmd, u32 tmd_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) |
− | | style="vertical-align: top;" rowspan="4" | | + | | style="vertical-align: top;" rowspan="4" |Writes the TMD to [[:/tmp/title.tmd]] |
|- | |- | ||
|? | |? | ||
Line 120: | Line 165: | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" rowspan="2" |0x03 | | style="vertical-align: top;" rowspan="2" |0x03 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ImportContentBegin |
| style="vertical-align: top;" rowspan="2" |2 | | style="vertical-align: top;" rowspan="2" |2 | ||
| style="vertical-align: top;" rowspan="2" |0 | | style="vertical-align: top;" rowspan="2" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_AddContentStart(u64 titleID, u32 cid) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 132: | Line 177: | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="2" |0x04 | | style="vertical-align: top;" rowspan="2" |0x04 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ImportContentData |
| style="vertical-align: top;" rowspan="2" |2 | | style="vertical-align: top;" rowspan="2" |2 | ||
| style="vertical-align: top;" rowspan="2" |0 | | style="vertical-align: top;" rowspan="2" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_AddContentData(s32 cfd, u8 *data, u32 data_size) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- | |- | ||
Line 144: | Line 189: | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" |0x05 | | style="vertical-align: top;" |0x05 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_ImportContentEnd |
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_AddContentFinish(u32 cid) |
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="1" |0x06 | | style="vertical-align: top;" rowspan="1" |0x06 | ||
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |ES_ImportTitleDone |
| style="vertical-align: top;" rowspan="1" |0 | | style="vertical-align: top;" rowspan="1" |0 | ||
| style="vertical-align: top;" rowspan="1" |0 | | style="vertical-align: top;" rowspan="1" |0 | ||
| style="vertical-align: top;" | | | style="vertical-align: top;" | | ||
| style="vertical-align: top;" | | | style="vertical-align: top;" | | ||
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |ES_AddTitleFinish(void) |
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |Renames /import/HIGHBITS/LOWBITS/ for the title currently being installed to /title/HIGHBITS/LOWBITS/ |
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" |0x07 | | style="vertical-align: top;" |0x07 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_GetDeviceId |
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_GetDeviceID(u32 *device_id) |
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
|- | |- | ||
Line 176: | Line 221: | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_LaunchTitleBackground(u64 titleID, const tikview *view); ES_LaunchTitle(u64 titleID, const tikview *view); |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- | |- | ||
Line 183: | Line 228: | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" |0x09 | | style="vertical-align: top;" |0x09 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_OpenContentFile |
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_OpenContent(u16 index) |
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
|- | |- | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |0x0A |
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ReadContentFile |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ReadContent(s32 cfd, u8 *data, u32 data_size) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- | |- | ||
Line 203: | Line 248: | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |0x0B |
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_CloseContentFile |
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_CloseContent(s32 cfd) |
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
|- | |- | ||
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |0x0C |
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |ES_ListOwnedTitles (count) |
| style="vertical-align: top;" rowspan="1" |0 | | style="vertical-align: top;" rowspan="1" |0 | ||
| style="vertical-align: top;" rowspan="1" |1 | | style="vertical-align: top;" rowspan="1" |1 | ||
| style="vertical-align: top;" |u32* count | | style="vertical-align: top;" |u32* count | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" rowspan="1" | | + | | style="vertical-align: top;" rowspan="1" |ES_GetNumOwnedTitles(u32 *cnt) |
| style="vertical-align: top;" rowspan="1" |? | | style="vertical-align: top;" rowspan="1" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |0x0D |
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ListOwnedTitles |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |u32* count | | style="vertical-align: top;" |u32* count | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetOwnedTitles(u64 *titles, u32 cnt) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 233: | Line 278: | ||
| style="vertical-align: top;" |[count]*0x8 | | style="vertical-align: top;" |[count]*0x8 | ||
|- | |- | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |0x0E |
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_ListTitlesOnCard (count) |
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |u32* count | | style="vertical-align: top;" |u32* count | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |ES_GetNumTitles(u32 *cnt) |
− | | style="vertical-align: top;" |Sets the u32 pointed to by ''count'' to the number of titles on the system under /title. | + | | style="vertical-align: top;" |"Card" refers to the NAND. Sets the u32 pointed to by ''count'' to the number of titles on the system under /title. |
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |0x0F |
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ListTitlesOnCard |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |u32* count | | style="vertical-align: top;" |u32* count | ||
| style="vertical-align: top;" |0x4 | | style="vertical-align: top;" |0x4 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetTitles(u64 *titles, u32 cnt) |
| style="vertical-align: top;" rowspan="2" |Fills out ''buffer'' with at most ''count'' 8 byte title ids of titles on the system under /title. It also update ''count'' for the number of title its copied. | | style="vertical-align: top;" rowspan="2" |Fills out ''buffer'' with at most ''count'' 8 byte title ids of titles on the system under /title. It also update ''count'' for the number of title its copied. | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 255: | Line 300: | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="2" |0x10 | | style="vertical-align: top;" rowspan="2" |0x10 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_ListTitleContentsOnCard (count) |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetTitleContentsCount(u64 titleID, u32 *num) |
− | | style="vertical-align: top;" rowspan="2" |Gets the number of contents from the tmd. It checks that the contents are present in the title's private content directory or linked via /shared1/content.map | + | | style="vertical-align: top;" rowspan="2" |Gets the number of contents from the tmd. It checks that the contents are present in the title's private content directory or linked via [[:/shared1/content.map]] |
|- | |- | ||
|u32* count | |u32* count | ||
Line 267: | Line 312: | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
| style="vertical-align: top;" rowspan="3" |0x11 | | style="vertical-align: top;" rowspan="3" |0x11 | ||
− | | style="vertical-align: top;" rowspan="3" | | + | | style="vertical-align: top;" rowspan="3" |ES_ListTitleContentsOnCard |
| style="vertical-align: top;" rowspan="3" |2 | | style="vertical-align: top;" rowspan="3" |2 | ||
| style="vertical-align: top;" rowspan="3" |1 | | style="vertical-align: top;" rowspan="3" |1 | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="3" | | + | | style="vertical-align: top;" rowspan="3" |No |
| style="vertical-align: top;" rowspan="3" |Fills out ''content_ids'' with the content ids from the title's tmd. It checks if the contents are present in the title's private content directory or linked via /shared1/content.map | | style="vertical-align: top;" rowspan="3" |Fills out ''content_ids'' with the content ids from the title's tmd. It checks if the contents are present in the title's private content directory or linked via /shared1/content.map | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 282: | Line 327: | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="2" |0x12 | | style="vertical-align: top;" rowspan="2" |0x12 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetTicketViews (count) |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetNumTicketViews(u64 titleID, u32 *cnt) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- | |- | ||
Line 299: | Line 344: | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="3" | | + | | style="vertical-align: top;" rowspan="3" |ES_GetTicketViews(u64 titleID, tikview *views, u32 cnt) |
| style="vertical-align: top;" rowspan="3" |? | | style="vertical-align: top;" rowspan="3" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 309: | Line 354: | ||
|- | |- | ||
| style="vertical-align: top;" rowspan="2" |0x14 | | style="vertical-align: top;" rowspan="2" |0x14 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetTmdView (size) |
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" rowspan="2" |1 | | style="vertical-align: top;" rowspan="2" |1 | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="2" | | + | | style="vertical-align: top;" rowspan="2" |ES_GetTMDViewSize(u64 titleID, u32 *size) |
| style="vertical-align: top;" rowspan="2" |? | | style="vertical-align: top;" rowspan="2" |? | ||
|- | |- | ||
Line 326: | Line 371: | ||
| style="vertical-align: top;" |u64 title_id | | style="vertical-align: top;" |u64 title_id | ||
| style="vertical-align: top;" |0x8 | | style="vertical-align: top;" |0x8 | ||
− | | style="vertical-align: top;" rowspan="3" | | + | | style="vertical-align: top;" rowspan="3" |ES_GetTMDView(u64 titleID, u8 *data, u32 size) |
| style="vertical-align: top;" rowspan="3" |? | | style="vertical-align: top;" rowspan="3" |? | ||
|- style="background-color: #eee;" | |- style="background-color: #eee;" | ||
Line 334: | Line 379: | ||
|tmdiew_t tmdview | |tmdiew_t tmdview | ||
|[count] | |[count] | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x16 | ||
+ | | style="vertical-align: top;"|ES_GetConsumption | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|2 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|No | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x17 | ||
+ | | style="vertical-align: top;"|ES_DeleteTitle | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|u64 titleID | ||
+ | | style="vertical-align: top;"|0x8 | ||
+ | | style="vertical-align: top;"|ES_DeleteTitle(u64 titleID) | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |||
+ | |- | ||
+ | | style="vertical-align: top;"|0x18 | ||
+ | | style="vertical-align: top;"|ES_DeleteTicket | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_DeleteTicket(const tikview *view) | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x19 | ||
+ | | style="vertical-align: top;"|ES_DiGetTmdView (size) | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|No | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1A | ||
+ | | style="vertical-align: top;"|ES_DiGetTmdView | ||
+ | | style="vertical-align: top;"|2 | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|No | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1B | ||
+ | | style="vertical-align: top;"|ES_DiGetTicketView | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|No | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1C | ||
+ | | style="vertical-align: top;"|ES_DiVerify | ||
+ | | style="vertical-align: top;"|4 | ||
+ | | style="vertical-align: top;"|2 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_Identify(const signed_blob *certificates, u32 certificates_size, const signed_blob *stmd, u32 tmd_size, const signed_blob *sticket, u32 ticket_size, u32 *keyid) | ||
+ | | style="vertical-align: top;"|Older IOSes forget to block access to this IOCTL from the [[Hardware/Broadway|Broadway]], hence the purpose of ES_Identify. Calling this IOCTL changes the title permissions to that of the title in the TMD, including verification of the TMD, but does not launch any code. Homebrew can therefore set its permissions to that of any title, or, if this IOS supports [[fakesign]]ing, anything. | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1D | ||
+ | | style="vertical-align: top;"|GetTitleDir | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_GetDataDir(u64 titleID,char *filepath) | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1E | ||
+ | | style="vertical-align: top;"|ES_GetDeviceCert | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_GetDeviceCert(u8 *outbuf) | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |||
+ | |- | ||
+ | | style="vertical-align: top;"|0x1F | ||
+ | | style="vertical-align: top;"|ES_ImportBoot | ||
+ | | style="vertical-align: top;"|6 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_ImportBoot(const signed_blob *tik, u32 tik_size,const signed_blob *tik_certs,u32 tik_certs_size,const signed_blob *tmd,u32 tmd_size,const signed_blob *tmd_certs,u32 tmd_certs_size,const u8 *content,u32 content_size) | ||
+ | | style="vertical-align: top;"|Installs a new [[boot2]]. This call is very buggy and bricks the Wii easily, so it is recommended to use custom installing code to install a custom boot2. | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x20 | ||
+ | | style="vertical-align: top;"|GetTitleId | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_GetTitleID(u64 *titleID) | ||
+ | | style="vertical-align: top;"|? | ||
+ | |- | ||
+ | |- | ||
+ | | style="vertical-align: top;"|0x21 | ||
+ | | style="vertical-align: top;"|ES_SetUid | ||
+ | | style="vertical-align: top;"|1 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|ES_SetUID(u64 uid) | ||
+ | | style="vertical-align: top;"|? | ||
|- | |- | ||
| style="vertical-align: top;" |0x22 | | style="vertical-align: top;" |0x22 | ||
Line 339: | Line 505: | ||
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
− | |||
− | |||
| style="vertical-align: top;" |? | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |ES_DeleteTitleContent(u64 titleID) | ||
| style="vertical-align: top;" |Deletes all files containing the substring "app" in a title's content directory (/title/xxxxxxxx/yyyyyyyy/content). | | style="vertical-align: top;" |Deletes all files containing the substring "app" in a title's content directory (/title/xxxxxxxx/yyyyyyyy/content). | ||
+ | |- | ||
+ | | style="vertical-align: top;" |0x23 | ||
+ | | style="vertical-align: top;" |ES_SeekContentFile | ||
+ | | style="vertical-align: top;" |3 | ||
+ | | style="vertical-align: top;" |0 | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |s32 ES_SeekContent(s32 cfd, s32 where, s32 whence) | ||
+ | | style="vertical-align: top;" |? | ||
+ | |- | ||
+ | | style="vertical-align: top;" |0x24 | ||
+ | | style="vertical-align: top;" |ES_OpenTitleContentFile | ||
+ | | style="vertical-align: top;" |3 | ||
+ | | style="vertical-align: top;" |0 | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |s32 ES_OpenTitleContent(u64 titleID, tikview *views, u16 index) | ||
+ | | style="vertical-align: top;" |? | ||
+ | |- | ||
+ | | style="vertical-align: top;" |0x25 | ||
+ | | style="vertical-align: top;" |LaunchBC | ||
+ | | style="vertical-align: top;" |0 | ||
+ | | style="vertical-align: top;" |0 | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |? | ||
+ | | style="vertical-align: top;" |No | ||
+ | | style="vertical-align: top;" |Shuts down [[IOS]] and runs [[BC]] | ||
|- | |- | ||
| style="vertical-align: top;" |0x38 | | style="vertical-align: top;" |0x38 | ||
− | | style="vertical-align: top;" | | + | | style="vertical-align: top;" |DeleteSharedContent |
| style="vertical-align: top;" |1 | | style="vertical-align: top;" |1 | ||
| style="vertical-align: top;" |0 | | style="vertical-align: top;" |0 | ||
Line 385: | Line 578: | ||
|tik_t ticket_buffer | |tik_t ticket_buffer | ||
|0x2a4 | |0x2a4 | ||
+ | |- style="background-color: #eee;" | ||
+ | | style="vertical-align: top;"|0x45 | ||
+ | | style="vertical-align: top;"| CheckHasKoreanKey | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"|0 | ||
+ | | style="vertical-align: top;"| | ||
+ | | style="vertical-align: top;"| | ||
+ | | style="vertical-align: top;"|? | ||
+ | | style="vertical-align: top;"|Used by System menu 4.2+ to check if the wii is a region changed Korean wii. See [[Error_003]] | ||
|} | |} | ||
− | == | + | == Error codes == |
+ | This list of ES error codes should be complete for IOS59. Other codes that can technically be returned, but only indirectly (since ES makes use of the FS module and IOSC) are not included in an exhaustive manner in this list. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Error code | ! Error code | ||
− | |||
! Notes | ! Notes | ||
|- | |- | ||
− | | -106 | + | | -106 (FS) |
− | | | + | | No such file or directory (returned by the FS module indirectly) |
− | |||
|- | |- | ||
− | | - | + | | -1005 (ES) |
− | | | + | | Invalid public key type in certificate |
+ | |- | ||
+ | | -1009 (ES) | ||
| Read failure (short read) | | Read failure (short read) | ||
|- | |- | ||
− | | -1010 | + | | -1010 (ES) |
− | |||
| Write failure (short write) | | Write failure (short write) | ||
|- | |- | ||
− | | -1012 | + | | -1012 (ES) |
− | + | | Invalid signature type (for signed blobs) | |
− | | Invalid signature type | ||
|- | |- | ||
− | | - | + | | -1016 (ES) |
− | + | | Maximum amount of handles exceeded (3 handles, as there are only 3 contexts) | |
− | | | ||
|- | |- | ||
− | | -1017 | + | | -1017 (ES) |
− | | | + | | Invalid arguments |
− | |||
|- | |- | ||
− | | -1020 | + | | -1020 (ES) |
− | | | + | | Device ID mismatch. Returned by ES_ImportTicket if the ticket is personalised and the device ID from the ticket mismatches with the actual ID. |
− | |||
|- | |- | ||
− | | -1022 | + | | -1022 (ES) |
− | | | + | | Imported content hash does not match with the hash from the TMD. Returned by ES_ImportContentEnd and ES_ImportBoot. |
− | |||
|- | |- | ||
− | | -1024 | + | | -1024 (ES) |
− | |||
| Memory allocation failure | | Memory allocation failure | ||
|- | |- | ||
− | | -1026 | + | | -1026 (ES) |
− | + | | Incorrect access rights (according to the TMD) | |
− | | Incorrect access rights | + | |- |
+ | | -1027 (ES) | ||
+ | | Issuer not found in the certificate chain | ||
+ | |- | ||
+ | | -1028 (ES) | ||
+ | | Ticket not found | ||
+ | |- | ||
+ | | -1029 (ES) | ||
+ | | Invalid ticket. This is returned if the common key field contains an invalid value (anything other than 0 or 1). This is also returned from ES_LaunchTitle if the title ID contained in the ticket does not match the TMD title ID. | ||
+ | |- | ||
+ | | -1031 (ES) | ||
+ | | During LaunchTitle/ImportTitle: installed boot2 version is too old. | ||
+ | During ImportBoot: downgrades are not allowed. | ||
+ | |- | ||
+ | | -1032 (ES) | ||
+ | | Fatal error early in ES initialisation. Can also be returned in ES_CheckHasKoreanKey in all other cases (key is not the Korean Key or a zero key!) | ||
+ | |- | ||
+ | | -1033 (ES) | ||
+ | | A ticket limit was exceeded (duration or launch count) | ||
+ | |- | ||
+ | | -1034 (ES) | ||
+ | | Returned by ES_CheckHasKoreanKey if the key is sensed to be all zeroes | ||
+ | |- | ||
+ | | -1035 (ES) | ||
+ | | A title with a higher version is already installed | ||
+ | |- | ||
+ | | -1036 (ES) | ||
+ | | Required sysversion(IOS) is not installed (only for the system menu {{check}}) | ||
+ | |- | ||
+ | | -1037 (ES) | ||
+ | | Installed number of contents doesn't match TMD (only for the system menu {{check}}) | ||
+ | |- | ||
+ | | -1039 (DI) | ||
+ | | Returned by DI as an ES error code when "TMD not supplied for disc/nand game" | ||
+ | |- | ||
+ | | -2000 (IOSC) | ||
+ | | Permission denied (returned when accessing an object for which the caller has no permission) | ||
+ | |- | ||
+ | | -2001 (IOSC) | ||
+ | | IOSC_EEXIST | ||
+ | |- | ||
+ | | -2003 (IOSC) | ||
+ | | IOSC_EMAX | ||
+ | |- | ||
+ | | -2004 (IOSC) | ||
+ | | IOSC_ENOENT | ||
+ | |- | ||
+ | | -2005 (IOSC) | ||
+ | | IOSC_INVALID_OBJTYPE | ||
+ | |- | ||
+ | | -2006 (IOSC) | ||
+ | | IOSC_INVALID_RNG | ||
|- | |- | ||
− | | - | + | | -2007 (IOSC) |
− | | | + | | IOSC_INVALID_FLAG |
− | |||
|- | |- | ||
− | | - | + | | -2008 (IOSC) |
− | | | + | | IOSC_INVALID_FORMAT |
− | |||
|- | |- | ||
− | | - | + | | -2009 (IOSC) |
− | | | + | | IOSC_INVALID_VERSION |
− | |||
|- | |- | ||
− | | - | + | | -2010 (IOSC) |
− | + | | IOSC_INVALID_SIGNER | |
− | | | ||
|- | |- | ||
− | | - | + | | -2011 (IOSC) |
− | | | + | | IOSC_FAIL_CHECKVALUE |
− | + | Known to be returned when a signature check failed. | |
|- | |- | ||
− | | - | + | | -2012 (IOSC) |
− | | | + | | Internal failure |
− | |||
|- | |- | ||
− | | -2013 | + | | -2013 (IOSC) |
− | | | + | | Memory allocation failure. Known to be returned when the keyring is full (contains 0x20 keys) |
− | |||
|- | |- | ||
− | | -2014 | + | | -2014 (IOSC) |
− | | | + | | Invalid size |
− | |||
|- | |- | ||
− | | - | + | | -2015 (IOSC) |
− | | | + | | Invalid address |
− | |||
|- | |- | ||
− | | - | + | | -2016 (IOSC) |
− | | | + | | Unaligned data |
− | |||
|} | |} | ||
[[Category:IOS API documentation]] | [[Category:IOS API documentation]] |
Latest revision as of 23:04, 24 February 2025
ES (E-Ticket Services) is the IOS module that is notably responsible for title management, bootstrapping the Broadway, and giving it access to title contents.
This module is always part of the main, bootable binary, along with the IOS kernel, crypto code (IOSC) and the flash filesystem driver (FFS). It runs with more privileges than any other process and has access to most syscalls.
Along with the rest of IOS, this is generally considered a "private interface" -- game developers never call any of these functions directly.
Most of these are now implemented in libogc. Please feel free to submit patches to implement the remaining functions.
ES generally does not launch PPC titles with ES_LaunchTitle; instead, it writes the title information to /sys/launch.sys, then reloads into the requested IOS (even if it is the same IOS), and the new IOS sees /sys/launch.sys when it boots and launches the title, deleting the file and replacing it with /sys/space.sys.
ES is also notable for having the most IOS exploits, some directly affecting title installation, and others allowing for arbitrary code execution.
Commands
Command | Name | Notes |
---|---|---|
0x1 | Open | ES keeps track of three contexts, one per active handle, so only three handles can be opened at once. -1016 will be returned if the maximum amount of handles is exceeded. |
0x2 | Close | - |
0x3 | Read | Not supported; returns IPC_EINVAL (-4). |
0x4 | Write | Not supported; returns IPC_EINVAL (-4). |
0x5 | Seek | Not supported; returns IPC_EINVAL (-4). |
0x6 | Ioctl | Not supported; returns IPC_EINVAL (-4). |
0x7 | Ioctlv | Up to 0x45 ioctlvs available depending on the version. |
Known ES Functions
ios_ioctlv( fd, 0x01, 3, 0, vec); // ES_AddTicket(const signed_blob *stik, u32 stik_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) ios_ioctlv( fd, 0x02, 4, 0, vec); // ES_AddTitleStart(const signed_blob *stmd, u32 tmd_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) ios_ioctlv( fd, 0x03, 2, 0, vec); // ES_AddContentStart(u64 titleID, u32 cid) ios_ioctlv( fd, 0x04, 2, 0, vec); // ES_AddContentData(s32 cfd, u8 *data, u32 data_size) ios_ioctlv( fd, 0x05, 1, 0, vec); // ES_AddContentFinish(u32 cid) ios_ioctlv( fd, 0x06, 0, 0, vec); // ES_AddTitleFinish(void) ios_ioctlv( fd, 0x07, 0, 1, vec); // ES_GetDeviceID(u32 *id) ios_ioctlvReboot(fd, 0x08, 2, 0, vec); // ES_LaunchTitle(u64 titleID, const tikview *view) ios_ioctlv( fd, 0x09, 1, 0, vec); // ES_OpenContent(u16 index) ios_ioctlv( fd, 0x0A, 1, 1, vec); // ES_ReadContent(s32 cfd, u8 *data, u32 data_size) ios_ioctlv( fd, 0x0B, 1, 0, vec); // ES_CloseContent(s32 cfd) ios_ioctlv( fd, 0x0C, 0, 1, vec); // ES_GetOwnedTitlesCount(u32 *count) ios_ioctlv( fd, 0x0D, 1, 1, vec); // ES_GetOwnedTitles(u64 *titles, u32 count) ios_ioctlv( fd, 0x0E, 0, 1, vec); // ES_GetTitlesCount(u32 *count) ios_ioctlv( fd, 0x0F, 1, 1, vec); // ES_GetTitles(u64 *titles) ios_ioctlv( fd, 0x10, 1, 1, vec); // ES_GetTitleContentsCount(u64 titleID, u32 *count) ios_ioctlv( fd, 0x11, 2, 1, vec); // ES_GetTitleContent(u64 titleID, u32 *contents, u32 count) ios_ioctlv( fd, 0x12, 1, 1, vec); // ES_GetNumTicketViews(u64 titleID, u32 *cnt) ios_ioctlv( fd, 0x13, 2, 1, vec); // ES_GetTicketViews(u64 titleID, tikview *views, u32 cnt) ios_ioctlv( fd, 0x14, 1, 1, vec); // ES_GetTmdViewSize(u64 titleID, u32 *size) ios_ioctlv( fd, 0x15, 2, 1, vec); // ES_GetTmdView(u64 titleID, tmdview *view, u32 size) ios_ioctlv( fd, 0x16, 1, 2, vec); // ES_GetConsumption(u64 ticketID, tiklimit *limits, u32 *cnt); ios_ioctlv( fd, 0x17, 1, 0, vec); // ES_DeleteTitle(u64 titleID) ios_ioctlv( fd, 0x18, 1, 0, vec); // ES_DeleteTicket(const tikview *view) ios_ioctlv( fd, 0x19, 1, 1, vec); // ES_DIGetTmdViewSize(const TMD *tmd, u32 *size) ios_ioctlv( fd, 0x1A, 2, 1, vec); // ES_DiGetTmdView(const TMD *tmd, tmdview *view, u32 size) ios_ioctlv( fd, 0x1B, 1, 1, vec); // ES_DiGetTicketView(const Ticket *ticket, tikview *view) ios_ioctlv( fd, 0x1C, 4, 2, vec); // ES_DiVerify(const signed_blob *certificates, u32 certificates_size, const void *crl, u32 crl_size, const Ticket *ticket, const TMD *tmd, u32 tmd_size, u32 *key_handle, sha1 *hashes); ios_ioctlv( fd, 0x1D, 1, 1, vec); // ES_GetDataDir(u64 titleID, char *out) ios_ioctlv( fd, 0x1E, 0, 1, vec); // ES_GetDeviceCert(signed_blob *out) ios_ioctlv( fd, 0x1F, 6, 0, vec); // ES_ImportBoot(const signed_blob *tik, u32 tik_size, const signed_blob *tik_certs, u32 tik_certs_size, const signed_blob *tmd, u32 tmd_size, const signed_blob *tmd_certs, u32 tmd_certs_size, const u8 *content, u32 content_size) ios_ioctlv( fd, 0x20, 0, 1, vec); // ES_GetTitleId(u64 *out) ios_ioctlv( fd, 0x21, 1, 0, vec); // ES_SetUid(u64 titleID) ios_ioctlv( fd, 0x22, 1, 0, vec); // ES_DeleteTitleContents(u64 titleID) - deletes all files containing 'app' in a /title/xxxxxxxx/yyyyyyyy/content ios_ioctlv( fd, 0x23, 3, 0, vec); // ES_SeekContent(int cfd, int where, int whence) ios_ioctlv( fd, 0x24, 3, 0, vec); // ES_OpenTitleContent(u64 titleID, const tikview *view, u16 index) ios_ioctlv( fd, 0x25, 0, 0, vec); // ES_LaunchBC(void) ios_ioctlv( fd, 0x26, 1, 1, vec); // ES_ExportTitleInit(TMD *tmd_out, u32 tmd_size) ios_ioctlv( fd, 0x27, 2, 0, vec); // ES_ExportContentBegin(u64 titleID, u32 cid) ios_ioctlv( fd, 0x28, 1, 1, vec); // ES_ExportContentData(s32 cfd, void *data, u32 data_size) ios_ioctlv( fd, 0x29, 1, 0, vec); // ES_ExportContentEnd(s32 cfd) ios_ioctlv( fd, 0x2A, 0, 0, vec); // ES_ExportTitleDone(void) ios_ioctlv( fd, 0x2B, 1, 0, vec); // ES_ReimportTitleInit(const TMD *tmd, u32 tmd_size) ios_ioctlv( fd, 0x2C, 3, 2, vec); // ES_Encrypt(u32 keynum, u32 *iv, const void *source, u32 size, void *dest) ios_ioctlv( fd, 0x2D, 3, 2, vec); // ES_Decrypt(u32 keynum, u32 *iv, const void *source, u32 size, void *dest) ios_ioctlv( fd, 0x2E, 0, 1, vec); // ES_GetBoot2Version(u32 *version) ios_ioctlv( fd, 0x2F, 0, 0, vec); // ES_AddTitleCancel(void) ios_ioctlv( fd, 0x30, 1, 2, vec); // ES_Sign(const void *data, u32 size, u8 *ap_signature, u8 *ap_certificate) ios_ioctlv( fd, 0x31, 3, 0, vec); // ES_VerifySign(const void *data, u32 size, const u8 *ap_signature, const signed_blob* certificates, u32 certificates_size) // the following functions are only available in IOS28+ ios_ioctlv( fd, 0x32, 1, 1, vec); // ES_GetStoredContentCount(const TMD *tmd, u32 *count) ios_ioctlv( fd, 0x33, 2, 1, vec); // ES_GetStoredContent(const TMD* tmd, u32 *contents, u32 count) ios_ioctlv( fd, 0x34, 1, 1, vec); // ES_GetStoredTmdSize(u64 titleID, u32 *size) ios_ioctlv( fd, 0x35, 2, 1, vec); // ES_GetStoredTmd(u64 titlteID, TMD *tmd, u32 size); ios_ioctlv( fd, 0x36, 0, 1, vec); // ES_GetSharedContentCount(u32 *count) ios_ioctlv( fd, 0x37, 1, 1, vec); // ES_GetSharedContents(sha1 *contents, u32 count) ios_ioctlv( fd, 0x38, 1, 0, vec); // ES_DeleteSharedContent(sha1 hash) ios_ioctlv( fd, 0x39, 0, 1, vec); // ES_GetDiTmdSize(u32 *size) ios_ioctlv( fd, 0x3A, 1, 1, vec); // ES_GetDiTmd(TMD *tmd, u32 size) ios_ioctlv( fd, 0x3B, 4, 2, vec); // ES_DiVerifyWithTicketView(const signed_blob *certificates, u32 certificates_size, const void *crl, u32 crl_size, const tikview *view, const TMD *tmd, u32 tmd_size, u32 *key_handle, sha1 *hashes) ios_ioctlv( fd, 0x3C, 2, 1, vec); // ES_SetupStreamKey(const tikview *ticket_view, const TMD *tmd, u32 tmd_size, u32 *key_handle) (WFS only, only usable for some title types and UIDs) ios_ioctlv( fd, 0x3D, 0, 1, vec); // ES_DeleteStreamKey(u32 *key_handle) (calls IOSC_DeleteObject, without any second thought...?) // the following functions are only available in IOS37+ but not in IOS38 ios_ioctlv( fd, 0x3E, 2, 0, vec); // ES_DeleteTitleContent(u64 titleID, u32 cid) // the following functions are only available in IOS37v3609+ but not in IOS38 ios_ioctlv( fd, 0x3F, ?, ?, vec); // non-existant ioctl why? ... because. ios_ioctlv( fd, 0x40, 1, 1, vec); // ES_GetV0TicketFromView(const tikview* ticket_view, Ticket* ticket) // the following functions are only available in IOS56+ ios_ioctlv( fd, 0x41, 1, 1, vec); // forwarder for GetProcessPriorities (syscall 0x79) ios_ioctlv( fd, 0x42, 2, 0, vec); // forwarder for SetProcessPriorities (syscall 0x78) // the following functions are only available in IOS56v5405+/IOS57v5661+/IOS61v5405+/IOS70+ Please check (I thought it was a rule never add new functions existing IOS) ios_ioctlv( fd, 0x43, 1, 1, vec); // ES_GetTicketSizeFromView(const tikview* view, u32* ticket_size) -- used to get the ticket size from a view (internally called with ticket = nullptr) ios_ioctlv( fd, 0x44, 2, 1, vec); // ES_GetTicketFromView(const tikview* view, Ticket *ticket, u32 ticket_size) -- used to get a ticket from a view ios_ioctlv( fd, 0x45, 0, 0, vec); // "ES_CheckHasKoreanKey"
/dev/es IOS_Ioctlv
This article is a stub. You can help WiiBrew by expanding it. |
number | name | in count | out count | vec entry target | vec entry size [bytes] | libogc prototype | Description |
---|---|---|---|---|---|---|---|
0x00 | ? | ? | ? | ? | ? | ? | Returns -1017 non-existant ioctl. |
0x01 | ES_ImportTicket | 3 | 0 | ? | 0x2A4 | ES_AddTicket(const signed_blob *stik, u32 stik_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) | ? |
? | ? | ||||||
? | ? | ||||||
0x02 | ES_ImportTitleInit | 4 | 0 | ? | ? | ES_AddTitleStart(const signed_blob *stmd, u32 tmd_size, const signed_blob *certificates, u32 certificates_size, const signed_blob *crl, u32 crl_size) | Writes the TMD to /tmp/title.tmd |
? | ? | ||||||
? | ? | ||||||
? | 0x1c | ||||||
0x03 | ES_ImportContentBegin | 2 | 0 | ? | 0x8 | ES_AddContentStart(u64 titleID, u32 cid) | ? |
? | 0x4 | ||||||
0x04 | ES_ImportContentData | 2 | 0 | ? | 0x4 | ES_AddContentData(s32 cfd, u8 *data, u32 data_size) | ? |
? | ? | ||||||
0x05 | ES_ImportContentEnd | 1 | 0 | ? | 0x4 | ES_AddContentFinish(u32 cid) | ? |
0x06 | ES_ImportTitleDone | 0 | 0 | ES_AddTitleFinish(void) | Renames /import/HIGHBITS/LOWBITS/ for the title currently being installed to /title/HIGHBITS/LOWBITS/ | ||
0x07 | ES_GetDeviceId | 0 | 1 | ? | 0x4 | ES_GetDeviceID(u32 *device_id) | ? |
0x08 | ES_LaunchTitle | 2 | 0 | ? | 0x8 | ES_LaunchTitleBackground(u64 titleID, const tikview *view); ES_LaunchTitle(u64 titleID, const tikview *view); | ? |
? | 0xd8 | ||||||
0x09 | ES_OpenContentFile | 1 | 0 | ? | 0x4 | ES_OpenContent(u16 index) | ? |
0x0A | ES_ReadContentFile | 1 | 1 | ? | 0x4 | ES_ReadContent(s32 cfd, u8 *data, u32 data_size) | ? |
? | ? | ||||||
0x0B | ES_CloseContentFile | 1 | 0 | ? | 0x4 | ES_CloseContent(s32 cfd) | ? |
0x0C | ES_ListOwnedTitles (count) | 0 | 1 | u32* count | 0x4 | ES_GetNumOwnedTitles(u32 *cnt) | ? |
0x0D | ES_ListOwnedTitles | 1 | 1 | u32* count | 0x4 | ES_GetOwnedTitles(u64 *titles, u32 cnt) | ? |
u64 titles[] | [count]*0x8 | ||||||
0x0E | ES_ListTitlesOnCard (count) | 0 | 1 | u32* count | 0x4 | ES_GetNumTitles(u32 *cnt) | "Card" refers to the NAND. Sets the u32 pointed to by count to the number of titles on the system under /title. |
0x0F | ES_ListTitlesOnCard | 1 | 1 | u32* count | 0x4 | ES_GetTitles(u64 *titles, u32 cnt) | Fills out buffer with at most count 8 byte title ids of titles on the system under /title. It also update count for the number of title its copied. |
u64 buffer[] | [count]*0x8 | ||||||
0x10 | ES_ListTitleContentsOnCard (count) | 1 | 1 | u64 title_id | 0x8 | ES_GetTitleContentsCount(u64 titleID, u32 *num) | Gets the number of contents from the tmd. It checks that the contents are present in the title's private content directory or linked via /shared1/content.map |
u32* count | 0x4 | ||||||
0x11 | ES_ListTitleContentsOnCard | 2 | 1 | u64 title_id | 0x8 | No | Fills out content_ids with the content ids from the title's tmd. It checks if the contents are present in the title's private content directory or linked via /shared1/content.map |
u32* count | 0x4 | ||||||
u32 content_ids[] | [count]*0x4 | ||||||
0x12 | ES_GetTicketViews (count) | 1 | 1 | u64 title_id | 0x8 | ES_GetNumTicketViews(u64 titleID, u32 *cnt) | ? |
u32* count | 0x4 | ||||||
0x13 | ES_GetTicketViews | 2 | 1 | u64 title_id | 0x8 | ES_GetTicketViews(u64 titleID, tikview *views, u32 cnt) | ? |
u32* count | 0x4 | ||||||
tikview_t ticketviews[] | [count]*0xd8 | ||||||
0x14 | ES_GetTmdView (size) | 1 | 1 | u64 title_id | 0x8 | ES_GetTMDViewSize(u64 titleID, u32 *size) | ? |
u32* count | 0x4 | ||||||
0x15 | ES_GetTmdView | 2 | 1 | u64 title_id | 0x8 | ES_GetTMDView(u64 titleID, u8 *data, u32 size) | ? |
u32* count | 0x4 | ||||||
tmdiew_t tmdview | [count] | ||||||
0x16 | ES_GetConsumption | 1 | 2 | ? | ? | No | ? |
0x17 | ES_DeleteTitle | 1 | 0 | u64 titleID | 0x8 | ES_DeleteTitle(u64 titleID) | ? |
0x18 | ES_DeleteTicket | 1 | 0 | ? | ? | ES_DeleteTicket(const tikview *view) | ? |
0x19 | ES_DiGetTmdView (size) | 1 | 0 | ? | ? | No | ? |
0x1A | ES_DiGetTmdView | 2 | 1 | ? | ? | No | ? |
0x1B | ES_DiGetTicketView | 1 | 1 | ? | ? | No | ? |
0x1C | ES_DiVerify | 4 | 2 | ? | ? | ES_Identify(const signed_blob *certificates, u32 certificates_size, const signed_blob *stmd, u32 tmd_size, const signed_blob *sticket, u32 ticket_size, u32 *keyid) | Older IOSes forget to block access to this IOCTL from the Broadway, hence the purpose of ES_Identify. Calling this IOCTL changes the title permissions to that of the title in the TMD, including verification of the TMD, but does not launch any code. Homebrew can therefore set its permissions to that of any title, or, if this IOS supports fakesigning, anything. |
0x1D | GetTitleDir | 1 | 1 | ? | ? | ES_GetDataDir(u64 titleID,char *filepath) | ? |
0x1E | ES_GetDeviceCert | 1 | 0 | ? | ? | ES_GetDeviceCert(u8 *outbuf) | ? |
0x1F | ES_ImportBoot | 6 | 0 | ? | ? | ES_ImportBoot(const signed_blob *tik, u32 tik_size,const signed_blob *tik_certs,u32 tik_certs_size,const signed_blob *tmd,u32 tmd_size,const signed_blob *tmd_certs,u32 tmd_certs_size,const u8 *content,u32 content_size) | Installs a new boot2. This call is very buggy and bricks the Wii easily, so it is recommended to use custom installing code to install a custom boot2. |
0x20 | GetTitleId | 0 | 1 | ? | ? | ES_GetTitleID(u64 *titleID) | ? |
0x21 | ES_SetUid | 1 | 0 | ? | ? | ES_SetUID(u64 uid) | ? |
0x22 | ES_DeleteTitleContent | 1 | 0 | ? | ? | ES_DeleteTitleContent(u64 titleID) | Deletes all files containing the substring "app" in a title's content directory (/title/xxxxxxxx/yyyyyyyy/content). |
0x23 | ES_SeekContentFile | 3 | 0 | ? | ? | s32 ES_SeekContent(s32 cfd, s32 where, s32 whence) | ? |
0x24 | ES_OpenTitleContentFile | 3 | 0 | ? | ? | s32 ES_OpenTitleContent(u64 titleID, tikview *views, u16 index) | ? |
0x25 | LaunchBC | 0 | 0 | ? | ? | No | Shuts down IOS and runs BC |
0x38 | DeleteSharedContent | 1 | 0 | u8 sha1[] | 0x14 | ? | Deletes the content file from /shared1 with the given sha1 checksum. It aborts if the tmd of an essential system title references the content. It rebuilds content.map after, removing the entry for the deleted file. |
0x3e | ? | 2 | 0 | u64 title_id | 0x8 | ? | Deletes a specific content from a title's private content directory. |
u32 content_id | 0x4 | ||||||
0x3f | ? | 0 | 0 | ? | returns -1017 | ||
0x40 | ? | 1 | 1 | tikview_t ticketview | 0xd8 | ? | Copies the ticket associated with ticketview into ticket_buffer based on some access checks [currently unknown ticket offsets +0x1e8 to +0x1ef, +0x1f0.] |
tik_t ticket_buffer | 0x2a4 | ||||||
0x45 | CheckHasKoreanKey | 0 | 0 | ? | Used by System menu 4.2+ to check if the wii is a region changed Korean wii. See Error_003 |
Error codes
This list of ES error codes should be complete for IOS59. Other codes that can technically be returned, but only indirectly (since ES makes use of the FS module and IOSC) are not included in an exhaustive manner in this list.
Error code | Notes |
---|---|
-106 (FS) | No such file or directory (returned by the FS module indirectly) |
-1005 (ES) | Invalid public key type in certificate |
-1009 (ES) | Read failure (short read) |
-1010 (ES) | Write failure (short write) |
-1012 (ES) | Invalid signature type (for signed blobs) |
-1016 (ES) | Maximum amount of handles exceeded (3 handles, as there are only 3 contexts) |
-1017 (ES) | Invalid arguments |
-1020 (ES) | Device ID mismatch. Returned by ES_ImportTicket if the ticket is personalised and the device ID from the ticket mismatches with the actual ID. |
-1022 (ES) | Imported content hash does not match with the hash from the TMD. Returned by ES_ImportContentEnd and ES_ImportBoot. |
-1024 (ES) | Memory allocation failure |
-1026 (ES) | Incorrect access rights (according to the TMD) |
-1027 (ES) | Issuer not found in the certificate chain |
-1028 (ES) | Ticket not found |
-1029 (ES) | Invalid ticket. This is returned if the common key field contains an invalid value (anything other than 0 or 1). This is also returned from ES_LaunchTitle if the title ID contained in the ticket does not match the TMD title ID. |
-1031 (ES) | During LaunchTitle/ImportTitle: installed boot2 version is too old.
During ImportBoot: downgrades are not allowed. |
-1032 (ES) | Fatal error early in ES initialisation. Can also be returned in ES_CheckHasKoreanKey in all other cases (key is not the Korean Key or a zero key!) |
-1033 (ES) | A ticket limit was exceeded (duration or launch count) |
-1034 (ES) | Returned by ES_CheckHasKoreanKey if the key is sensed to be all zeroes |
-1035 (ES) | A title with a higher version is already installed |
-1036 (ES) | Required sysversion(IOS) is not installed (only for the system menu [check]) |
-1037 (ES) | Installed number of contents doesn't match TMD (only for the system menu [check]) |
-1039 (DI) | Returned by DI as an ES error code when "TMD not supplied for disc/nand game" |
-2000 (IOSC) | Permission denied (returned when accessing an object for which the caller has no permission) |
-2001 (IOSC) | IOSC_EEXIST |
-2003 (IOSC) | IOSC_EMAX |
-2004 (IOSC) | IOSC_ENOENT |
-2005 (IOSC) | IOSC_INVALID_OBJTYPE |
-2006 (IOSC) | IOSC_INVALID_RNG |
-2007 (IOSC) | IOSC_INVALID_FLAG |
-2008 (IOSC) | IOSC_INVALID_FORMAT |
-2009 (IOSC) | IOSC_INVALID_VERSION |
-2010 (IOSC) | IOSC_INVALID_SIGNER |
-2011 (IOSC) | IOSC_FAIL_CHECKVALUE
Known to be returned when a signature check failed. |
-2012 (IOSC) | Internal failure |
-2013 (IOSC) | Memory allocation failure. Known to be returned when the keyring is full (contains 0x20 keys) |
-2014 (IOSC) | Invalid size |
-2015 (IOSC) | Invalid address |
-2016 (IOSC) | Unaligned data |