s32 WII_LaunchTitleWithArgs(u64 titleID, int launchcode, ...) { char argv0[20]; const char *argv[256]; int argc = 1; va_list args; if(!__initialized) return WII_ENOTINIT; sprintf(argv0, "%016llx", titleID); argv[0] = argv0; va_start(args, launchcode); do { argv[argc++] = va_arg(args, const char *); } while(argv[argc - 1] != NULL); va_end(args); if(ES_GetTitleID(&nandboot.launcher) < 0) nandboot.launcher = 0x100000002LL; if(titleID == 0x100000002LL) nandboot.titletype = 4; else nandboot.titletype = 2; nandboot.apptype = 0x80; nandboot.launchcode = launchcode; stateflags.type = TYPE_RETURN; stateflags.returnto = RETURN_TO_ARGS; __WII_SetArgs(argv); __WII_WriteStateFlags(); __WII_WriteNANDBootInfo(); return WII_LaunchTitle(titleID); }
s32 SetNandBootInfo(void) { static NANDBootInfo BootInfo ATTRIBUTE_ALIGN(32); memset(&BootInfo,0,sizeof(NANDBootInfo)); BootInfo.apptype = 0x80; BootInfo.titletype = 2; if(ES_GetTitleID(&BootInfo.launcher) < 0) BootInfo.launcher = 0x0000000100000002LL; BootInfo.checksum = __CalcChecksum((u32*)&BootInfo,sizeof(NANDBootInfo)); s32 fd = ISFS_Open("/shared2/sys/NANDBOOTINFO", ISFS_OPEN_RW ); if(fd < 0) { return fd; } s32 ret = ISFS_Write(fd, &BootInfo, sizeof(NANDBootInfo)); if(ret < 0) { ISFS_Close(fd); gprintf("SetNandBootInfo : ISFS_Write returned %d\n",ret); return -2; } ISFS_Close(fd); return 1; }
int main(void) { u32 queuehandle; s32 ret; /* Avoid GCC optimizations */ exe_mem[0] = 0; /* Print info */ write("$IOSVersion: MLOAD: " __DATE__ " " __TIME__ " 64M$\n"); /* Initialize module */ ret = __MLoad_Initialize(&queuehandle); if (ret < 0) return ret; // Debug_SetMode(2); /* Initialize stuff */ Epic_Init(queuehandle); /* Main loop */ while (1) { ipcmessage *message = NULL; /* Wait for message */ os_message_queue_receive(queuehandle, (void *)&message, 0); /* Epic stuff */ if ((u32)message == EPIC_MESSAGE) { Epic_Main(); continue; } switch (message->command) { case IOS_OPEN: { u64 tid; /* Get title ID */ ret = ES_GetTitleID(&tid); /* Check title ID */ if (ret >= 0) { write("MLOAD: Title identified. Blocking opening request.\n"); ret = IPC_ENOENT; break; } /* Check device path */ if (!strcmp(message->open.device, DEVICE_NAME)) ret = message->open.resultfd; else ret = IPC_ENOENT; break; } case IOS_CLOSE: { /* Do nothing */ break; } case IOS_READ: { void *dst = message->read.data; void *src = (void *)offset; u32 len = message->read.length; /* Read data */ Swi_uMemcpy(dst, src, len); /* Update offset */ offset += len; } case IOS_WRITE: { void *dst = (void *)offset; void *src = message->write.data; u32 len = message->write.length; /* Write data */ Swi_Memcpy(dst, src, len); /* Update offset */ offset += len; } case IOS_SEEK: { s32 whence = message->seek.origin; s32 where = message->seek.offset; /* Update offset */ switch (whence) { case SEEK_SET: offset = where; break; case SEEK_CUR: offset += where; break; case SEEK_END: offset = -where; break; } /* Return offset */ ret = offset; break; } case IOS_IOCTLV: { ioctlv *vector = message->ioctlv.vector; u32 inlen = message->ioctlv.num_in; u32 iolen = message->ioctlv.num_io; u32 cmd = message->ioctlv.command; /* Parse IOCTLV */ ret = __MLoad_Ioctlv(cmd, vector, inlen, iolen); break; } default: /* Unknown command */ ret = IPC_EINVAL; } /* Acknowledge message */ os_message_queue_ack(message, ret); } return 0; }
static int identify(void){ // Identify as our own title void* dvdCert = NULL, * dvdTMD = NULL, * dvdTicket = NULL; unsigned int dvdCertSize, dvdTMDSize, dvdTicketSize, keyid; int ret; if(!customCert){ // If there's no certificate supplied #if 0 // Use the one from the DVD ret = getTitle(&dvdCert, &dvdCertSize, &dvdTMD, &dvdTMDSize, &dvdTicket, &dvdTicketSize); customCert = dvdCert; customCertSize = dvdCertSize; if(ret < 0) return ret; #else return identified = 0; #endif } ret = ES_Identify(customCert, customCertSize, customTMD, customTMDSize, customTicket, customTicketSize, &keyid); if(ret >= 0){ ES_GetTitleID(&titleID); ISFS_Initialize(); // If we haven't identified this title before // we'll need to set some things up char* path = memalign(32, 64);; ES_GetDataDir(titleID, path); strncat(path, "/banner.bin", 64); ret = ISFS_Open(path, 1); if(ret < 0){ // If the banner doesn't exist // Create our banner.bin ret = ISFS_CreateFile(path, 0, 3, 3, 1); if(ret < 0) return 0; ret = ISFS_Open(path, 2); if(ret < 0) return 0; ISFS_Write(ret, customBanner, customBannerSize); ISFS_Close(ret); // Create the N64SAVES directory ES_GetDataDir(titleID, path); strncat(path, "/N64SAVES", 64); ISFS_CreateDir(path, 0, 3, 3, 1); } else ISFS_Close(ret); free(path); return identified = 1; } #if 0 // If that still fails, try to identify from the discs certs if(!dvdCert || !dvdTMD || !dvdTicket) ret = getTitle(&dvdCert, &dvdCertSize, &dvdTMD, &dvdTMDSize, &dvdTicket, &dvdTicketSize); else ret = 0; if(ret >= 0){ ret = ES_Identify(dvdCert, dvdCertSize, dvdTMD, dvdTMDSize, dvdTicket, dvdTicketSize, &keyid); ES_GetTitleID(&titleID); ISFS_Initialize(); return identified = (ret >= 0); } #endif return identified = 0; }