1 /*-------------------------------------------------------------
3 wiilaunch.c -- Wii NAND title launching and argument passing
8 This software is provided 'as-is', without any express or implied
9 warranty. In no event will the authors be held liable for any
10 damages arising from the use of this software.
12 Permission is granted to anyone to use this software for any
13 purpose, including commercial applications, and to alter it and
14 redistribute it freely, subject to the following restrictions:
16 1. The origin of this software must not be misrepresented; you
17 must not claim that you wrote the original software. If you use
18 this software in a product, an acknowledgment in the product
19 documentation would be appreciated but is not required.
21 2. Altered source versions must be plainly marked as such, and
22 must not be misrepresented as being the original software.
24 3. This notice may not be removed or altered from any source
27 -------------------------------------------------------------*/
38 #include "processor.h"
42 #include "wiilaunch.h"
44 static char __nandbootinfo
[] ATTRIBUTE_ALIGN(32) = "/shared2/sys/NANDBOOTINFO";
45 static char __stateflags
[] ATTRIBUTE_ALIGN(32) = "/title/00000001/00000002/data/state.dat";
47 static int __initialized
= 0;
72 #define TYPE_NANDBOOT 4
73 #define TYPE_SHUTDOWNSYSTEM 5
74 #define RETURN_TO_MENU 0
75 #define RETURN_TO_SETTINGS 1
76 #define RETURN_TO_ARGS 2
79 static NANDBootInfo nandboot
ATTRIBUTE_ALIGN(32);
81 static StateFlags stateflags
ATTRIBUTE_ALIGN(32);
83 static u32
__CalcChecksum(u32
*buf
, int len
)
95 static void __SetChecksum(void *buf
, int len
)
98 p
[0] = __CalcChecksum(p
, len
);
101 static int __ValidChecksum(void *buf
, int len
)
104 return p
[0] == __CalcChecksum(p
, len
);
107 static s32
__WII_ReadStateFlags(void)
112 fd
= IOS_Open(__stateflags
,IPC_OPEN_READ
);
114 memset(&stateflags
,0,sizeof(stateflags
));
115 return WII_EINTERNAL
;
118 ret
= IOS_Read(fd
, &stateflags
, sizeof(stateflags
));
120 if(ret
!= sizeof(stateflags
)) {
121 memset(&stateflags
,0,sizeof(stateflags
));
122 return WII_EINTERNAL
;
124 if(!__ValidChecksum(&stateflags
, sizeof(stateflags
))) {
125 memset(&stateflags
,0,sizeof(stateflags
));
126 return WII_ECHECKSUM
;
131 static s32
__WII_ReadNANDBootInfo(void)
136 fd
= IOS_Open(__nandbootinfo
,IPC_OPEN_READ
);
138 memset(&nandboot
,0,sizeof(nandboot
));
139 return WII_EINTERNAL
;
142 ret
= IOS_Read(fd
, &nandboot
, sizeof(nandboot
));
144 if(ret
!= sizeof(nandboot
)) {
145 memset(&nandboot
,0,sizeof(nandboot
));
146 return WII_EINTERNAL
;
148 if(!__ValidChecksum(&nandboot
, sizeof(nandboot
))) {
149 memset(&nandboot
,0,sizeof(nandboot
));
150 return WII_ECHECKSUM
;
155 static s32
__WII_WriteStateFlags(void)
160 __SetChecksum(&stateflags
, sizeof(stateflags
));
162 fd
= IOS_Open(__stateflags
,IPC_OPEN_READ
|IPC_OPEN_WRITE
);
164 return WII_EINTERNAL
;
167 ret
= IOS_Write(fd
, &stateflags
, sizeof(stateflags
));
169 if(ret
!= sizeof(stateflags
)) {
170 return WII_EINTERNAL
;
175 static s32
__WII_WriteNANDBootInfo(void)
180 __SetChecksum(&nandboot
, sizeof(nandboot
));
182 fd
= IOS_Open(__nandbootinfo
,IPC_OPEN_READ
|IPC_OPEN_WRITE
);
184 return WII_EINTERNAL
;
187 ret
= IOS_Write(fd
, &nandboot
, sizeof(nandboot
));
189 if(ret
!= sizeof(nandboot
)) {
190 return WII_EINTERNAL
;
195 s32
WII_Initialize(void)
197 __WII_ReadStateFlags();
198 __WII_ReadNANDBootInfo();
203 s32
__WII_SetArgs(const char **argv
)
214 for(i
=0; argv
[i
] != NULL
; i
++) {
215 argslen
+= strlen(argv
[i
]) + 1;
218 buflen
= (argslen
+ 3) & ~3;
225 argp
= 0x1000 - argslen
;
226 argvp
= 0x1000 - buflen
;
228 memset(&nandboot
.argbuf
, 0, sizeof(nandboot
.argbuf
));
230 nandboot
.argsoff
= 0x1000 + argvp
;
231 *((u32
*)&nandboot
.argbuf
[argvp
]) = argc
;
234 for(i
=0; i
<argc
; i
++) {
235 strcpy((char*)&nandboot
.argbuf
[argp
], argv
[i
]);
236 *((u32
*)&nandboot
.argbuf
[argvp
]) = argp
+ 0x1000;
238 argp
+= strlen(argv
[i
]) + 1;
240 *((u32
*)&nandboot
.argbuf
[argvp
]) = 0;
245 s32
WII_LaunchTitle(u64 titleID
)
249 STACK_ALIGN(tikview
,views
,4,32);
254 res
= ES_GetNumTicketViews(titleID
, &numviews
);
259 return WII_EINTERNAL
;
261 res
= ES_GetTicketViews(titleID
, views
, numviews
);
267 memset(&nandboot
,0,sizeof(NANDBootInfo
));
268 nandboot
.apptype
= 0x80;
269 if(titleID
== 0x100000002LL
)
270 nandboot
.titletype
= 4;
272 nandboot
.titletype
= 2;
273 if(ES_GetTitleID(&nandboot
.launcher
) < 0)
274 nandboot
.launcher
= 0x0000000100000002LL
;
275 nandboot
.checksum
= __CalcChecksum((u32
*)&nandboot
,sizeof(NANDBootInfo
));
276 __WII_WriteNANDBootInfo();
281 res
= ES_LaunchTitle(titleID
, &views
[0]);
284 return WII_EINTERNAL
;
287 s32
WII_LaunchTitleWithArgs(u64 titleID
, int launchcode
, ...)
290 const char *argv
[256];
297 sprintf(argv0
, "%016llx", titleID
);
301 va_start(args
, launchcode
);
304 argv
[argc
++] = va_arg(args
, const char *);
305 } while(argv
[argc
- 1] != NULL
);
309 if(ES_GetTitleID(&nandboot
.launcher
) < 0)
310 nandboot
.launcher
= 0x100000002LL
;
312 if(titleID
== 0x100000002LL
)
313 nandboot
.titletype
= 4;
315 nandboot
.titletype
= 2;
316 nandboot
.apptype
= 0x80;
317 nandboot
.launchcode
= launchcode
;
319 stateflags
.type
= TYPE_RETURN
;
320 stateflags
.returnto
= RETURN_TO_ARGS
;
324 __WII_WriteStateFlags();
325 __WII_WriteNANDBootInfo();
327 return WII_LaunchTitle(titleID
);
330 s32
WII_ReturnToMenu(void)
334 stateflags
.type
= TYPE_RETURN
;
335 stateflags
.returnto
= RETURN_TO_MENU
;
336 __WII_WriteStateFlags();
337 return WII_LaunchTitle(0x100000002LL
);
340 s32
WII_ReturnToSettings(void)
344 stateflags
.type
= TYPE_RETURN
;
345 stateflags
.returnto
= RETURN_TO_SETTINGS
;
346 __WII_WriteStateFlags();
347 return WII_LaunchTitle(0x100000002LL
);
350 s32
WII_ReturnToSettingsPage(const char *page
)
355 return WII_LaunchTitleWithArgs(0x100000002LL
, 1, page
, NULL
);
358 s32
WII_OpenURL(const char *url
)
370 ret
= ES_GetNumTitles(&titlecount
);
372 return WII_EINTERNAL
;
374 list
= memalign(32, titlecount
* sizeof(u64
) + 32);
376 ret
= ES_GetTitles(list
, titlecount
);
379 return WII_EINTERNAL
;
382 for(i
=0; i
<titlecount
; i
++) {
383 if((list
[i
] & ~0xFF) == 0x1000148414400LL
) {
393 if(ES_GetStoredTMDSize(tid
, &tmdsize
) < 0)
396 return WII_LaunchTitleWithArgs(tid
, 0, url
, NULL
);