Build for main svn r428

* Added nanddumper functions (Nand dumper not enabled yet)

* Added an extended check for new installed games which is enabled by default
Since the check takes some time you can bypass the check by setting: 'extended_list_check' in GENERAL section of wiiflow.ini to 'no'
Todo: Add an extended check for removed games

* Fixed a bug ISFS_Initialize() was called before reloading to cIOS

* Fixed long wait time when installing a Wii game @ 100%
This commit is contained in:
overjoy.psm 2012-04-05 11:00:05 +00:00
parent 9607e68ef2
commit 3153ef3d2e
11 changed files with 300 additions and 46 deletions

View File

@ -1,6 +1,6 @@
/***************************************************************************
* Copyright (C) 2011 by Miigotu for wiiflow 2011
* (C) 2012 by OverjoY for Wiiflow-mod
* Copyright (C) 2011 by Miigotu
* (C) 2012 by OverjoY
*
* Rewritten code from Mighty Channels and Triiforce
*
@ -23,7 +23,7 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Nand/Emulation Handling Class
* Nand/Emulation Handling Class for Wiiflow
*
***************************************************************************/
@ -39,7 +39,7 @@
#include "utils.h"
#include "gecko.h"
#include "mem2.hpp"
#include "smartptr.hpp"
#include "text.hpp"
u8 *confbuffer ATTRIBUTE_ALIGN(32);
u8 CCode[0x1008];
@ -51,7 +51,8 @@ config_header *cfg_hdr;
bool tbdec = false;
bool configloaded = false;
static NandDevice NandDeviceList[] = {
static NandDevice NandDeviceList[] =
{
{ "Disable", 0, 0x00, 0x00 },
{ "SD/SDHC Card", 1, 0xF0, 0xF1 },
{ "USB 2.0 Mass Storage Device", 2, 0xF2, 0xF3 },
@ -228,6 +229,45 @@ void Nand::__configshifttxt(char *str)
*ctr = '\0';
}
void Nand::__GetNameList(const char *source, namelist **entries, int *count)
{
u32 i, j, k, l;
u32 numentries = 0;
char *names;
char curentry[ISFS_MAXPATH];
char entrypath[ISFS_MAXPATH];
s32 ret = ISFS_ReadDir(source, NULL, &numentries);
names = (char *)MEM2_alloc((ISFS_MAXPATH) * numentries);
ret = ISFS_ReadDir(source, names, &numentries);
*count = numentries;
if(*entries)
MEM2_free(*entries);
*entries = (namelist *)MEM2_alloc(sizeof(namelist)*numentries);
for(i = 0, k = 0; i < numentries; i++)
{
for(j = 0; names[k] != 0; j++, k++)
curentry[j] = names[k];
curentry[j] = 0;
k++;
strcpy((*entries)[i].name, curentry);
if(source[strlen(source)-1] == '/')
snprintf(entrypath, sizeof(entrypath), "%s%s", source, curentry);
else
snprintf(entrypath, sizeof(entrypath), "%s/%s", source, curentry);
ret = ISFS_ReadDir(entrypath, NULL, &l);
(*entries)[i].type = ret < 0 ? 0 : 1;
}
MEM2_free(names);
}
s32 Nand::__configread(void)
{
confbuffer = (u8 *)MEM2_alloc(0x4000);
@ -360,6 +400,67 @@ u32 Nand::__configsetsetting(const char *item, const char *val)
return 0;
}
bool Nand::__FileExists(const char *path, ...)
{
FILE *f = fopen(path, "rb");
if (f != 0)
{
gprintf("File \"%s\" exists\n", path);
SAFE_CLOSE(f);
return true;
}
return false;
}
u32 Nand::__TestNandPath(const char *path)
{
if(!strncmp(path, "/import", 7)) return 0;
if(!strncmp(path, "/meta", 5)) return 0;
if(!strncmp(path, "/shared", 7) && !n_dumpwsc && !n_dumpwvc) return 1;
if(!strncmp(path, "/sys", 4)) return 0;
if(!strncmp(path, "/ticket/00000001/", 17))
{
const char *tmp = path + 17;
if(!strncmp(tmp, "00000002.tik", 8) && !n_dumpmen) return 1; // Menu
if(strncmp(tmp, "00000002.tik", 8) && !n_dumpios) return 1; // IOSs
return 0;
}
if(!strncmp(path, "/ticket/00010001/", 17))
{
const char *tmp = path + 17;
if(!strncmp(tmp, "48XXXXXX.tik", 2) && n_dumpwsc) return 0; // SC
if(strncmp(tmp, "48XXXXXX.tik", 2) && n_dumpwvc) return 0; // WW&VC
return 1;
}
if(!strncmp(path, "/ticket/00010002/", 17) && !n_dumpwsc) return 1; // SC
if(!strncmp(path, "/ticket/00010005/", 17) && !n_dumpwgs) return 1; // DLC?
if(!strncmp(path, "/ticket/00010008/", 17) && !n_dumpwsc) return 1; // Hidden SC
if(!strncmp(path, "/title/00000001/", 16))
{
const char *tmp = path + 16;
if(!strncmp(tmp, "00000002", 8) && n_dumpmen) return 0; // Menu
if(strncmp(tmp, "00000002", 8) && n_dumpios) return 0; // IOSs
return 1;
}
if(!strncmp(path, "/title/00010000/", 16) && !n_dumpwgs) return 1; // Saves
if(!strncmp(path, "/title/00010001/", 16))
{
const char *tmp = path + 16;
if(!strncmp(tmp, "48XXXXXX", 2) && n_dumpwsc) return 0; // SC
if(strncmp(tmp, "48XXXXXX", 2) && n_dumpwvc) return 0; // WW&VC
return 1;
}
if(!strncmp(path, "/title/00010002/", 16) && !n_dumpwsc) return 1; // SC
if(!strncmp(path, "/title/00010004/", 16) && !n_dumpwgs) return 1; // Saves
if(!strncmp(path, "/title/00010005/", 16) && !n_dumpwgs) return 1; // DLC
if(!strncmp(path, "/title/00010008/", 16) && !n_dumpwsc) return 1; // Hidden SC
if(!strncmp(path, "/tmp", 4)) return 0;
return 0;
}
s32 Nand::__FlashNandFile(const char *source, const char *dest)
{
s32 ret;
@ -374,7 +475,7 @@ s32 Nand::__FlashNandFile(const char *source, const char *dest)
u32 fsize = ftell(file);
fseek(file, 0, SEEK_SET);
gprintf("Flashing: %s (%uKB) to nand: %s...", source, (fsize / 0x400)+1, dest);
gprintf("Flashing: %s (%uKB) to nand...", source, (fsize / 0x400)+1);
ISFS_Delete(dest);
ISFS_CreateFile(dest, 0, 3, 3, 3);
@ -425,13 +526,19 @@ s32 Nand::__FlashNandFile(const char *source, const char *dest)
s32 Nand::__DumpNandFile(const char *source, const char *dest)
{
if(__TestNandPath(source))
return 0;
s32 fd = ISFS_Open(source, ISFS_OPEN_READ);
if (fd < 0)
{
gprintf("Error: IOS_OPEN(%s, %d) %d\n", source, ISFS_OPEN_READ, fd);
return fd;
}
if(__FileExists(dest))
remove(dest);
FILE *file = fopen(dest, "wb");
if (!file)
{
@ -451,7 +558,7 @@ s32 Nand::__DumpNandFile(const char *source, const char *dest)
return ret;
}
gprintf("Dumping: %s (%uKB) from nand to %s...", source, (status->file_length / 0x400)+1, dest);
gprintf("Dumping: %s (%uKB)...", source, (status->file_length / 0x400)+1);
u8 *buffer = (u8 *)MEM2_alloc(BLOCK);
u32 toread = status->file_length;
@ -492,18 +599,59 @@ s32 Nand::__DumpNandFile(const char *source, const char *dest)
return 1;
}
void Nand::__CreatePath(const char *path, ...)
s32 Nand::__DumpNandFolder(const char *source, const char *dest)
{
namelist *names = NULL;
int cnt, i;
char nsource[ISFS_MAXPATH];
char ndest[MAX_FAT_PATH];
__GetNameList(source, &names, &cnt);
for(i = 0; i < cnt; i++)
{
if(source[strlen(source)-1] == '/')
snprintf(nsource, sizeof(nsource), "%s%s", source, names[i].name);
else
snprintf(nsource, sizeof(nsource), "%s/%s", source, names[i].name);
if(!names[i].type)
{
Asciify2(nsource);
snprintf(ndest, sizeof(ndest), "%s%s", dest, nsource);
__DumpNandFile(nsource, ndest);
}
else
{
if(!__TestNandPath(nsource))
{
CreatePath("%s%s", dest, nsource);
__DumpNandFolder(nsource, dest);
}
}
}
SAFE_FREE(names);
return 0;
}
void Nand::CreatePath(const char *path, ...)
{
char *folder = NULL;
va_list args;
va_start(args, path);
if((vasprintf(&folder, path, args) >= 0) && folder)
{
if(folder[strlen(folder)-1] == '/')
folder[strlen(folder)-1] = 0;
Asciify2(folder);
DIR *d;
d = opendir(folder);
if(!d)
{
{
gprintf("Creating folder: \"%s\"\n", folder);
makedir(folder);
}
@ -516,19 +664,46 @@ void Nand::__CreatePath(const char *path, ...)
va_end(args);
SAFE_FREE(folder);
}
s32 Nand::DoNandDump(const char *source, const char *dest, bool dumpios, bool dumpwgs, bool dumpwsc, bool dumpwvc, bool dumpmen)
{
n_dumpios = dumpios;
n_dumpwgs = dumpwgs;
n_dumpwsc = dumpwsc;
n_dumpwvc = dumpwvc;
n_dumpmen = dumpmen;
u32 temp = 0;
s32 ret = ISFS_ReadDir(source, NULL, &temp);
if(ret < 0)
{
char ndest[MAX_FAT_PATH];
snprintf(ndest, sizeof(ndest), "%s%s", dest, source);
CreatePath(dest);
__DumpNandFile(source, ndest);
}
else
{
__DumpNandFolder(source, dest);
}
return 0;
}
s32 Nand::CreateConfig(const char *path)
{
__CreatePath(path);
__CreatePath("%s/shared2", path);
__CreatePath("%s/shared2/sys", path);
__CreatePath("%s/title", path);
__CreatePath("%s/title/00000001", path);
__CreatePath("%s/title/00000001/00000002", path);
__CreatePath("%s/title/00000001/00000002/data", path);
CreatePath(path);
CreatePath("%s/shared2", path);
CreatePath("%s/shared2/sys", path);
CreatePath("%s/title", path);
CreatePath("%s/title/00000001", path);
CreatePath("%s/title/00000001/00000002", path);
CreatePath("%s/title/00000001/00000002/data", path);
bzero(cfgpath, MAX_FAT_PATH);
bzero(settxtpath, MAX_FAT_PATH);
bzero(cfgpath, MAX_FAT_PATH+1);
bzero(settxtpath, MAX_FAT_PATH+1);
snprintf(cfgpath, sizeof(cfgpath), "%s%s", path, SYSCONFPATH);
snprintf(settxtpath, sizeof(settxtpath), "%s%s", path, TXTPATH);
@ -602,5 +777,4 @@ s32 Nand::Do_Region_Change(string id)
}
__configwrite();
return 1;
}
}

View File

@ -21,7 +21,7 @@
#define SYSCONFPATH "/shared2/sys/SYSCONF"
#define TXTPATH "/title/00000001/00000002/data/setting.txt"
#define BLOCK 0x4000
#define BLOCK 2048
/* 'NAND Device' structure */
typedef struct nandDevice
@ -39,6 +39,12 @@ typedef struct _config_header
u16 noff[];
} config_header;
typedef struct _namelist
{
char name[ISFS_MAXPATH];
int type;
} namelist;
using namespace std;
class Nand
@ -60,10 +66,12 @@ class Nand
u32 Get_Partition(void) { return Partition; };
void Set_NandPath(string path);
void CreatePath(const char *path, ...);
s32 CreateConfig(const char *path);
s32 Do_Region_Change(string id);
s32 DoNandDump(const char *source, const char *dest, bool dumpios, bool dumpwgs, bool dumpwsc, bool dumpwvc, bool dumpmen);
private:
Nand() : MountedDevice(0), EmuDevice(REAL_NAND), Disabled(true), Partition(0), FullMode(0x100), NandPath() {}
~Nand(void){}
@ -75,20 +83,27 @@ class Nand
s32 Nand_Disable(void);
void __Dec_Enc_TB(void);
void __configshifttxt(char *str);
void __GetNameList(const char *source, namelist **entries, int *count);
s32 __configread(void);
s32 __configwrite(void);
u32 __configsetbyte(const char *item, u8 val);
u32 __configsetbigarray(const char *item, void *val, u32 size);
u32 __configsetsetting(const char *item, const char *val);
bool __FileExists(const char *path, ...);
u32 __TestNandPath(const char *path);
s32 __FlashNandFile(const char *source, const char *dest);
s32 __DumpNandFile(const char *source, const char *dest);
void __CreatePath(const char *path, ...);
s32 __DumpNandFolder(const char *source, const char *dest);
u32 MountedDevice;
u32 EmuDevice;
bool Disabled;
bool n_dumpios;
bool n_dumpwgs;
bool n_dumpwsc;
bool n_dumpwvc;
bool n_dumpmen;
u32 Partition ATTRIBUTE_ALIGN(32);
u32 FullMode ATTRIBUTE_ALIGN(32);
char NandPath[32] ATTRIBUTE_ALIGN(32);

View File

@ -1,9 +1,10 @@
#define APP_NAME "WiiFlow"
#define APP_VERSION "Mod 3.0"
#define APP_VERSION "Mod 3.1"
#define APPDATA_DIR "wiiflow"
#define APPDATA_DIR2 "apps/wiiflow"
#define STDEMU_DIR "/wiiflow/nandemu"
#define GAMES_DIR "%s:/wbfs"
#define HOMEBREW_DIR "%s:/apps"
#define DML_DIR "%s:/games"
@ -13,8 +14,8 @@
#define TITLES_FILENAME "titles.ini"
#define CTITLES_FILENAME "custom_titles.ini"
#define DEVELOPERS "r-win, Miigotu, OverjoY, FIX94"
#define PAST_DEVELOPERS "Hibernatus, Narolez, Hulk"
#define DEVELOPERS "r-win, OverjoY, FIX94"
#define PAST_DEVELOPERS "Hibernatus, Narolez, Hulk, Miigotu"
#define LOADER_AUTHOR "Kwiirk, Waninkoko, Hermes"
#define GUI_AUTHOR "Hibernatus"

View File

@ -497,7 +497,6 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
}
if (ret) break;
info->wlba_table[i] = wbfs_htons(bl);
wbfs_sync(p);
}
// write disc info
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;

View File

@ -493,7 +493,6 @@ void Asciify2( char *str )
{
case '*':
case '\"':
case ':':
case '|':
case '<':
case '>':

View File

@ -40,13 +40,31 @@ void CachedList<T>::Load(string path, string containing, string m_lastLanguage)
bool noDB = stat(m_database.c_str(), &cache) == -1;
bool mtimes = filestat.st_mtime > cache.st_mtime;
if(strcasestr(m_discinf.c_str(), "wbfs") != NULL && stat(m_discinf.c_str(), &discinfo) != -1)
ditimes = discinfo.st_mtime > cache.st_mtime;
ditimes = discinfo.st_mtime > cache.st_mtime;
m_update = update_lang || noDB || mtimes || ditimes;
if(m_update) gprintf("Cache of %s is being updated because ", path.c_str());
if(update_lang) gprintf("languages are different!\nOld language string: %s\nNew language string: %s\n", m_lastLanguage.c_str(), m_curLanguage.c_str());
if(noDB) gprintf("a database was not found!\n");
if(mtimes || ditimes) gprintf("the WBFS folder was modified!\n");
if(m_extcheck && !m_update)
{
bool m_chupdate = false;
DIR *dir = opendir(path.c_str());
struct dirent *entry;
while((entry = readdir(dir)) != NULL)
{
m_discinf = sfmt("%s/%s", path.c_str(), entry->d_name);
if(stat(m_discinf.c_str(), &discinfo) != -1)
m_chupdate = discinfo.st_mtime > cache.st_mtime;
if(m_chupdate)
break;
}
m_update = m_chupdate;
}
}
if(update_games) force_update[COVERFLOW_USB] = false;

View File

@ -20,7 +20,7 @@ template <typename T = dir_discHdr>
class CachedList : public safe_vector<T>
{
public:
void Init(string cachedir, string settingsDir, string curLanguage, string DMLgameDir) /* Initialize Private Variables */
void Init(string cachedir, string settingsDir, string curLanguage, string DMLgameDir, bool extcheck) /* Initialize Private Variables */
{
m_cacheDir = cachedir;
m_settingsDir = settingsDir;
@ -28,6 +28,7 @@ class CachedList : public safe_vector<T>
m_loaded = false;
m_database = "";
m_update = false;
m_extcheck = extcheck;
m_DMLgameDir = DMLgameDir;
for(u32 i = 0; i < COVERFLOW_MAX; i++)
force_update[i] = false;
@ -67,6 +68,7 @@ class CachedList : public safe_vector<T>
bool m_loaded;
bool m_update;
bool m_wbfsFS;
bool m_extcheck;
u8 force_update[COVERFLOW_MAX];
CList<T> list;
string m_database;

View File

@ -52,14 +52,14 @@ int main(int argc, char **argv)
gameid = NULL;
}
}
gprintf("Loading cIOS: %d\n", mainIOS);
ISFS_Initialize();
gprintf("Loading cIOS: %d\n", mainIOS);
// Load Custom IOS
bool iosOK = loadIOS(mainIOS, false);
MEM2_init(52);
ISFS_Initialize();
u8 mainIOSBase = 0;
iosOK = iosOK && cIOSInfo::D2X(mainIOS, &mainIOSBase);
gprintf("Loaded cIOS: %u has base %u\n", mainIOS, mainIOSBase);

View File

@ -375,7 +375,9 @@ void CMenu::init(void)
m_loc.load(sfmt("%s/%s.ini", m_languagesDir.c_str(), m_curLanguage.c_str()).c_str());
}
m_gameList.Init(m_listCacheDir, m_settingsDir, m_loc.getString(m_curLanguage, "gametdb_code", "EN"), m_DMLgameDir);
bool extcheck = m_cfg.getBool("GENERAL", "extended_list_check", true);
m_gameList.Init(m_listCacheDir, m_settingsDir, m_loc.getString(m_curLanguage, "gametdb_code", "EN"), m_DMLgameDir, extcheck);
m_aa = 3;

View File

@ -1,4 +1,6 @@
//#define ENABLEDUMPER
#include "menu.hpp"
#include "loader/patchcode.h"
@ -1008,7 +1010,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
emuPartition = m_cfg.getInt("NAND", "partition", 0);
string emuPath = m_cfg.getString("GAMES", "savepath", m_cfg.getString("NAND", "path", ""));
u8 emuSave = min((u32)m_gcfg2.getInt(id, "emulate_save", 0), ARRAY_SIZE(CMenu::_SaveEmu) - 1u);
if (emuSave == 0)
@ -1018,15 +1020,54 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
emuSave++;
}
else if (emuSave == 1)
emuSave = 0;
if (!dvd && get_frag_list((u8 *) hdr->hdr.id, (char *) hdr->path, currentPartition == 0 ? 0x200 : sector_size) < 0)
return;
emuSave = 0;
if(!dvd && emuSave)
{
{
bool createnand = false;
char basepath[64];
snprintf(basepath, 64, "%s:%s", DeviceName[emuPartition], emuPath.c_str());
if(emuPath.size() == 0)
{
Nand::Instance()->CreatePath("%s:/wiiflow", DeviceName[emuPartition]);
Nand::Instance()->CreatePath("%s:/wiiflow/nandemu", DeviceName[emuPartition]);
m_cfg.setString("GAMES", "savepath", STDEMU_DIR);
emuPath = m_cfg.getString("GAMES", "savepath", STDEMU_DIR);
snprintf(basepath, 64, "%s:%s", DeviceName[emuPartition], emuPath.c_str());
if(emuSave == 4)
createnand = true;
}
else
{
snprintf(basepath, 64, "%s:%s", DeviceName[emuPartition], emuPath.c_str());
if(emuSave == 4)
{
DIR *d;
d = opendir(basepath);
if(!d)
{
Nand::Instance()->CreatePath("%s:/wiiflow", DeviceName[emuPartition]);
Nand::Instance()->CreatePath("%s:/wiiflow/nandemu", DeviceName[emuPartition]);
createnand = true;
}
else
{
closedir(d);
}
}
}
if(createnand)
{
#ifdef ENABLEDUMPER
bool dumpios = m_cfg.getBool("NAND", "nanddumpios", false);
bool dumpgs = m_cfg.getBool("NAND", "nanddumpgamesaves", false);
bool dumpsc = m_cfg.getBool("NAND", "nanddumpsyschannels", false);
bool dumpwvc = m_cfg.getBool("NAND", "nanddumpwwchannels", true);
bool dumpmen = m_cfg.getBool("NAND", "nanddumpsysmenu", false);
Nand::Instance()->DoNandDump("/", basepath, dumpios, dumpgs, dumpsc, dumpwvc, dumpmen);
#endif
}
if(emuSave == 2 || emuSave > 3)
{
CreateSavePath(basepath, hdr);
@ -1037,6 +1078,9 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
Nand::Instance()->Do_Region_Change(id);
}
}
if (!dvd && get_frag_list((u8 *) hdr->hdr.id, (char *) hdr->path, currentPartition == 0 ? 0x200 : sector_size) < 0)
return;
int gameIOS = 0;
int userIOS = 0;

View File

@ -31,7 +31,7 @@ void MusicPlayer::Init(Config &cfg, string musicDir, string themeMusicDir)
SetVolume(0); // Fades in with tick()
MusicDirectory dir = (MusicDirectory) cfg.getInt("GENERAL", "music_directories", NORMAL_MUSIC | THEME_MUSIC);
m_music_files.Init(cfg.getString("GENERAL", "dir_list_cache"), std::string(), std::string(), std::string());
m_music_files.Init(cfg.getString("GENERAL", "dir_list_cache"), std::string(), std::string(), std::string(), false);
if (dir & THEME_MUSIC)
m_music_files.Load(themeMusicDir, ".ogg|.mp3", "EN"); //|.mod|.xm|.s3m|.wav|.aiff");