mirror of
https://github.com/modmii/YAWM-ModMii-Edition.git
synced 2024-11-21 15:49:19 +01:00
- FAT stuff:
- Refactored almost everything - Will mount available devices at start and unmount at exit app - Device select screen will now only show avialable devices - Added option to remount devices in the select screen - Will now warn if region checks are disabled in select screen - Added option to reenable region checks in select screen - Probably even more changes - SM wad installation: - Changed the region check functions (WIP) - While you install a SM you'll now be able to retain Priiloader - Bug fixes - Refactoring - Even more bug fixes
This commit is contained in:
parent
2d2592a890
commit
31d2402d59
1416
Test/menu.c
1416
Test/menu.c
File diff suppressed because it is too large
Load Diff
BIN
data/appboot.bin
BIN
data/appboot.bin
Binary file not shown.
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
128
source/fat.c
128
source/fat.c
@ -1,58 +1,104 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
|
||||
//#include <smb.h>
|
||||
|
||||
#include "fat.h"
|
||||
#include "usbstorage.h"
|
||||
|
||||
|
||||
s32 Fat_Mount(fatDevice *dev)
|
||||
typedef struct
|
||||
{
|
||||
s32 ret;
|
||||
/* Device prefix */
|
||||
char* prefix;
|
||||
|
||||
/* Initialize interface */
|
||||
ret = dev->interface->startup();
|
||||
if (!ret)
|
||||
return -1;
|
||||
/* Device name */
|
||||
char* name;
|
||||
|
||||
/* Mount device */
|
||||
ret = fatMountSimple(dev->mount, dev->interface);
|
||||
if (!ret)
|
||||
return -1;
|
||||
/* Device available */
|
||||
bool isMounted;
|
||||
|
||||
return 0;
|
||||
/* Device interface */
|
||||
const DISC_INTERFACE* interface;
|
||||
} FatDevice;
|
||||
|
||||
static FatDevice DeviceList[] =
|
||||
{
|
||||
{ "sd", "Wii SD Slot", false, &__io_wiisd },
|
||||
{ "usb", "USB Mass Storage Device", false, &__io_usbstorage },
|
||||
{ "usb2", "USB 2.0 Mass Storage Device", false, &__io_wiiums },
|
||||
{ "gcsda", "SD Gecko (Slot A)", false, &__io_gcsda },
|
||||
{ "gcsdb", "SD Gecko (Slot B)", false, &__io_gcsdb },
|
||||
};
|
||||
|
||||
static u32 gNumDevices = 0;
|
||||
FatDevice* gDevices[(sizeof(DeviceList) / sizeof(FatDevice))];
|
||||
|
||||
void FatMount()
|
||||
{
|
||||
FatUnmount();
|
||||
|
||||
s32 i;
|
||||
for (i = 0; i < (sizeof(DeviceList) / sizeof(FatDevice)); i++)
|
||||
{
|
||||
gDevices[gNumDevices] = &DeviceList[i];
|
||||
|
||||
s32 ret = gDevices[gNumDevices]->interface->startup();
|
||||
|
||||
if (!ret)
|
||||
continue;
|
||||
|
||||
ret = fatMountSimple(gDevices[gNumDevices]->prefix, gDevices[gNumDevices]->interface);
|
||||
|
||||
if (!ret)
|
||||
continue;
|
||||
|
||||
gDevices[gNumDevices]->isMounted = true;
|
||||
gNumDevices++;
|
||||
}
|
||||
}
|
||||
|
||||
void Fat_Unmount(fatDevice *dev)
|
||||
void FatUnmount()
|
||||
{
|
||||
/* Unmount device */
|
||||
fatUnmount(dev->mount);
|
||||
|
||||
/* Shutdown interface */
|
||||
dev->interface->shutdown();
|
||||
}
|
||||
|
||||
char *Fat_ToFilename(const char *filename)
|
||||
{
|
||||
static char buffer[128];
|
||||
|
||||
u32 cnt, idx, len;
|
||||
|
||||
/* Clear buffer */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
/* Get filename length */
|
||||
len = strlen(filename);
|
||||
|
||||
for (cnt = idx = 0; idx < len; idx++) {
|
||||
char c = filename[idx];
|
||||
|
||||
/* Valid characters */
|
||||
if ( (c >= '#' && c <= ')') || (c >= '-' && c <= '.') ||
|
||||
(c >= '0' && c <= '9') || (c >= 'A' && c <= 'z') ||
|
||||
(c >= 'a' && c <= 'z') || (c == '!') )
|
||||
buffer[cnt++] = c;
|
||||
s32 i;
|
||||
for (i = 0; i < FatGetDeviceCount(); i++)
|
||||
{
|
||||
fatUnmount(gDevices[i]->prefix);
|
||||
gDevices[i]->interface->shutdown();
|
||||
gDevices[i]->isMounted = false;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
gNumDevices = 0;
|
||||
}
|
||||
|
||||
char* FatGetDeviceName(u8 index)
|
||||
{
|
||||
if (index >= FatGetDeviceCount())
|
||||
return NULL;
|
||||
|
||||
if (gDevices[index]->isMounted)
|
||||
return gDevices[index]->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char* FatGetDevicePrefix(u8 index)
|
||||
{
|
||||
if (index >= FatGetDeviceCount())
|
||||
return NULL;
|
||||
|
||||
if (gDevices[index]->isMounted)
|
||||
return gDevices[index]->prefix;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s32 FatGetDeviceCount()
|
||||
{
|
||||
return gNumDevices;
|
||||
}
|
||||
|
31
source/fat.h
31
source/fat.h
@ -1,27 +1,6 @@
|
||||
#ifndef _FAT_H_
|
||||
#define _FAT_H_
|
||||
|
||||
/* libfat header */
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
/* SD headers */
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
|
||||
|
||||
/* 'FAT Device' structure */
|
||||
typedef struct {
|
||||
/* Device mount point */
|
||||
char *mount;
|
||||
|
||||
/* Device name */
|
||||
char *name;
|
||||
|
||||
/* Device interface */
|
||||
const DISC_INTERFACE *interface;
|
||||
} fatDevice;
|
||||
|
||||
/* 'FAT File' structure */
|
||||
typedef struct {
|
||||
/* Filename */
|
||||
@ -41,9 +20,11 @@ typedef struct {
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
s32 Fat_Mount(fatDevice *);
|
||||
void Fat_Unmount(fatDevice *);
|
||||
char *Fat_ToFilename(const char *);
|
||||
|
||||
void FatMount();
|
||||
void FatUnmount();
|
||||
char* FatGetDeviceName(u8 index);
|
||||
char* FatGetDevicePrefix(u8 index);
|
||||
s32 FatGetDeviceCount();
|
||||
|
||||
#endif
|
||||
|
||||
|
80
source/fileops.c
Normal file
80
source/fileops.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "fileops.h"
|
||||
|
||||
|
||||
bool FSOPFileExists(const char* file)
|
||||
{
|
||||
FILE* f;
|
||||
f = fopen(file, "rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSOPFolderExists(const char* path)
|
||||
{
|
||||
DIR* dir;
|
||||
dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t FSOPGetFileSizeBytes(const char* path)
|
||||
{
|
||||
FILE* f;
|
||||
size_t size = 0;
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
fclose(f);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void FSOPDeleteFile(const char* file)
|
||||
{
|
||||
if (!FSOPFileExists(file))
|
||||
return;
|
||||
|
||||
remove(file);
|
||||
}
|
||||
|
||||
void FSOPMakeFolder(const char* path)
|
||||
{
|
||||
if (FSOPFolderExists(path))
|
||||
return;
|
||||
|
||||
mkdir(path, S_IREAD | S_IWRITE);
|
||||
}
|
||||
|
||||
s32 FSOPReadOpenFile(FILE* fp, void* buffer, u32 offset, u32 length)
|
||||
{
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
return fread(buffer, length, 1, fp);
|
||||
}
|
||||
|
||||
s32 FSOPReadOpenFileA(FILE* fp, void** buffer, u32 offset, u32 length)
|
||||
{
|
||||
*buffer = memalign(32, length);
|
||||
if (!*buffer)
|
||||
return -1;
|
||||
|
||||
s32 ret = FSOPReadOpenFile(fp, *buffer, offset, length);
|
||||
if (ret < 0)
|
||||
free(*buffer);
|
||||
|
||||
return ret;
|
||||
}
|
17
source/fileops.h
Normal file
17
source/fileops.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __FILEOPS_H__
|
||||
#define __FILEOPS_H__
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
bool FSOPFileExists(const char* file);
|
||||
bool FSOPFolderExists(const char* path);
|
||||
size_t FSOPGetFileSizeBytes(const char* path);
|
||||
|
||||
void FSOPDeleteFile(const char* file);
|
||||
void FSOPMakeFolder(const char* path);
|
||||
|
||||
s32 FSOPReadOpenFile(FILE* fp, void* buffer, u32 offset, u32 length);
|
||||
s32 FSOPReadOpenFileA(FILE* fp, void** buffer, u32 offset, u32 length);
|
||||
|
||||
#endif
|
@ -3,7 +3,7 @@
|
||||
|
||||
// Constants
|
||||
#define CIOS_VERSION 249
|
||||
#define ENTRIES_PER_PAGE 14
|
||||
#define ENTRIES_PER_PAGE 12
|
||||
#define MAX_FILE_PATH_LEN 1024
|
||||
#define MAX_DIR_LEVELS 10
|
||||
#define WAD_DIRECTORY "/"
|
||||
@ -16,20 +16,8 @@
|
||||
#define WM_CONFIG_FILE_PATH ":/wad/wm_config.txt"
|
||||
#define WM_BACKGROUND_PATH ":/wad/background.png"
|
||||
|
||||
// These are indices into the fatDevice fdevList
|
||||
#define FAT_DEVICE_INDEX_WII_SD 0
|
||||
#define FAT_DEVICE_INDXE_USB 1
|
||||
#define FAT_DEVICE_INDEX_USB2 2
|
||||
#define FAT_DEVICE_INDEX_GC_SDA 3
|
||||
#define FAT_DEVICE_INDEX_GC_SDB 4
|
||||
#define FAT_DEVICE_INDEX_INVALID -1
|
||||
|
||||
// These are the indices into the nandDevice ndevList
|
||||
#define NAND_DEVICE_INDEX_DISABLE 0
|
||||
#define NAND_DEVICE_INDEX_SD 1
|
||||
#define NAND_DEVICE_INDEX_USB 2
|
||||
#define NAND_DEVICE_INDEX_INVALID -1
|
||||
|
||||
#define CIOS_VERSION_INVALID -1
|
||||
|
||||
// For the WiiLight
|
||||
@ -52,7 +40,7 @@ typedef struct
|
||||
|
||||
extern CONFIG gConfig;
|
||||
extern nandDevice ndevList[];
|
||||
extern fatDevice fdevList[];
|
||||
//extern fatDevice fdevList[];
|
||||
|
||||
|
||||
#endif
|
||||
|
37
source/gui.c
37
source/gui.c
@ -7,6 +7,7 @@
|
||||
#include "menu.h"
|
||||
#include "nand.h"
|
||||
#include "globals.h"
|
||||
#include "fileops.h"
|
||||
|
||||
/* Constants */
|
||||
#define CONSOLE_XCOORD 70
|
||||
@ -14,36 +15,25 @@
|
||||
#define CONSOLE_WIDTH 502
|
||||
#define CONSOLE_HEIGHT 300
|
||||
|
||||
bool file_exists(const char * filename)
|
||||
{
|
||||
FILE * file;
|
||||
if ((file = fopen(filename, "r")))
|
||||
{
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
s32 __Gui_DrawPng(void *img, u32 x, u32 y)
|
||||
{
|
||||
IMGCTX ctx = NULL;
|
||||
PNGUPROP imgProp;
|
||||
char path[1024];
|
||||
s32 ret = -1;
|
||||
s32 i;
|
||||
|
||||
s32 ret;
|
||||
|
||||
fatDevice *fdev = &fdevList[0];
|
||||
ret = Fat_Mount(fdev);
|
||||
if (file_exists("sd:/wad/background.png")) ctx = PNGU_SelectImageFromDevice ("sd:/wad/background.png");
|
||||
|
||||
if (ret < 0)
|
||||
for (i = 0; i < FatGetDeviceCount(); i++)
|
||||
{
|
||||
fdev = &fdevList[2];
|
||||
Fat_Mount(fdev);
|
||||
if (file_exists("usb2:/wad/background.png")) ctx = PNGU_SelectImageFromDevice ("usb2:/wad/background.png");
|
||||
snprintf(path, sizeof(path), "%s:/wad/background.png", FatGetDevicePrefix(i));
|
||||
if (FSOPFileExists(path))
|
||||
{
|
||||
ctx = PNGU_SelectImageFromDevice(path);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(!ctx)
|
||||
{
|
||||
/* Select PNG data */
|
||||
@ -53,6 +43,7 @@ s32 __Gui_DrawPng(void *img, u32 x, u32 y)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get image properties */
|
||||
ret = PNGU_GetImageProperties(ctx, &imgProp);
|
||||
if (ret != PNGU_OK) {
|
||||
|
@ -74,6 +74,8 @@ const u8 ES_TitleVersionCheck_old[] = { 0xD2, 0x01, 0x4E, 0x56 };
|
||||
const u8 ES_TitleVersionCheck_patch[] = { 0xE0, 0x01, 0x4E, 0x56 };
|
||||
const u8 ES_TitleDeleteCheck_old[] = { 0xD8, 0x00, 0x4A, 0x04 };
|
||||
const u8 ES_TitleDeleteCheck_patch[] = { 0xE0, 0x00, 0x4A, 0x04 };
|
||||
const u8 isfs_permissions_old[] = { 0x9B, 0x05, 0x40, 0x03, 0x99, 0x05, 0x42, 0x8B, };
|
||||
const u8 isfs_permissions_patch[] = { 0x9B, 0x05, 0x40, 0x03, 0x1C, 0x0B, 0x42, 0x8B, };
|
||||
|
||||
//Following patches made my damysteryman for use with Wii U's vWii
|
||||
const u8 Kill_AntiSysTitleInstallv3_pt1_old[] = { 0x68, 0x1A, 0x2A, 0x01, 0xD0, 0x05 }; // Make sure that the pt1
|
||||
@ -97,7 +99,7 @@ u32 IOSPATCH_Apply() {
|
||||
if (AHBPROT_DISABLED) {
|
||||
disable_memory_protection();
|
||||
//count += apply_patch("di_readlimit", di_readlimit_old, sizeof(di_readlimit_old), di_readlimit_patch, sizeof(di_readlimit_patch), 12);
|
||||
//count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0);
|
||||
count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0);
|
||||
//count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0);
|
||||
//count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2);
|
||||
count += apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1);
|
||||
|
663
source/menu.c
663
source/menu.c
@ -12,7 +12,6 @@
|
||||
#include "nand.h"
|
||||
#include "restart.h"
|
||||
#include "title.h"
|
||||
#include "usbstorage.h"
|
||||
#include "utils.h"
|
||||
#include "video.h"
|
||||
#include "wad.h"
|
||||
@ -21,27 +20,16 @@
|
||||
#include "globals.h"
|
||||
#include "iospatch.h"
|
||||
#include "appboot.h"
|
||||
|
||||
/* FAT device list */
|
||||
//static fatDevice fdevList[] = {
|
||||
fatDevice fdevList[] = {
|
||||
{ "sd", "Wii SD Slot", &__io_wiisd },
|
||||
{ "usb", "USB Mass Storage Device", &__io_usbstorage },
|
||||
{ "usb2", "USB 2.0 Mass Storage Device", &__io_wiiums },
|
||||
{ "gcsda", "SD Gecko (Slot A)", &__io_gcsda },
|
||||
{ "gcsdb", "SD Gecko (Slot B)", &__io_gcsdb },
|
||||
};
|
||||
#include "fileops.h"
|
||||
|
||||
/* NAND device list */
|
||||
//static nandDevice ndevList[] = {
|
||||
nandDevice ndevList[] = {
|
||||
nandDevice ndevList[] =
|
||||
{
|
||||
{ "Disable", 0, 0x00, 0x00 },
|
||||
{ "SD/SDHC Card", 1, 0xF0, 0xF1 },
|
||||
{ "USB 2.0 Mass Storage Device", 2, 0xF2, 0xF3 },
|
||||
};
|
||||
|
||||
/* FAT device */
|
||||
static fatDevice *fdev = NULL;
|
||||
static nandDevice *ndev = NULL;
|
||||
|
||||
// wiiNinja: Define a buffer holding the previous path names as user
|
||||
@ -50,9 +38,12 @@ static u8 gDirLevel = 0;
|
||||
static char gDirList [MAX_DIR_LEVELS][MAX_FILE_PATH_LEN];
|
||||
static s32 gSeleted[MAX_DIR_LEVELS];
|
||||
static s32 gStart[MAX_DIR_LEVELS];
|
||||
static char gMenuRegion = '\0';
|
||||
static u16 gMenuVersion = 0;
|
||||
static u8 gSelected = 0;
|
||||
|
||||
/* Macros */
|
||||
#define NB_FAT_DEVICES (sizeof(fdevList) / sizeof(fatDevice))
|
||||
//#define NB_FAT_DEVICES (sizeof(fdevList) / sizeof(fatDevice))
|
||||
#define NB_NAND_DEVICES (sizeof(ndevList) / sizeof(nandDevice))
|
||||
|
||||
// Local prototypes: wiiNinja
|
||||
@ -92,34 +83,6 @@ int __Menu_EntryCmp(const void *p1, const void *p2)
|
||||
return strcasecmp(f1->filename, f2->filename);
|
||||
}
|
||||
|
||||
static bool __FolderExists(const char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
dir = opendir(path);
|
||||
if(dir)
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t __GetFileSizeBytes(const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
size_t size = 0;
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if(!f) return 0;
|
||||
|
||||
//Get file size
|
||||
fseek(f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
fclose(f);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
char gFileName[MAX_FILE_PATH_LEN];
|
||||
s32 __Menu_RetrieveList(char *inPath, fatFile **outbuf, u32 *outlen)
|
||||
{
|
||||
@ -165,7 +128,7 @@ s32 __Menu_RetrieveList(char *inPath, fatFile **outbuf, u32 *outlen)
|
||||
size_t fsize = 0;
|
||||
|
||||
snprintf(gFileName, MAX_FILE_PATH_LEN, "%s/%s", inPath, ent->d_name);
|
||||
if (__FolderExists(gFileName)) // wiiNinja
|
||||
if (FSOPFolderExists(gFileName)) // wiiNinja
|
||||
{
|
||||
isdir = true;
|
||||
// Add only the item ".." which is the previous directory
|
||||
@ -181,19 +144,19 @@ s32 __Menu_RetrieveList(char *inPath, fatFile **outbuf, u32 *outlen)
|
||||
{
|
||||
if(!strcasecmp(ent->d_name+strlen(ent->d_name)-4, ".wad"))
|
||||
{
|
||||
fsize = __GetFileSizeBytes(gFileName);
|
||||
fsize = FSOPGetFileSizeBytes(gFileName);
|
||||
addFlag = true;
|
||||
iswad = true;
|
||||
}
|
||||
if(!strcasecmp(ent->d_name+strlen(ent->d_name)-4, ".dol"))
|
||||
{
|
||||
fsize = __GetFileSizeBytes(gFileName);
|
||||
fsize = FSOPGetFileSizeBytes(gFileName);
|
||||
addFlag = true;
|
||||
isdol = true;
|
||||
}
|
||||
if(!strcasecmp(ent->d_name+strlen(ent->d_name)-4, ".elf"))
|
||||
{
|
||||
fsize = __GetFileSizeBytes(gFileName);
|
||||
fsize = FSOPGetFileSizeBytes(gFileName);
|
||||
addFlag = true;
|
||||
iself = true;
|
||||
}
|
||||
@ -333,74 +296,94 @@ void Menu_SelectIOS(void)
|
||||
|
||||
void Menu_FatDevice(void)
|
||||
{
|
||||
int ret, selected = 0;
|
||||
FatMount();
|
||||
|
||||
/* Unmount FAT device */
|
||||
//if (fdev)
|
||||
//Fat_Unmount(fdev);
|
||||
//if (((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S')))
|
||||
//selected++;
|
||||
static const u16 konamiCode[] = {
|
||||
const u16 konamiCode[] =
|
||||
{
|
||||
WPAD_BUTTON_UP, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT,
|
||||
WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT, WPAD_BUTTON_B, WPAD_BUTTON_A
|
||||
};
|
||||
|
||||
int codePosition = 0;
|
||||
extern bool skipRegionSafetyCheck;
|
||||
|
||||
/* Select source device */
|
||||
if (gConfig.fatDeviceIndex < 0)
|
||||
{
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
/* Clear console */
|
||||
Con_Clear();
|
||||
|
||||
if (!FatGetDeviceCount())
|
||||
{
|
||||
printf("\t[+] No source device: < %s >\n\n", FatGetDeviceName(gSelected));
|
||||
}
|
||||
|
||||
/* Selected device */
|
||||
fdev = &fdevList[selected];
|
||||
|
||||
printf("\t>> Select source device: < %s >\n\n", fdev->name);
|
||||
|
||||
//printf("\tWii menu version: %d, region: %s\n\n", gMenuVersion, GetSysMenuRegionString(&gMenuRegion));
|
||||
printf("\t>> Select source device: < %s >\n\n", FatGetDeviceName(gSelected));
|
||||
printf("\t Press LEFT/RIGHT to change the selected device.\n\n");
|
||||
|
||||
printf("\t Press A button to continue.\n");
|
||||
printf("\t Press B button to remount source devices.\n");
|
||||
printf("\t Press HOME button to restart.\n\n");
|
||||
|
||||
if (skipRegionSafetyCheck)
|
||||
{
|
||||
printf("[+] WARNING: SM Region checks disabled!\n\n");
|
||||
printf("\t Press 1 button to reset.\n");
|
||||
}
|
||||
|
||||
|
||||
u32 buttons = WaitButtons();
|
||||
|
||||
if (buttons & (WPAD_BUTTON_UP | WPAD_BUTTON_DOWN | WPAD_BUTTON_RIGHT | WPAD_BUTTON_LEFT | WPAD_BUTTON_A | WPAD_BUTTON_B)) {
|
||||
if (buttons & konamiCode[codePosition])
|
||||
++codePosition;
|
||||
else
|
||||
codePosition = 0;
|
||||
if (buttons & (WPAD_BUTTON_UP | WPAD_BUTTON_DOWN | WPAD_BUTTON_RIGHT | WPAD_BUTTON_LEFT | WPAD_BUTTON_A | WPAD_BUTTON_B))
|
||||
{
|
||||
if (!skipRegionSafetyCheck)
|
||||
{
|
||||
if (buttons & konamiCode[codePosition])
|
||||
++codePosition;
|
||||
else
|
||||
codePosition = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* LEFT/RIGHT buttons */
|
||||
if (buttons & WPAD_BUTTON_LEFT) {
|
||||
if ((--selected) <= -1)
|
||||
selected = (NB_FAT_DEVICES - 1);
|
||||
if ((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S'))
|
||||
selected--;
|
||||
if ((fdevList[selected].mount[0] == 'u' && fdevList[selected].mount[3] == '2') && (ndev->name[0] == 'U'))
|
||||
selected--;
|
||||
if ((selected) <= -1)
|
||||
selected = (NB_FAT_DEVICES - 1);
|
||||
if (buttons & WPAD_BUTTON_LEFT)
|
||||
{
|
||||
if ((s8)(--gSelected) < 0)
|
||||
gSelected = FatGetDeviceCount() - 1;
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_RIGHT) {
|
||||
if ((++selected) >= NB_FAT_DEVICES)
|
||||
selected = 0;
|
||||
if ((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S'))
|
||||
selected++;
|
||||
if ((fdevList[selected].mount[0] == 'u' && fdevList[selected].mount[3] == '2') && (ndev->name[0] == 'U'))
|
||||
selected++;
|
||||
else if (buttons & WPAD_BUTTON_1 && skipRegionSafetyCheck)
|
||||
{
|
||||
skipRegionSafetyCheck = false;
|
||||
}
|
||||
|
||||
/* HOME button */
|
||||
if (buttons & WPAD_BUTTON_HOME)
|
||||
else if (buttons & WPAD_BUTTON_RIGHT)
|
||||
{
|
||||
if ((++gSelected) >= FatGetDeviceCount())
|
||||
gSelected = 0;
|
||||
}
|
||||
else if (buttons & WPAD_BUTTON_HOME)
|
||||
{
|
||||
Restart();
|
||||
|
||||
/* A button */
|
||||
if (buttons & WPAD_BUTTON_A) {
|
||||
if (codePosition == sizeof(konamiCode) / sizeof(konamiCode[0])) {
|
||||
extern bool skipRegionSafetyCheck;
|
||||
}
|
||||
else if (buttons & WPAD_BUTTON_B && !codePosition)
|
||||
{
|
||||
printf("\t\t[-] Mounting devices.");
|
||||
usleep(500000);
|
||||
printf("\r\t\t[\\]");
|
||||
usleep(500000);
|
||||
printf("\r\t\t[|]");
|
||||
usleep(500000);
|
||||
printf("\r\t\t[/]");
|
||||
usleep(500000);
|
||||
printf("\r\t\t[-]");
|
||||
FatMount();
|
||||
gSelected = 0;
|
||||
usleep(500000);
|
||||
}
|
||||
else if (buttons & WPAD_BUTTON_A)
|
||||
{
|
||||
if (codePosition == sizeof(konamiCode) / sizeof(konamiCode[0]))
|
||||
{
|
||||
skipRegionSafetyCheck = true;
|
||||
printf("[+] Disabled SM region checks\n");
|
||||
sleep(3);
|
||||
@ -412,34 +395,12 @@ void Menu_FatDevice(void)
|
||||
else
|
||||
{
|
||||
sleep(5);
|
||||
fdev = &fdevList[gConfig.fatDeviceIndex];
|
||||
if (gConfig.fatDeviceIndex < FatGetDeviceCount())
|
||||
gSelected = gConfig.fatDeviceIndex;
|
||||
}
|
||||
|
||||
printf("[+] Mounting %s, please wait...", fdev->name );
|
||||
fflush(stdout);
|
||||
|
||||
/* Mount FAT device */
|
||||
|
||||
ret = Fat_Mount(fdev);
|
||||
if (ret < 0) {
|
||||
printf(" ERROR! (ret = %d)\n", ret);
|
||||
goto err;
|
||||
} else
|
||||
printf(" OK!\n");
|
||||
printf("[+] Selected source device: %s.", FatGetDeviceName(gSelected));
|
||||
sleep(2);
|
||||
return;
|
||||
|
||||
err:
|
||||
|
||||
if(gConfig.fatDeviceIndex >= 0) gConfig.fatDeviceIndex = -1;
|
||||
WiiLightControl (WII_LIGHT_OFF);
|
||||
printf("\n");
|
||||
printf(" Press any button to continue...\n");
|
||||
|
||||
WaitButtons();
|
||||
|
||||
/* Prompt menu again */
|
||||
Menu_FatDevice();
|
||||
}
|
||||
|
||||
void Menu_NandDevice(void)
|
||||
@ -845,45 +806,58 @@ void Menu_WadList(void)
|
||||
|
||||
gDirLevel = 0;
|
||||
|
||||
// push root dir as base folder
|
||||
sprintf(tmpPath, "%s:%s", fdev->mount, WAD_DIRECTORY);
|
||||
// push root dir as base folderGetDevice()
|
||||
//sprintf(tmpPath, "%s:%s", fdev->mount, WAD_DIRECTORY);
|
||||
sprintf(tmpPath, "%s:%s", FatGetDevicePrefix(gSelected), WAD_DIRECTORY);
|
||||
PushCurrentDir(tmpPath,0,0);
|
||||
// if user provides startup directory, try it out first
|
||||
if (strcmp (WAD_DIRECTORY, gConfig.startupPath) != 0)
|
||||
{
|
||||
// replace root dir with provided startup directory
|
||||
sprintf(tmpPath, "%s:%s", fdev->mount, gConfig.startupPath);
|
||||
// If the directory can be successfully opened, it must exists
|
||||
DIR *tmpDirPtr = opendir(tmpPath);
|
||||
if (tmpDirPtr)
|
||||
{
|
||||
closedir (tmpDirPtr);
|
||||
PushCurrentDir(tmpPath,0,0);
|
||||
}
|
||||
else // unable to open provided dir, stick with root dir
|
||||
sprintf(tmpPath, "%s:%s", fdev->mount, WAD_DIRECTORY);
|
||||
sprintf(tmpPath, "%s:%s", FatGetDevicePrefix(gSelected), gConfig.startupPath);
|
||||
|
||||
if (FSOPFolderExists(tmpPath))
|
||||
PushCurrentDir(tmpPath, 0, 0);
|
||||
else
|
||||
sprintf(tmpPath, "%s:%s", FatGetDevicePrefix(gSelected), WAD_DIRECTORY);
|
||||
|
||||
// If the directory can be successfully opened, it must exists
|
||||
// DIR *tmpDirPtr = opendir(tmpPath);
|
||||
// if (tmpDirPtr)
|
||||
// {
|
||||
// closedir (tmpDirPtr);
|
||||
// PushCurrentDir(tmpPath,0,0);
|
||||
// }
|
||||
//else // unable to open provided dir, stick with root dir
|
||||
//{
|
||||
// sprintf(tmpPath, "%s:%s", FatGetDevicePrefix(gSelected), WAD_DIRECTORY);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
/* Retrieve filelist */
|
||||
getList:
|
||||
free (fileList);
|
||||
free(fileList);
|
||||
fileList = NULL;
|
||||
|
||||
ret = __Menu_RetrieveList(tmpPath, &fileList, &fileCnt);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
printf(" ERROR! (ret = %d)\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* No files */
|
||||
if (!fileCnt) {
|
||||
if (!fileCnt)
|
||||
{
|
||||
printf(" No files found!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Set install-values to 0 - Leathl */
|
||||
int counter;
|
||||
for (counter = 0; counter < fileCnt; counter++) {
|
||||
for (counter = 0; counter < fileCnt; counter++)
|
||||
{
|
||||
fatFile *file = &fileList[counter];
|
||||
file->install = 0;
|
||||
}
|
||||
@ -898,8 +872,8 @@ getList:
|
||||
|
||||
/** Print entries **/
|
||||
cnt = strlen(tmpPath);
|
||||
if(cnt>30)
|
||||
index = cnt-30;
|
||||
if(cnt > 30)
|
||||
index = cnt - 30;
|
||||
else
|
||||
index = 0;
|
||||
|
||||
@ -916,13 +890,16 @@ getList:
|
||||
break;
|
||||
|
||||
strncpy(str, file->filename, 40); //Only 40 chars to fit the screen
|
||||
str[40]=0;
|
||||
str[40] = 0;
|
||||
|
||||
/* Print filename */
|
||||
//printf("\t%2s %s (%.2f MB)\n", (cnt == selected) ? ">>" : " ", file->filename, filesize);
|
||||
if (file->isdir) // wiiNinja
|
||||
{
|
||||
printf("\t%2s [%s]\n", (cnt == selected) ? ">>" : " ", str);
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if(file->iswad)
|
||||
printf("\t%2s%s%s (%.2f MB)\n", (cnt == selected) ? ">>" : " ", (file->install == 1) ? "+" : ((file->install == 2) ? "-" : " "), str, filesize);
|
||||
else
|
||||
@ -932,270 +909,285 @@ getList:
|
||||
|
||||
printf("\n");
|
||||
fatFile *file = &fileList[selected];
|
||||
if(file->iswad)
|
||||
printf("[+] Press A to (un)install.");
|
||||
else if(file->isdol || file->iself)
|
||||
printf("[+] Press A to launch dol/elf.");
|
||||
else if(file->isdir)
|
||||
printf("[+] Press A to Enter directory.");
|
||||
if(gDirLevel>1)
|
||||
|
||||
if (file->iswad)
|
||||
printf("[+] Press A to (un)install.");
|
||||
else if (file->isdol || file->iself)
|
||||
printf("[+] Press A to launch dol/elf.");
|
||||
else if (file->isdir)
|
||||
printf("[+] Press A to Enter directory.");
|
||||
|
||||
if (gDirLevel > 1)
|
||||
printf(" Press B to go up-level DIR.\n");
|
||||
else
|
||||
printf(" Press B to select a device.\n");
|
||||
if(file->iswad) printf(" Use +/X and -/Y to (un)mark. Press 1/Z/ZR for delete menu.");
|
||||
|
||||
if (file->iswad)
|
||||
printf(" Use +/X and -/Y to (un)mark. Press 1/Z/ZR for delete menu.");
|
||||
|
||||
/** Controls **/
|
||||
u32 buttons = WaitButtons();
|
||||
|
||||
/* DPAD buttons */
|
||||
if (buttons & WPAD_BUTTON_UP) {
|
||||
selected--;
|
||||
|
||||
if (selected <= -1)
|
||||
if (buttons & WPAD_BUTTON_UP)
|
||||
{
|
||||
if (--selected < 0)
|
||||
selected = (fileCnt - 1);
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_LEFT) {
|
||||
selected = selected + ENTRIES_PER_PAGE;
|
||||
else if (buttons & WPAD_BUTTON_LEFT)
|
||||
{
|
||||
selected += ENTRIES_PER_PAGE;
|
||||
|
||||
if (selected >= fileCnt)
|
||||
selected = 0;
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_DOWN) {
|
||||
selected ++;
|
||||
|
||||
if (selected >= fileCnt)
|
||||
else if (buttons & WPAD_BUTTON_DOWN)
|
||||
{
|
||||
if (++selected >= fileCnt)
|
||||
selected = 0;
|
||||
}
|
||||
if (buttons & WPAD_BUTTON_RIGHT) {
|
||||
selected = selected - ENTRIES_PER_PAGE;
|
||||
else if (buttons & WPAD_BUTTON_RIGHT)
|
||||
{
|
||||
selected -= ENTRIES_PER_PAGE;
|
||||
|
||||
if (selected <= -1)
|
||||
if (selected < 0)
|
||||
selected = (fileCnt - 1);
|
||||
}
|
||||
|
||||
/* HOME button */
|
||||
if (buttons & WPAD_BUTTON_HOME)
|
||||
else if (buttons & WPAD_BUTTON_HOME)
|
||||
{
|
||||
Restart();
|
||||
if(file->iswad) {
|
||||
/* Plus Button - Leathl */
|
||||
if (buttons & WPAD_BUTTON_PLUS)
|
||||
}
|
||||
|
||||
if (file->iswad)
|
||||
{
|
||||
if(Wpad_TimeButton())
|
||||
/* Plus Button - Leathl */
|
||||
if (buttons & WPAD_BUTTON_PLUS)
|
||||
{
|
||||
installCnt = 0;
|
||||
int i = 0;
|
||||
while( i < fileCnt)
|
||||
{
|
||||
fatFile *file = &fileList[i];
|
||||
if (((file->isdir) == false) & (file->install == 0)) {
|
||||
file->install = 1;
|
||||
if(Wpad_TimeButton())
|
||||
{
|
||||
installCnt = 0;
|
||||
int i = 0;
|
||||
while( i < fileCnt)
|
||||
{
|
||||
fatFile *file = &fileList[i];
|
||||
if (((file->isdir) == false) && (file->install == 0))
|
||||
{
|
||||
file->install = 1;
|
||||
installCnt += 1;
|
||||
}
|
||||
else if (((file->isdir) == false) && (file->install == 1))
|
||||
{
|
||||
file->install = 0;
|
||||
installCnt--;
|
||||
}
|
||||
else if (((file->isdir) == false) && (file->install == 2))
|
||||
{
|
||||
file->install = 1;
|
||||
|
||||
installCnt += 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 1)) {
|
||||
file->install = 0;
|
||||
installCnt++;
|
||||
uninstallCnt--;
|
||||
}
|
||||
|
||||
installCnt -= 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2)) {
|
||||
file->install = 1;
|
||||
|
||||
installCnt += 1;
|
||||
uninstallCnt -= 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatFile *file = &fileList[selected];
|
||||
if (((file->isdir) == false) && (file->install == 0))
|
||||
{
|
||||
file->install = 1;
|
||||
installCnt++;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 1))
|
||||
{
|
||||
file->install = 0;
|
||||
installCnt--;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2))
|
||||
{
|
||||
file->install = 1;
|
||||
|
||||
installCnt++;
|
||||
uninstallCnt--;
|
||||
}
|
||||
|
||||
selected++;
|
||||
if (selected >= fileCnt)
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Minus Button - Leathl */
|
||||
else if (buttons & WPAD_BUTTON_MINUS)
|
||||
{
|
||||
fatFile *file = &fileList[selected];
|
||||
if (((file->isdir) == false) & (file->install == 0)) {
|
||||
file->install = 1;
|
||||
if(Wpad_TimeButton())
|
||||
{
|
||||
installCnt = 0;
|
||||
int i = 0;
|
||||
|
||||
while( i < fileCnt)
|
||||
{
|
||||
fatFile *file = &fileList[i];
|
||||
if (((file->isdir) == false) && (file->install == 0))
|
||||
{
|
||||
file->install = 2;
|
||||
uninstallCnt++;
|
||||
}
|
||||
else if (((file->isdir) == false) && (file->install == 1))
|
||||
{
|
||||
file->install = 2;
|
||||
uninstallCnt++;
|
||||
installCnt--;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2))
|
||||
{
|
||||
file->install = 0;
|
||||
uninstallCnt--;
|
||||
}
|
||||
|
||||
installCnt += 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 1)) {
|
||||
file->install = 0;
|
||||
|
||||
installCnt -= 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2)) {
|
||||
file->install = 1;
|
||||
|
||||
installCnt += 1;
|
||||
uninstallCnt -= 1;
|
||||
}
|
||||
selected++;
|
||||
|
||||
if (selected >= fileCnt)
|
||||
selected = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatFile *file = &fileList[selected];
|
||||
if (((file->isdir) == false) && (file->install == 0))
|
||||
{
|
||||
file->install = 2;
|
||||
uninstallCnt++;
|
||||
}
|
||||
else if (((file->isdir) == false) && (file->install == 1))
|
||||
{
|
||||
file->install = 2;
|
||||
uninstallCnt++;
|
||||
installCnt--;
|
||||
}
|
||||
else if (((file->isdir) == false) && (file->install == 2))
|
||||
{
|
||||
file->install = 0;
|
||||
uninstallCnt -= 1;
|
||||
}
|
||||
|
||||
selected++;
|
||||
if (selected >= fileCnt)
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Minus Button - Leathl */
|
||||
if (buttons & WPAD_BUTTON_MINUS)
|
||||
{
|
||||
if(Wpad_TimeButton())
|
||||
{
|
||||
installCnt = 0;
|
||||
int i = 0;
|
||||
while( i < fileCnt)
|
||||
{
|
||||
fatFile *file = &fileList[i];
|
||||
if (((file->isdir) == false) & (file->install == 0)) {
|
||||
file->install = 2;
|
||||
|
||||
uninstallCnt += 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 1)) {
|
||||
file->install = 2;
|
||||
|
||||
uninstallCnt += 1;
|
||||
installCnt -= 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2)) {
|
||||
file->install = 0;
|
||||
|
||||
uninstallCnt -= 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fatFile *file = &fileList[selected];
|
||||
if (((file->isdir) == false) & (file->install == 0)) {
|
||||
file->install = 2;
|
||||
|
||||
uninstallCnt += 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 1)) {
|
||||
file->install = 2;
|
||||
|
||||
uninstallCnt += 1;
|
||||
installCnt -= 1;
|
||||
}
|
||||
else if (((file->isdir) == false) & (file->install == 2)) {
|
||||
file->install = 0;
|
||||
|
||||
uninstallCnt -= 1;
|
||||
}
|
||||
selected++;
|
||||
|
||||
if (selected >= fileCnt)
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 1 Button - Leathl */
|
||||
if (buttons & WPAD_BUTTON_1)
|
||||
{
|
||||
fatFile *tmpFile = &fileList[selected];
|
||||
char *tmpCurPath = PeekCurrentDir ();
|
||||
if (tmpCurPath != NULL) {
|
||||
char *tmpCurPath = PeekCurrentDir();
|
||||
if (tmpCurPath != NULL)
|
||||
{
|
||||
int res = Menu_FileOperations(tmpFile, tmpCurPath);
|
||||
if (res != 0)
|
||||
goto getList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* A button */
|
||||
if (buttons & WPAD_BUTTON_A)
|
||||
else if (buttons & WPAD_BUTTON_A)
|
||||
{
|
||||
fatFile *tmpFile = &fileList[selected];
|
||||
char *tmpCurPath;
|
||||
if (tmpFile->isdir) // wiiNinja
|
||||
fatFile *tmpFile = &fileList[selected];
|
||||
char *tmpCurPath;
|
||||
if (tmpFile->isdir) // wiiNinja
|
||||
{
|
||||
if (strcmp (tmpFile->filename, "..") == 0)
|
||||
{
|
||||
if (strcmp (tmpFile->filename, "..") == 0)
|
||||
{
|
||||
selected = 0;
|
||||
start = 0;
|
||||
selected = 0;
|
||||
start = 0;
|
||||
|
||||
// Previous dir
|
||||
tmpCurPath = PopCurrentDir(&selected, &start);
|
||||
if (tmpCurPath != NULL)
|
||||
sprintf(tmpPath, "%s", tmpCurPath);
|
||||
// Previous dir
|
||||
tmpCurPath = PopCurrentDir(&selected, &start);
|
||||
if (tmpCurPath != NULL)
|
||||
sprintf(tmpPath, "%s", tmpCurPath);
|
||||
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
|
||||
goto getList;
|
||||
}
|
||||
else if (IsListFull () == true)
|
||||
{
|
||||
WaitPrompt ("Maximum number of directory levels is reached.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpCurPath = PeekCurrentDir ();
|
||||
if (tmpCurPath != NULL)
|
||||
{
|
||||
if(gDirLevel>1)
|
||||
sprintf(tmpPath, "%s/%s", tmpCurPath, tmpFile->filename);
|
||||
else
|
||||
sprintf(tmpPath, "%s%s", tmpCurPath, tmpFile->filename);
|
||||
}
|
||||
// wiiNinja: Need to PopCurrentDir
|
||||
PushCurrentDir (tmpPath, selected, start);
|
||||
selected = 0;
|
||||
start = 0;
|
||||
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
|
||||
goto getList;
|
||||
}
|
||||
goto getList;
|
||||
}
|
||||
else if (IsListFull() == true)
|
||||
{
|
||||
WaitPrompt ("Maximum number of directory levels is reached.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//If at least one WAD is marked, goto batch screen - Leathl
|
||||
if ((installCnt > 0) | (uninstallCnt > 0)) {
|
||||
char *thisCurPath = PeekCurrentDir ();
|
||||
if (thisCurPath != NULL) {
|
||||
int res = Menu_BatchProcessWads(fileList, fileCnt, thisCurPath, installCnt, uninstallCnt);
|
||||
tmpCurPath = PeekCurrentDir ();
|
||||
if (tmpCurPath != NULL)
|
||||
{
|
||||
if(gDirLevel > 1)
|
||||
sprintf(tmpPath, "%s/%s", tmpCurPath, tmpFile->filename);
|
||||
else
|
||||
sprintf(tmpPath, "%s%s", tmpCurPath, tmpFile->filename);
|
||||
}
|
||||
|
||||
// wiiNinja: Need to PopCurrentDir
|
||||
PushCurrentDir (tmpPath, selected, start);
|
||||
selected = 0;
|
||||
start = 0;
|
||||
|
||||
if (res == 1) {
|
||||
int counter;
|
||||
for (counter = 0; counter < fileCnt; counter++) {
|
||||
fatFile *temp = &fileList[counter];
|
||||
temp->install = 0;
|
||||
}
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
goto getList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//If at least one WAD is marked, goto batch screen - Leathl
|
||||
if ((installCnt > 0) || (uninstallCnt > 0))
|
||||
{
|
||||
char *thisCurPath = PeekCurrentDir ();
|
||||
if (thisCurPath != NULL)
|
||||
{
|
||||
int res = Menu_BatchProcessWads(fileList, fileCnt, thisCurPath, installCnt, uninstallCnt);
|
||||
|
||||
if (res == 1)
|
||||
{
|
||||
int counter;
|
||||
for (counter = 0; counter < fileCnt; counter++)
|
||||
{
|
||||
fatFile *temp = &fileList[counter];
|
||||
temp->install = 0;
|
||||
}
|
||||
|
||||
installCnt = 0;
|
||||
uninstallCnt = 0;
|
||||
}
|
||||
}
|
||||
//else use standard wadmanage menu - Leathl
|
||||
else {
|
||||
tmpCurPath = PeekCurrentDir ();
|
||||
if (tmpCurPath != NULL)
|
||||
Menu_WadManage(tmpFile, tmpCurPath);
|
||||
}
|
||||
}
|
||||
//else use standard wadmanage menu - Leathl
|
||||
else
|
||||
{
|
||||
tmpCurPath = PeekCurrentDir ();
|
||||
if (tmpCurPath != NULL)
|
||||
Menu_WadManage(tmpFile, tmpCurPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* B button */
|
||||
if (buttons & WPAD_BUTTON_B)
|
||||
else if (buttons & WPAD_BUTTON_B)
|
||||
{
|
||||
if(gDirLevel<=1)
|
||||
{
|
||||
if (gDirLevel <= 1)
|
||||
return;
|
||||
}
|
||||
|
||||
char *tmpCurPath;
|
||||
selected = 0;
|
||||
start = 0;
|
||||
|
||||
// Previous dir
|
||||
tmpCurPath = PopCurrentDir(&selected, &start);
|
||||
if (tmpCurPath != NULL)
|
||||
sprintf(tmpPath, "%s", tmpCurPath);
|
||||
|
||||
goto getList;
|
||||
//return;
|
||||
}
|
||||
|
||||
/** Scrolling **/
|
||||
@ -1204,7 +1196,7 @@ getList:
|
||||
|
||||
if (index >= ENTRIES_PER_PAGE)
|
||||
start += index - (ENTRIES_PER_PAGE - 1);
|
||||
if (index <= -1)
|
||||
else if (index < 0)
|
||||
start += index;
|
||||
}
|
||||
|
||||
@ -1212,7 +1204,7 @@ err:
|
||||
printf("\n");
|
||||
printf(" Press any button to continue...\n");
|
||||
|
||||
free (tmpPath);
|
||||
free(tmpPath);
|
||||
|
||||
/* Wait for button */
|
||||
WaitButtons();
|
||||
@ -1220,8 +1212,10 @@ err:
|
||||
void Menu_Loop(void)
|
||||
{
|
||||
u8 iosVersion;
|
||||
if(AHBPROT_DISABLED)
|
||||
if (AHBPROT_DISABLED)
|
||||
{
|
||||
IOSPATCH_Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Select IOS menu */
|
||||
@ -1230,6 +1224,7 @@ void Menu_Loop(void)
|
||||
|
||||
/* Retrieve IOS version */
|
||||
iosVersion = IOS_GetVersion();
|
||||
GetSysMenuRegion(&gMenuVersion, &gMenuRegion);
|
||||
|
||||
ndev = &ndevList[0];
|
||||
|
||||
|
383
source/nand.c
383
source/nand.c
@ -1,10 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ogcsys.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nand.h"
|
||||
#include "fileops.h"
|
||||
|
||||
#define BLOCK 2048
|
||||
|
||||
/* Buffer */
|
||||
static u32 inbuf[8] ATTRIBUTE_ALIGN(32);
|
||||
static bool gNandInitialized = false;
|
||||
|
||||
#if 0
|
||||
static void NANDFATify(char* ptr, const char* str)
|
||||
{
|
||||
char ctr;
|
||||
while ((ctr = *(str++)) != '\0')
|
||||
{
|
||||
const char* esc;
|
||||
switch (ctr)
|
||||
{
|
||||
case '"':
|
||||
esc = "&qt;";
|
||||
break;
|
||||
case '*':
|
||||
esc = "&st;";
|
||||
break;
|
||||
case ':':
|
||||
esc = "&cl;";
|
||||
break;
|
||||
case '<':
|
||||
esc = "<";
|
||||
break;
|
||||
case '>':
|
||||
esc = ">";
|
||||
break;
|
||||
case '?':
|
||||
esc = "&qm;";
|
||||
break;
|
||||
case '|':
|
||||
esc = "&vb;";
|
||||
break;
|
||||
default:
|
||||
*(ptr++) = ctr;
|
||||
continue;
|
||||
}
|
||||
strcpy(ptr, esc);
|
||||
ptr += 4;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
s32 Nand_Mount(nandDevice *dev)
|
||||
@ -83,4 +131,337 @@ s32 Nand_Disable(void)
|
||||
IOS_Close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
bool NANDInitialize()
|
||||
{
|
||||
if(!gNandInitialized)
|
||||
{
|
||||
if (ISFS_Initialize() == ISFS_OK)
|
||||
gNandInitialized = true;
|
||||
}
|
||||
|
||||
return gNandInitialized;
|
||||
}
|
||||
|
||||
u8* NANDReadFromFile(const char* path, u32 offset, u32 length, u32* size)
|
||||
{
|
||||
*size = ISFS_EINVAL;
|
||||
|
||||
if (NANDInitialize())
|
||||
{
|
||||
s32 fd = IOS_Open(path, 1);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
*size = fd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!length)
|
||||
length = IOS_Seek(fd, 0, SEEK_END);
|
||||
|
||||
u8* data = (u8*)memalign(0x40, length);
|
||||
if (!data)
|
||||
{
|
||||
*size = 0;
|
||||
IOS_Close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*size = IOS_Seek(fd, offset, SEEK_SET);
|
||||
if (*size < 0)
|
||||
{
|
||||
IOS_Close(fd);
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*size = IOS_Read(fd, data, length);
|
||||
IOS_Close(fd);
|
||||
if (*size != length)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8* NANDLoadFile(const char* path, u32* size)
|
||||
{
|
||||
return NANDReadFromFile(path, 0, 0, size);
|
||||
}
|
||||
|
||||
s32 NANDWriteFileSafe(const char* path, u8* data, u32 size)
|
||||
{
|
||||
NANDInitialize();
|
||||
|
||||
char* tmpPath = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
u32 i;
|
||||
|
||||
for (i = strlen(path); i > 0; --i)
|
||||
{
|
||||
if (path[i] == '/')
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(tmpPath, "/tmp%s", path + i);
|
||||
|
||||
s32 ret = ISFS_CreateFile(tmpPath, 0, 3, 3, 3);
|
||||
if (ret == -105)
|
||||
{
|
||||
ISFS_Delete(tmpPath);
|
||||
ret = ISFS_CreateFile(tmpPath, 0, 3, 3, 3);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
s32 fd = IOS_Open(tmpPath, 2);
|
||||
if (fd < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return fd;
|
||||
}
|
||||
|
||||
ret = IOS_Write(fd, data, size);
|
||||
|
||||
|
||||
IOS_Close(fd);
|
||||
if (ret != size)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret - 3;
|
||||
}
|
||||
|
||||
if (strcmp(tmpPath, path))
|
||||
ret = ISFS_Rename(tmpPath, path);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 NANDBackUpFile(const char* src, const char* dst, u32* size)
|
||||
{
|
||||
NANDInitialize();
|
||||
u8* buffer = NANDLoadFile(src, size);
|
||||
if (!buffer)
|
||||
return *size;
|
||||
|
||||
s32 ret = NANDWriteFileSafe(dst, buffer, *size);
|
||||
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 NANDGetFileSize(const char* path, u32* size)
|
||||
{
|
||||
NANDInitialize();
|
||||
s32 fd = IOS_Open(path, 1);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
*size = 0;
|
||||
return fd;
|
||||
}
|
||||
|
||||
*size = IOS_Seek(fd, 0, SEEK_END);
|
||||
return IOS_Close(fd);
|
||||
}
|
||||
|
||||
s32 NANDDeleteFile(const char* path)
|
||||
{
|
||||
NANDInitialize();
|
||||
return ISFS_Delete(path);
|
||||
}
|
||||
|
||||
#if 0
|
||||
s32 NANDGetNameList(const char* src, NameList** entries, s32* count)
|
||||
{
|
||||
*count = 0;
|
||||
u32 numEntries = 0;
|
||||
char currentEntry[ISFS_MAXPATH];
|
||||
char entryPath[ISFS_MAXPATH + 1];
|
||||
|
||||
s32 ret = ISFS_ReadDir(src, NULL, &numEntries);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
char* names = (char*)memalign(0x40, ISFS_MAXPATH * numEntries);
|
||||
|
||||
if (!names)
|
||||
return ISFS_ENOMEM;
|
||||
|
||||
ret = ISFS_ReadDir(src, names, &numEntries);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(names);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*count = numEntries;
|
||||
|
||||
free(*entries);
|
||||
*entries = (NameList*)memalign(0x20, sizeof(NameList) * numEntries);
|
||||
if (!*entries)
|
||||
{
|
||||
free(names);
|
||||
return ISFS_ENOMEM;
|
||||
}
|
||||
|
||||
s32 i, j, k;
|
||||
u32 dummy;
|
||||
for (i = 0, k = 0; i < numEntries; i++)
|
||||
{
|
||||
for (j = 0; names[k] != 0; j++, k++)
|
||||
currentEntry[j] = names[k];
|
||||
|
||||
currentEntry[j] = 0;
|
||||
k++;
|
||||
|
||||
strcpy((*entries)[i].name, currentEntry);
|
||||
|
||||
if (src[strlen(src) - 1] == '/')
|
||||
snprintf(entryPath, sizeof(entryPath), "%s%s", src, currentEntry);
|
||||
else
|
||||
snprintf(entryPath, sizeof(entryPath), "%s/%s", src, currentEntry);
|
||||
|
||||
ret = ISFS_ReadDir(entryPath, NULL, &dummy);
|
||||
(*entries)[i].type = ret < 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
free(names);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 NANDDumpFile(const char* src, const char* dst)
|
||||
{
|
||||
s32 fd = ISFS_Open(src, ISFS_OPEN_READ);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
fstats* status = (fstats*)memalign(32, sizeof(fstats));
|
||||
if (status == NULL)
|
||||
return ISFS_ENOMEM;
|
||||
|
||||
s32 ret = ISFS_GetFileStats(fd, status);
|
||||
if (ret < 0)
|
||||
{
|
||||
ISFS_Close(fd);
|
||||
free(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FSOPDeleteFile(dst);
|
||||
|
||||
FILE* file = fopen(dst, "wb");
|
||||
|
||||
if (!file)
|
||||
{
|
||||
ISFS_Close(fd);
|
||||
free(status);
|
||||
return ISFS_EINVAL;
|
||||
}
|
||||
|
||||
u8* buffer = (u8*)memalign(32, BLOCK);
|
||||
if (!buffer)
|
||||
{
|
||||
ISFS_Close(fd);
|
||||
free(status);
|
||||
return ISFS_ENOMEM;
|
||||
}
|
||||
|
||||
u32 toRead = status->file_length;
|
||||
while (toRead > 0)
|
||||
{
|
||||
u32 size = toRead < BLOCK ? toRead : BLOCK;
|
||||
|
||||
ret = ISFS_Read(fd, buffer, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
ISFS_Close(fd);
|
||||
fclose(file);
|
||||
free(status);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fwrite(buffer, 1, size, file);
|
||||
if (ret < 0)
|
||||
{
|
||||
ISFS_Close(fd);
|
||||
fclose(file);
|
||||
free(status);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
toRead -= size;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
ISFS_Close(fd);
|
||||
free(status);
|
||||
free(buffer);
|
||||
|
||||
return ISFS_OK;
|
||||
}
|
||||
|
||||
s32 NANDDumpFolder(const char* src, const char* dst)
|
||||
{
|
||||
NameList* names = NULL;
|
||||
s32 count = 0;
|
||||
s32 i;
|
||||
|
||||
char nSrc[ISFS_MAXPATH + 1];
|
||||
char nDst[1024];
|
||||
char tDst[1024];
|
||||
|
||||
NANDGetNameList(src, &names, &count);
|
||||
FSOPMakeFolder(dst);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
if (src[strlen(src) - 1] == '/')
|
||||
snprintf(nSrc, sizeof(nSrc), "%s%s", src, names[i].name);
|
||||
else
|
||||
snprintf(nSrc, sizeof(nSrc), "%s/%s", src, names[i].name);
|
||||
|
||||
if (!names[i].type)
|
||||
{
|
||||
NANDFATify(tDst, nSrc);
|
||||
snprintf(nDst, sizeof(nDst), "%s%s", dst, tDst);
|
||||
NANDDumpFile(nSrc, nDst);
|
||||
}
|
||||
else
|
||||
{
|
||||
NANDFATify(tDst, nSrc);
|
||||
snprintf(nDst, sizeof(nDst), "%s%s", dst, tDst);
|
||||
FSOPMakeFolder(nDst);
|
||||
NANDDumpFolder(nSrc, dst);
|
||||
}
|
||||
}
|
||||
|
||||
free(names);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -12,7 +12,13 @@ typedef struct {
|
||||
/* Un/mount command */
|
||||
u32 mountCmd;
|
||||
u32 umountCmd;
|
||||
} nandDevice;
|
||||
} nandDevice;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[ISFS_MAXPATH];
|
||||
int type;
|
||||
} NameList;
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
@ -20,5 +26,18 @@ s32 Nand_Mount(nandDevice *);
|
||||
s32 Nand_Unmount(nandDevice *);
|
||||
s32 Nand_Enable(nandDevice *);
|
||||
s32 Nand_Disable(void);
|
||||
bool NANDInitialize();
|
||||
u8* NANDReadFromFile(const char* path, u32 offset, u32 length, u32* size);
|
||||
u8* NANDLoadFile(const char* path, u32* size);
|
||||
s32 NANDWriteFileSafe(const char* path, u8* data, u32 size);
|
||||
s32 NANDBackUpFile(const char* src, const char* dst, u32* size);
|
||||
s32 NANDGetFileSize(const char* path, u32* size);
|
||||
s32 NANDDeleteFile(const char* path);
|
||||
|
||||
#if 0
|
||||
s32 NANDGetNameList(const char* src, NameList** entries, s32* count);
|
||||
s32 NANDDumpFile(const char* src, const char* dst);
|
||||
s32 NANDDumpFolder(const char* src, const char* dst);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -175,3 +175,17 @@ void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf) {
|
||||
SHA1Update(&ctx, ptr, size);
|
||||
SHA1Final(outbuf, &ctx);
|
||||
}
|
||||
|
||||
int CompareHash(unsigned char* first, unsigned int firstSize, unsigned char* second, unsigned int secondSize)
|
||||
{
|
||||
unsigned int HashA[5] = { 0, 0, 0, 0, 0, };
|
||||
unsigned int HashB[5] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, };
|
||||
|
||||
SHA1(first, firstSize, (unsigned char*)HashA);
|
||||
SHA1(second, secondSize, (unsigned char*)HashB);
|
||||
|
||||
//printf("Hash 1: %.8X, %.8X, %.8X, %.8X, %.8X", HashA[0], HashA[1], HashA[2], HashA[3], HashA[4]);
|
||||
//printf("Hash 2: %.8X, %.8X, %.8X, %.8X, %.8X", HashB[0], HashB[1], HashB[2], HashB[3], HashB[4]);
|
||||
|
||||
return memcmp(HashA, HashB, sizeof(HashA));
|
||||
}
|
||||
|
@ -2,5 +2,6 @@
|
||||
#define _SHA1_H_
|
||||
|
||||
void SHA1(unsigned char *, unsigned int, unsigned char *);
|
||||
int CompareHash(unsigned char* first, unsigned int firstSize, unsigned char* second, unsigned int secondSize);
|
||||
|
||||
#endif
|
||||
|
@ -166,6 +166,8 @@ int main(int argc, char **argv)
|
||||
/* Set video mode */
|
||||
Video_SetMode();
|
||||
|
||||
FatMount();
|
||||
|
||||
/* Initialize console */
|
||||
Gui_InitConsole();
|
||||
|
||||
@ -193,6 +195,8 @@ int main(int argc, char **argv)
|
||||
/* Menu loop */
|
||||
Menu_Loop();
|
||||
|
||||
FatUnmount();
|
||||
|
||||
/* Restart Wii */
|
||||
Restart_Wait();
|
||||
|
||||
@ -200,30 +204,27 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
|
||||
int ReadConfigFile (char *configFilePath)
|
||||
int ReadConfigFile(char* configFilePath)
|
||||
{
|
||||
int retval = 0;
|
||||
FILE *fptr;
|
||||
char *tmpStr = malloc (MAX_FILE_PATH_LEN);
|
||||
char tmpOutStr [40], path[128];
|
||||
int i;
|
||||
int retval = 0;
|
||||
FILE* fptr;
|
||||
char* tmpStr = malloc(MAX_FILE_PATH_LEN);
|
||||
char tmpOutStr[40], path[128];
|
||||
s32 i;
|
||||
s32 ret = -1;
|
||||
bool found = false;
|
||||
|
||||
if (tmpStr == NULL)
|
||||
return (-1);
|
||||
|
||||
fatDevice *fdev = &fdevList[0];
|
||||
int ret = Fat_Mount(fdev);
|
||||
snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
|
||||
|
||||
if (ret < 0)
|
||||
// Just check if at least one device is available
|
||||
for (i = 0; i < FatGetDeviceCount(); i++)
|
||||
{
|
||||
fdev = &fdevList[2];
|
||||
ret = Fat_Mount(fdev);
|
||||
snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
|
||||
//snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
|
||||
snprintf(path, sizeof(path), "%s%s", FatGetDevicePrefix(i), configFilePath);
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
if (!found)
|
||||
{
|
||||
printf(" ERROR! (ret = %d)\n", ret);
|
||||
// goto err;
|
||||
@ -281,7 +282,8 @@ int ReadConfigFile (char *configFilePath)
|
||||
GetStringParam (tmpOutStr, tmpStr, MAX_FAT_DEVICE_LENGTH);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (strncmp (fdevList[i].mount, tmpOutStr, 4) == 0)
|
||||
//if (strncmp (fdevList[i].mount, tmpOutStr, 4) == 0)
|
||||
if (strncmp(FatGetDevicePrefix(i), tmpOutStr, 4) == 0)
|
||||
{
|
||||
gConfig.fatDeviceIndex = i;
|
||||
}
|
||||
@ -313,11 +315,11 @@ int ReadConfigFile (char *configFilePath)
|
||||
//printf ("Config file is not found\n"); // This is for testing only
|
||||
//WaitButtons();
|
||||
}
|
||||
Fat_Unmount(fdev);
|
||||
//Fat_Unmount(fdev);
|
||||
}
|
||||
|
||||
// Free memory
|
||||
free (tmpStr);
|
||||
free(tmpStr);
|
||||
|
||||
return (retval);
|
||||
} // ReadConfig
|
||||
|
620
source/wad.c
620
source/wad.c
@ -3,6 +3,7 @@
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/pad.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sys.h"
|
||||
#include "title.h"
|
||||
@ -10,6 +11,9 @@
|
||||
#include "video.h"
|
||||
#include "wad.h"
|
||||
#include "wpad.h"
|
||||
#include "nand.h"
|
||||
#include "fileops.h"
|
||||
#include "sha1.h"
|
||||
|
||||
// Turn upper and lower into a full title ID
|
||||
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
|
||||
@ -18,32 +22,34 @@
|
||||
// Turn upper and lower into a full title ID
|
||||
#define TITLE_LOWER(x) ((u32)(x))
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int region;
|
||||
|
||||
} SMRegion;
|
||||
|
||||
SMRegion regionlist[] = {
|
||||
{33, 'X'},
|
||||
{128, 'J'}, {97, 'E'}, {130, 'P'},
|
||||
{162, 'P'},
|
||||
{192, 'J'}, {193, 'E'}, {194, 'P'},
|
||||
{224, 'J'}, {225, 'E'}, {226, 'P'},
|
||||
{256, 'J'}, {257, 'E'}, {258, 'P'},
|
||||
{288, 'J'}, {289, 'E'}, {290, 'P'},
|
||||
{352, 'J'}, {353, 'E'}, {354, 'P'}, {326, 'K'},
|
||||
{384, 'J'}, {385, 'E'}, {386, 'P'},
|
||||
{390, 'K'},
|
||||
{416, 'J'}, {417, 'E'}, {418, 'P'},
|
||||
{448, 'J'}, {449, 'E'}, {450, 'P'}, {454, 'K'},
|
||||
{480, 'J'}, {481, 'E'}, {482, 'P'}, {486, 'K'},
|
||||
{512, 'E'}, {513, 'E'}, {514, 'P'}, {518, 'K'},
|
||||
const char RegionLookupList[16] =
|
||||
{
|
||||
'J', 'E', 'P', 0, 0, 0, 'K', 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
#define NB_SM (sizeof(regionlist) / sizeof(SMRegion))
|
||||
const u16 versionList[] =
|
||||
{
|
||||
// J E P K
|
||||
|
||||
64, 33, 66, // 1.0
|
||||
128, 97, 130, // 2.0
|
||||
162, // 2.1
|
||||
192, 193, 194, // 2.2
|
||||
224, 225, 226, // 3.0
|
||||
256, 257, 258, // 3.1
|
||||
288, 289, 290, // 3.2
|
||||
352, 353, 354, 326, // 3.3
|
||||
384, 385, 386, // 3.4
|
||||
390, // 3.5
|
||||
416, 417, 418, // 4.0
|
||||
448, 449, 450, 454, // 4.1
|
||||
480, 481, 482, 486, // 4.2
|
||||
512, 513, 514, 518, // 4.3
|
||||
};
|
||||
|
||||
u32 WaitButtons(void);
|
||||
static u32 gPriiloaderSize = 0;
|
||||
static bool gForcedInstall = false;
|
||||
|
||||
u32 be32(const u8 *p)
|
||||
{
|
||||
@ -125,33 +131,280 @@ u64 get_title_ios(u64 title) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_sm_region_basic()
|
||||
s32 GetSysMenuRegion(u16* version, char* region)
|
||||
{
|
||||
u32 tmd_size;
|
||||
|
||||
u64 title = TITLE_ID(1, 2);
|
||||
static u8 tmd_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
int ret = ES_GetStoredTMDSize(title, &tmd_size);
|
||||
|
||||
// Some of this code adapted from bushing's title_lister.c
|
||||
signed_blob *s_tmd = (signed_blob *)tmd_buf;
|
||||
ret = ES_GetStoredTMD(title, s_tmd, tmd_size);
|
||||
if (ret < 0){
|
||||
//printf("Error! ES_GetStoredTMD: %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
tmd *t = SIGNATURE_PAYLOAD(s_tmd);
|
||||
ret = t->title_version;
|
||||
int i = 0;
|
||||
while( i <= NB_SM)
|
||||
{
|
||||
if( regionlist[i].version == ret) return regionlist[i].region;
|
||||
i++;
|
||||
}
|
||||
u16 v = 0;
|
||||
s32 ret = Title_GetVersion(0x100000002LL, &v);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (version)
|
||||
*version = v;
|
||||
|
||||
if (region)
|
||||
*region = RegionLookupList[(v & 0x0F)];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* GetSysMenuRegionString(const char* region)
|
||||
{
|
||||
switch (*region)
|
||||
{
|
||||
case 'J': return "Japan (NTSC-J)";
|
||||
case 'E': return "USA (NTSC-U/C)";
|
||||
case 'P': return "Europe (PAL)";
|
||||
case 'K': return "Korea (NTSC-K)";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static char* GetTitleExec(u64 tId, bool tweaked)
|
||||
{
|
||||
u32 size;
|
||||
const u8 buffer[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
s32 ret = ES_GetStoredTMDSize(0x100000002, &size);
|
||||
signed_blob* tmdRaw = (signed_blob*)buffer;
|
||||
|
||||
ret = ES_GetStoredTMD(0x100000002, tmdRaw, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Error! ES_GetStoredTMDSize: Failed! (Error: %d)\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmd* smTMD = SIGNATURE_PAYLOAD(tmdRaw);
|
||||
|
||||
char* path = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
if(tweaked)
|
||||
sprintf(path, "/title/%08x/%08x/content/1%.7x.app", TITLE_UPPER(tId), TITLE_LOWER(tId), smTMD->contents[smTMD->boot_index].cid);
|
||||
else
|
||||
sprintf(path, "/title/%08x/%08x/content/%.8x.app", TITLE_UPPER(tId), TITLE_LOWER(tId), smTMD->contents[smTMD->boot_index].cid);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static inline bool IsPriiloaderInstalled()
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, true);
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
|
||||
u32 size = 0;
|
||||
NANDGetFileSize(path, &size);
|
||||
free(path);
|
||||
|
||||
if (size > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool BackUpPriiloader()
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, false);
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile(path, "/tmp/priiload.app", &size);
|
||||
free(path);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = NANDGetFileSize("/tmp/priiload.app", &gPriiloaderSize);
|
||||
|
||||
return (gPriiloaderSize == size);
|
||||
}
|
||||
|
||||
static bool MoveMenu(bool restore)
|
||||
{
|
||||
char* srcPath = GetTitleExec(0x100000002LL, restore);
|
||||
if (!srcPath)
|
||||
return false;
|
||||
|
||||
char* dstPath = GetTitleExec(0x100000002LL, !restore);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile(srcPath, dstPath, &size);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 checkSize = 0;
|
||||
ret = NANDGetFileSize(dstPath, &checkSize);
|
||||
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
|
||||
return (checkSize == size);
|
||||
}
|
||||
|
||||
static bool RestorePriiloader()
|
||||
{
|
||||
char* dstPath = GetTitleExec(0x100000002LL, false);
|
||||
if (!dstPath)
|
||||
return false;
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile("/tmp/priiload.app", dstPath, &size);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(dstPath);
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 checkSize = 0;
|
||||
ret = NANDGetFileSize(dstPath, &checkSize);
|
||||
|
||||
free(dstPath);
|
||||
|
||||
return (checkSize == size && checkSize == gPriiloaderSize);
|
||||
}
|
||||
|
||||
static void PrintCleanupResult(s32 result)
|
||||
{
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case -102:
|
||||
{
|
||||
printf(" Acces denied.\n");
|
||||
} break;
|
||||
case -106:
|
||||
{
|
||||
printf(" Not found.\n");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
printf(" Error: %d\n", result);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" OK!\n");
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
static void CleanupPriiloaderLeftOvers(bool retain)
|
||||
{
|
||||
if (!retain)
|
||||
{
|
||||
printf("\n\t\tCleanup Priiloader leftover files...\n");
|
||||
printf("\r\t\t>> Password file...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/password.txt"));
|
||||
printf("\r\t\t>> Settings file...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/loader.ini"));
|
||||
printf("\r\t\t>> Ticket...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/ticket"));
|
||||
printf("\r\t\t>> File: main.nfo...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/main.nfo"));
|
||||
printf("\r\t\t>> File: main.bin...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/main.bin"));
|
||||
}
|
||||
|
||||
printf("\n\t\tRemoving Priiloader hacks...\n");
|
||||
|
||||
printf("\r\t\t>> File: hacks_s.ini...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/hacks_s.ini"));
|
||||
printf("\r\t\t>> File: hacks.ini...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/hacks.ini"));
|
||||
printf("\r\t\t>> File: hacksh_s.ini...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/hacksh_s.ini"));
|
||||
printf("\r\t\t>> File: hackshas.ini...");
|
||||
PrintCleanupResult(NANDDeleteFile("/title/00000001/00000002/data/hackshas.ini"));
|
||||
|
||||
if (retain)
|
||||
{
|
||||
printf("\n\t\tPriiloader hacks will be reset!\n");
|
||||
printf("\t\tRemember to set them again.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static bool CompareHashes(bool priiloader)
|
||||
{
|
||||
char* dstPath = NULL;
|
||||
char* srcPath = GetTitleExec(0x100000002LL, false);
|
||||
|
||||
if (!srcPath)
|
||||
return false;
|
||||
|
||||
if (priiloader)
|
||||
{
|
||||
dstPath = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy(dstPath, "/tmp/priiload.app");
|
||||
}
|
||||
else
|
||||
{
|
||||
dstPath = GetTitleExec(0x100000002LL, true);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
u32 sizeA = 0;
|
||||
u32 sizeB = 0;
|
||||
u8* dataA = NANDLoadFile(srcPath, &sizeA);
|
||||
if (!dataA)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
u8* dataB = NANDLoadFile(dstPath, &sizeB);
|
||||
if (!dataA)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
free(dataA);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = !CompareHash(dataA, sizeA, dataB, sizeB);
|
||||
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
free(dataA);
|
||||
free(dataB);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 'WAD Header' structure */
|
||||
typedef struct {
|
||||
/* Header length */
|
||||
@ -174,45 +427,6 @@ typedef struct {
|
||||
/* Variables */
|
||||
static u8 wadBuffer[BLOCK_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
|
||||
s32 __Wad_ReadFile(FILE *fp, void *outbuf, u32 offset, u32 len)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
/* Seek to offset */
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
|
||||
/* Read data */
|
||||
ret = fread(outbuf, len, 1, fp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 __Wad_ReadAlloc(FILE *fp, void **outbuf, u32 offset, u32 len)
|
||||
{
|
||||
void *buffer = NULL;
|
||||
s32 ret;
|
||||
|
||||
/* Allocate memory */
|
||||
buffer = memalign(32, len);
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
/* Read file */
|
||||
ret = __Wad_ReadFile(fp, buffer, offset, len);
|
||||
if (ret < 0) {
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set pointer */
|
||||
*outbuf = buffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 __Wad_GetTitleID(FILE *fp, wadHeader *header, u64 *tid)
|
||||
{
|
||||
signed_blob *p_tik = NULL;
|
||||
@ -227,8 +441,8 @@ s32 __Wad_GetTitleID(FILE *fp, wadHeader *header, u64 *tid)
|
||||
offset += round_up(header->crl_len, 64);
|
||||
|
||||
/* Read ticket */
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&p_tik, offset, header->tik_len);
|
||||
if (ret < 0)
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&p_tik, offset, header->tik_len);
|
||||
if (ret != 1)
|
||||
goto out;
|
||||
|
||||
/* Ticket data */
|
||||
@ -273,15 +487,17 @@ s32 Wad_Install(FILE *fp)
|
||||
u32 cnt, offset = 0;
|
||||
int ret;
|
||||
u64 tid;
|
||||
bool retainPriiloader = false;
|
||||
bool cleanupPriiloader = false;
|
||||
|
||||
printf("\t\t>> Reading WAD data...");
|
||||
fflush(stdout);
|
||||
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&header, offset, sizeof(wadHeader));
|
||||
if (ret >= 0)
|
||||
offset += round_up(header->header_len, 64);
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&header, offset, sizeof(wadHeader));
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
else
|
||||
goto err;
|
||||
offset += round_up(header->header_len, 64);
|
||||
|
||||
//Don't try to install boot2
|
||||
__Wad_GetTitleID(fp, header, &tid);
|
||||
@ -294,31 +510,31 @@ s32 Wad_Install(FILE *fp)
|
||||
}
|
||||
|
||||
/* WAD certificates */
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&p_certs, offset, header->certs_len);
|
||||
if (ret >= 0)
|
||||
offset += round_up(header->certs_len, 64);
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&p_certs, offset, header->certs_len);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
else
|
||||
goto err;
|
||||
|
||||
offset += round_up(header->certs_len, 64);
|
||||
|
||||
/* WAD crl */
|
||||
if (header->crl_len) {
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&p_crl, offset, header->crl_len);
|
||||
if (ret < 0)
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&p_crl, offset, header->crl_len);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
else
|
||||
offset += round_up(header->crl_len, 64);
|
||||
}
|
||||
|
||||
/* WAD ticket */
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&p_tik, offset, header->tik_len);
|
||||
if (ret < 0)
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&p_tik, offset, header->tik_len);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
else
|
||||
offset += round_up(header->tik_len, 64);
|
||||
|
||||
/* WAD TMD */
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&p_tmd, offset, header->tmd_len);
|
||||
if (ret < 0)
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&p_tmd, offset, header->tmd_len);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
else
|
||||
offset += round_up(header->tmd_len, 64);
|
||||
@ -338,7 +554,7 @@ s32 Wad_Install(FILE *fp)
|
||||
|
||||
if(get_title_ios(TITLE_ID(1, 2)) == tid)
|
||||
{
|
||||
if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
|
||||
if (( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001))
|
||||
{
|
||||
printf("\n I won't install a stub System Menu IOS\n");
|
||||
ret = -999;
|
||||
@ -348,7 +564,7 @@ s32 Wad_Install(FILE *fp)
|
||||
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'E')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'P')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'J')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'K')))
|
||||
{
|
||||
if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
|
||||
if ((tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001))
|
||||
{
|
||||
printf("\n I won't install a stub EULA IOS\n");
|
||||
ret = -999;
|
||||
@ -358,7 +574,7 @@ s32 Wad_Install(FILE *fp)
|
||||
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'E')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'P')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'J')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'K')))
|
||||
{
|
||||
if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
|
||||
if ((tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001))
|
||||
{
|
||||
printf("\n I won't install a stub rgsel IOS\n");
|
||||
ret = -999;
|
||||
@ -385,30 +601,36 @@ s32 Wad_Install(FILE *fp)
|
||||
|
||||
if (tid == TITLE_ID(1, 2))
|
||||
{
|
||||
if (skipRegionSafetyCheck) goto skipChecks;
|
||||
char region = 0;
|
||||
u16 version = 0;
|
||||
|
||||
if(get_sm_region_basic() == 0)
|
||||
if (skipRegionSafetyCheck || gForcedInstall)
|
||||
goto skipChecks;
|
||||
|
||||
GetSysMenuRegion(&version, ®ion);
|
||||
if(region == 0)
|
||||
{
|
||||
printf("\n Can't get the SM region\n Please check the site for updates\n");
|
||||
printf("\n Unkown SM region\n Please check the site for updates\n");
|
||||
ret = -999;
|
||||
goto err;
|
||||
}
|
||||
|
||||
int i, ret = -1;
|
||||
for(i = 0; i <= NB_SM; i++)
|
||||
for(i = 0; i < sizeof(versionList); i++)
|
||||
{
|
||||
if( regionlist[i].version == tmd_data->title_version)
|
||||
if(versionList[i] == tmd_data->title_version)
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret -1)
|
||||
if(ret != 1)
|
||||
{
|
||||
printf("\n Can't get the SM region\n Please check the site for updates\n");
|
||||
printf("\n Unknown SM region\n Please check the site for updates\n");
|
||||
ret = -999;
|
||||
goto err;
|
||||
}
|
||||
if(get_sm_region_basic() != regionlist[i].region)
|
||||
if(region != RegionLookupList[(tmd_data->title_version & 0x0F)])
|
||||
{
|
||||
printf("\n I won't install the wrong regions SM\n");
|
||||
ret = -999;
|
||||
@ -424,8 +646,57 @@ skipChecks:
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gForcedInstall && IsPriiloaderInstalled())
|
||||
{
|
||||
cleanupPriiloader = true;
|
||||
printf("\n Priiloader is installed next to the system menu.\n\n");
|
||||
printf(" Press A to retain Priiloader or B to remove.");
|
||||
|
||||
u32 buttons = WaitButtons();
|
||||
|
||||
if ((buttons & WPAD_BUTTON_A))
|
||||
{
|
||||
retainPriiloader = (BackUpPriiloader() && CompareHashes(true));
|
||||
if (retainPriiloader)
|
||||
{
|
||||
Con_ClearLine();
|
||||
printf("\r[+] Priiloader will be retained.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_ClearLine();
|
||||
printf("\r Couldn't backup Priiloader.\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("\n Press A to continue or B to skip");
|
||||
|
||||
u32 buttons = WaitButtons();
|
||||
|
||||
if (!(buttons & WPAD_BUTTON_A))
|
||||
{
|
||||
ret = -990;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!retainPriiloader)
|
||||
{
|
||||
Con_ClearLine();
|
||||
printf("\r[+] Priiloader will be removed.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gForcedInstall)
|
||||
{
|
||||
gForcedInstall = false;
|
||||
cleanupPriiloader = true;
|
||||
}
|
||||
|
||||
/* Fix ticket */
|
||||
__Wad_FixTicket(p_tik);
|
||||
|
||||
@ -479,8 +750,8 @@ skipChecks:
|
||||
size = BLOCK_SIZE;
|
||||
|
||||
/* Read data */
|
||||
ret = __Wad_ReadFile(fp, &wadBuffer, offset, size);
|
||||
if (ret < 0)
|
||||
ret = FSOPReadOpenFile(fp, &wadBuffer, offset, size);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
|
||||
/* Install data */
|
||||
@ -506,13 +777,106 @@ skipChecks:
|
||||
|
||||
/* Finish title install */
|
||||
ret = ES_AddTitleFinish();
|
||||
if (ret >= 0) {
|
||||
if (ret >= 0)
|
||||
{
|
||||
printf(" OK!\n");
|
||||
|
||||
if (retainPriiloader)
|
||||
{
|
||||
printf("\r\t\t>> Moving System Menu...");
|
||||
if (MoveMenu(false))
|
||||
{
|
||||
printf(" OK!\n");
|
||||
|
||||
printf("\r\t\t>> Check System Menu executable hashes...");
|
||||
|
||||
s32 restoreMenu = 0;
|
||||
|
||||
if (CompareHashes(false))
|
||||
{
|
||||
printf(" OK!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Failed!\n");
|
||||
restoreMenu = 1;
|
||||
}
|
||||
|
||||
printf("\r\t\t>> Restore Priiloader...");
|
||||
if (!restoreMenu && RestorePriiloader())
|
||||
{
|
||||
printf(" OK!\n");
|
||||
printf("\r\t\t>> Check Priiloader executable hashes...");
|
||||
if (CompareHashes(true))
|
||||
{
|
||||
printf(" OK!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Failed!\n");
|
||||
restoreMenu = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Failed!\n");
|
||||
restoreMenu = 2;
|
||||
}
|
||||
|
||||
if (restoreMenu)
|
||||
{
|
||||
printf("\r\t\t>> Restore System Menu...");
|
||||
bool restored = true;
|
||||
switch (restoreMenu)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
restored = (MoveMenu(true) && CompareHashes(false));
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (restored)
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, true);
|
||||
NANDDeleteFile(path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (restored)
|
||||
{
|
||||
printf(" OK!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Failed!\n");
|
||||
printf("\n\t\t>> Reinstalling System Menu...\n\n");
|
||||
sleep(3);
|
||||
printf("\t\t>> Priiloader will be removed!\n\n");
|
||||
|
||||
gForcedInstall = true;
|
||||
cleanupPriiloader = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" Failed!\n");
|
||||
printf("\n\t\t>> Priiloader will be removed!\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanupPriiloader)
|
||||
{
|
||||
CleanupPriiloaderLeftOvers(retainPriiloader);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
err:
|
||||
printf(" ERROR! (ret = %d)\n", ret);
|
||||
printf("\n ERROR! (ret = %d)\n", ret);
|
||||
|
||||
/* Cancel install */
|
||||
ES_AddTitleCancel();
|
||||
@ -525,6 +889,9 @@ out:
|
||||
free(p_tik);
|
||||
free(p_tmd);
|
||||
|
||||
if (gForcedInstall)
|
||||
return Wad_Install(fp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -541,8 +908,9 @@ s32 Wad_Uninstall(FILE *fp)
|
||||
fflush(stdout);
|
||||
|
||||
/* WAD header */
|
||||
ret = __Wad_ReadAlloc(fp, (void *)&header, 0, sizeof(wadHeader));
|
||||
if (ret < 0) {
|
||||
ret = FSOPReadOpenFileA(fp, (void*)&header, 0, sizeof(wadHeader));
|
||||
if (ret != 1)
|
||||
{
|
||||
printf(" ERROR! (ret = %d)\n", ret);
|
||||
goto out;
|
||||
}
|
||||
@ -592,32 +960,36 @@ s32 Wad_Uninstall(FILE *fp)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
char region = 0;
|
||||
GetSysMenuRegion(NULL, ®ion);
|
||||
|
||||
if((tid == TITLE_ID(0x10008, 0x48414B00 | 'E') || tid == TITLE_ID(0x10008, 0x48414B00 | 'P') || tid == TITLE_ID(0x10008, 0x48414B00 | 'J') || tid == TITLE_ID(0x10008, 0x48414B00 | 'K')
|
||||
|| (tid == TITLE_ID(0x10008, 0x48414C00 | 'E') || tid == TITLE_ID(0x10008, 0x48414C00 | 'P') || tid == TITLE_ID(0x10008, 0x48414C00 | 'J') || tid == TITLE_ID(0x10008, 0x48414C00 | 'K'))) && get_sm_region_basic() == 0)
|
||||
|| (tid == TITLE_ID(0x10008, 0x48414C00 | 'E') || tid == TITLE_ID(0x10008, 0x48414C00 | 'P') || tid == TITLE_ID(0x10008, 0x48414C00 | 'J') || tid == TITLE_ID(0x10008, 0x48414C00 | 'K'))) && region == 0)
|
||||
{
|
||||
printf("\n Can't get the SM region\n Please check the site for updates\n");
|
||||
printf("\n Unkown SM region\n Please check the site for updates\n");
|
||||
ret = -999;
|
||||
goto out;
|
||||
}
|
||||
if(tid == TITLE_ID(0x10008, 0x48414B00 | get_sm_region_basic()))
|
||||
if(tid == TITLE_ID(0x10008, 0x48414B00 | region))
|
||||
{
|
||||
printf("\n I won't uninstall the EULA\n");
|
||||
ret = -999;
|
||||
goto out;
|
||||
}
|
||||
if(tid == TITLE_ID(0x10008, 0x48414C00 | get_sm_region_basic()))
|
||||
if(tid == TITLE_ID(0x10008, 0x48414C00 | region))
|
||||
{
|
||||
printf("\n I won't uninstall rgsel\n");
|
||||
ret = -999;
|
||||
goto out;
|
||||
}
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | get_sm_region_basic())))
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | region)))
|
||||
{
|
||||
printf("\n I won't uninstall the EULAs IOS\n");
|
||||
ret = -999;
|
||||
goto out;
|
||||
}
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | get_sm_region_basic())))
|
||||
if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | region)))
|
||||
{
|
||||
printf("\n I won't uninstall the rgsel IOS\n");
|
||||
ret = -999;
|
||||
|
@ -2,7 +2,9 @@
|
||||
#define _WAD_H_
|
||||
|
||||
/* Prototypes */
|
||||
s32 Wad_Install(FILE *);
|
||||
s32 Wad_Uninstall(FILE *);
|
||||
s32 Wad_Install(FILE* fp);
|
||||
s32 Wad_Uninstall(FILE* fp);
|
||||
s32 GetSysMenuRegion(u16* version, char* region);
|
||||
const char* GetSysMenuRegionString(const char* region);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user