mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-18 17:29:17 +01:00
5adbf57bf5
* Fixed progress window not hiding if Wiiload didn't send the file. * Simplify HBC loading logic. * Added a warning when trying to launch a Wii game with a non-d2x cIOS if EmuNAND is enabled. * Fixed individual game settings to allow modification of the EmuNAND settings based on the game's IOS instead of global IOS. * Added back cIOS rev17-21 support for EmuNAND Channel. issue 2152 (Thanks to Garfunkiel for the patch and to Themanuel for all the tests with game compatibility and partition detection) This hidden feature is unlocked only if all the user's setup is compatible with rev17-21: EmuNAND Channel path must be on the root of the first FAT32 partition on a 512 bytes/sector device. * DML: Changed the GameCube Multi-discs prompt logic to display on older DIOS MIOS (Lite) versions too. * DML: Added a partition type verification to warn the user if the HDD is not correctly setup.
272 lines
4.6 KiB
C++
272 lines
4.6 KiB
C++
/*****************************************
|
|
* This code is from Mighty Channel 11
|
|
* which is based on the TriiForce source.
|
|
* Modifications by Dimok.
|
|
*****************************************/
|
|
#include <stdio.h>
|
|
#include <ogcsys.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
|
|
#include "system/IosLoader.h"
|
|
#include "utils/tools.h"
|
|
#include "gecko.h"
|
|
#include "NandEmu.h"
|
|
|
|
/* 'NAND Device' structure */
|
|
typedef struct {
|
|
/* Device name */
|
|
const char *name;
|
|
|
|
/* Mode value */
|
|
u32 mode;
|
|
|
|
/* Un/mount command */
|
|
u32 mountCmd;
|
|
u32 umountCmd;
|
|
} nandDevice;
|
|
|
|
static nandDevice ndevList[] =
|
|
{
|
|
{ "Disable", 0, 0x00, 0x00 },
|
|
{ "SD/SDHC Card", 1, 0xF0, 0xF1 },
|
|
{ "USB 2.0 Mass Storage Device", 2, 0xF2, 0xF3 },
|
|
};
|
|
|
|
/* Buffer */
|
|
static const char fs[] ATTRIBUTE_ALIGN(32) = "/dev/fs";
|
|
static const char fat[] ATTRIBUTE_ALIGN(32) = "fat";
|
|
static u32 inbuf[8] ATTRIBUTE_ALIGN(32);
|
|
static u32 partition ATTRIBUTE_ALIGN(32) = 0;
|
|
static u32 mode ATTRIBUTE_ALIGN(32) = 0;
|
|
static char path[32] ATTRIBUTE_ALIGN(32) = "\0";
|
|
static int fullmode = 0;
|
|
static int mounted = 0;
|
|
|
|
static s32 Nand_Mount(nandDevice *dev)
|
|
{
|
|
s32 fd, ret;
|
|
u32 inlen = 0;
|
|
ioctlv *vector = NULL;
|
|
int rev = IOS_GetRevision();
|
|
|
|
/* Open FAT module */
|
|
fd = IOS_Open(fat, 0);
|
|
if (fd < 0)
|
|
return fd;
|
|
|
|
|
|
if(rev >= 21 && rev < 30000)
|
|
{
|
|
// NOTE:
|
|
// The official cIOSX rev21 by Waninkoko ignores the partition argument
|
|
// and the nand is always expected to be on the 1st partition.
|
|
// However this way earlier d2x betas having revision 21 take in
|
|
// consideration the partition argument.
|
|
inlen = 1;
|
|
|
|
/* Allocate memory */
|
|
vector = (ioctlv *) memalign(32, sizeof(ioctlv));
|
|
if(vector == NULL)
|
|
{
|
|
/* Close FAT module */
|
|
IOS_Close(fd);
|
|
return -2;
|
|
}
|
|
|
|
vector[0].data = &partition;
|
|
vector[0].len = sizeof(u32);
|
|
}
|
|
/* Mount device */
|
|
ret = IOS_Ioctlv(fd, dev->mountCmd, inlen, 0, vector);
|
|
|
|
/* Close FAT module */
|
|
IOS_Close(fd);
|
|
|
|
/* Free memory */
|
|
free(vector);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static s32 Nand_Unmount(nandDevice *dev)
|
|
{
|
|
s32 fd, ret;
|
|
|
|
// Open FAT module
|
|
fd = IOS_Open(fat, 0);
|
|
if (fd < 0)
|
|
return fd;
|
|
|
|
// Unmount device
|
|
ret = IOS_Ioctlv(fd, dev->umountCmd, 0, 0, NULL);
|
|
|
|
// Close FAT module
|
|
IOS_Close(fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static s32 Nand_Enable(nandDevice *dev)
|
|
{
|
|
s32 fd, ret;
|
|
ioctlv *vector = NULL;
|
|
int rev = IOS_GetRevision();
|
|
|
|
// Open /dev/fs
|
|
fd = IOS_Open(fs, 0);
|
|
if (fd < 0)
|
|
return fd;
|
|
|
|
if (IOS_GetRevision() >= 18)
|
|
{
|
|
//FULL NAND emulation since rev18
|
|
//needed for reading images on triiforce mrc folder using ISFS commands
|
|
mode = dev->mode | fullmode;
|
|
}
|
|
else
|
|
{
|
|
mode = dev->mode;
|
|
}
|
|
|
|
if(rev >= 21 && rev < 30000)
|
|
{
|
|
// NOTE:
|
|
// The official cIOSX rev21 by Waninkoko provides an undocumented feature
|
|
// to set nand path when mounting the device.
|
|
// This feature has been discovered during d2x development.
|
|
|
|
/* Allocate memory */
|
|
vector = (ioctlv *)memalign(32, sizeof(ioctlv)*2);
|
|
if(vector == NULL)
|
|
{
|
|
/* Close FAT module */
|
|
IOS_Close(fd);
|
|
return -2;
|
|
}
|
|
|
|
vector[0].data = &mode;
|
|
vector[0].len = sizeof(u32);
|
|
vector[1].data = path;
|
|
vector[1].len = sizeof(path);
|
|
|
|
ret = IOS_Ioctlv(fd, 100, 2, 0, vector);
|
|
|
|
/* Free memory */
|
|
free(vector);
|
|
}
|
|
else
|
|
{
|
|
memset(inbuf, 0, sizeof(inbuf));
|
|
inbuf[0] = dev->mode;
|
|
ret = IOS_Ioctl(fd, 100, inbuf, sizeof(inbuf), NULL, 0);
|
|
}
|
|
|
|
// Close /dev/fs
|
|
IOS_Close(fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static s32 Nand_Disable(void)
|
|
{
|
|
s32 fd, ret;
|
|
|
|
// Open /dev/fs
|
|
fd = IOS_Open(fs, 0);
|
|
if (fd < 0)
|
|
return fd;
|
|
|
|
// Set input buffer
|
|
mode = 0;
|
|
|
|
// Disable NAND emulator
|
|
ret = IOS_Ioctl(fd, 100, &mode, sizeof(mode), NULL, 0);
|
|
|
|
// Close /dev/fs
|
|
IOS_Close(fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 Enable_Emu(int selection)
|
|
{
|
|
if(!IosLoader::IsD2X() && IOS_GetRevision() < 17)
|
|
return -1;
|
|
|
|
if(mounted != 0)
|
|
return -1;
|
|
|
|
s32 ret;
|
|
nandDevice *ndev = NULL;
|
|
ndev = &ndevList[selection];
|
|
|
|
ret = Nand_Mount(ndev);
|
|
if (ret < 0)
|
|
{
|
|
gprintf(" ERROR Mount! (ret = %d)\n", ret);
|
|
return ret;
|
|
|
|
}
|
|
|
|
ret = Nand_Enable(ndev);
|
|
if (ret < 0)
|
|
{
|
|
gprintf(" ERROR Enable! (ret = %d)\n", ret);
|
|
return ret;
|
|
}
|
|
mounted = selection;
|
|
return 0;
|
|
}
|
|
|
|
s32 Disable_Emu()
|
|
{
|
|
if(!IosLoader::IsD2X() && IOS_GetRevision() < 17)
|
|
return -1;
|
|
|
|
if(mounted==0)
|
|
return 0;
|
|
|
|
nandDevice *ndev = NULL;
|
|
ndev = &ndevList[mounted];
|
|
|
|
Nand_Disable();
|
|
Nand_Unmount(ndev);
|
|
|
|
mounted = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Set_Partition(int p)
|
|
{
|
|
partition = p;
|
|
}
|
|
|
|
void Set_Path(const char* p)
|
|
{
|
|
int i = 0;
|
|
|
|
while(p[i] != '\0' && i < 31)
|
|
{
|
|
path[i] = p[i];
|
|
i++;
|
|
}
|
|
while(path[i-1] == '/')
|
|
{
|
|
path[i-1] = '\0';
|
|
--i;
|
|
}
|
|
path[i] = '\0';
|
|
}
|
|
|
|
void Set_FullMode(int fm)
|
|
{
|
|
fullmode = fm ? 0x100 : 0;
|
|
}
|
|
|
|
const char* Get_Path(void)
|
|
{
|
|
return path;
|
|
}
|