mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-30 15:14:18 +01:00
-updated dml usb to sd installer, should
be faster now thanks to threaded copy by stfour, also fixed codedumps when copying from ntfs to sd, everything should work now
This commit is contained in:
parent
5e18be6598
commit
fcf9d344f7
@ -20,15 +20,25 @@ en exposed s_fsop fsop structure can be used by callback to update operation sta
|
||||
#include "fileOps.h"
|
||||
#include "memory/mem2.hpp"
|
||||
#include "utils.h"
|
||||
#include "gecko.h"
|
||||
|
||||
s_fsop fsop;
|
||||
#define SET(a, b) a = b; DCFlushRange(&a, sizeof(a));
|
||||
#define STACKSIZE 8192
|
||||
|
||||
static u8 *buff = NULL;
|
||||
static FILE *fs = NULL, *ft = NULL;
|
||||
static u32 block = 32768;
|
||||
static u32 blockIdx = 0;
|
||||
static u32 blockInfo[2] = {0,0};
|
||||
static u32 blockReady = 0;
|
||||
static u32 stopThread;
|
||||
|
||||
// return false if the file doesn't exist
|
||||
bool fsop_GetFileSizeBytes (char *path, size_t *filesize) // for me stats st_size report always 0 :(
|
||||
{
|
||||
FILE *f;
|
||||
size_t size = 0;
|
||||
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if (!f)
|
||||
{
|
||||
@ -42,7 +52,6 @@ bool fsop_GetFileSizeBytes (char *path, size_t *filesize) // for me stats st_siz
|
||||
if (filesize) *filesize = size;
|
||||
SAFE_CLOSE(f);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -55,17 +64,17 @@ u64 fsop_GetFolderBytes (char *source)
|
||||
struct dirent *pent;
|
||||
char newSource[300];
|
||||
u64 bytes = 0;
|
||||
|
||||
pdir=opendir(source);
|
||||
|
||||
|
||||
pdir = opendir(source);
|
||||
|
||||
while ((pent=readdir(pdir)) != NULL)
|
||||
{
|
||||
// Skip it
|
||||
if (strcmp (pent->d_name, ".") == 0 || strcmp (pent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
sprintf (newSource, "%s/%s", source, pent->d_name);
|
||||
|
||||
|
||||
// If it is a folder... recurse...
|
||||
if (fsop_DirExist (newSource))
|
||||
{
|
||||
@ -78,13 +87,10 @@ u64 fsop_GetFolderBytes (char *source)
|
||||
bytes += s;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(pdir);
|
||||
|
||||
//Debug ("fsop_GetFolderBytes (%s) = %llu", source, bytes);
|
||||
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
u32 fsop_GetFolderKb (char *source)
|
||||
{
|
||||
@ -96,11 +102,11 @@ u32 fsop_GetFolderKb (char *source)
|
||||
u32 fsop_GetFreeSpaceKb (char *path) // Return free kb on the device passed
|
||||
{
|
||||
struct statvfs s;
|
||||
|
||||
statvfs (path, &s);
|
||||
|
||||
|
||||
statvfs(path, &s);
|
||||
|
||||
u32 ret = (u32)round( ((double)s.f_bfree / 1000.0) * s.f_bsize);
|
||||
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
@ -108,28 +114,46 @@ u32 fsop_GetFreeSpaceKb (char *path) // Return free kb on the device passed
|
||||
bool fsop_DirExist (char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
|
||||
dir=opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *thread_CopyFileReader (void *arg)
|
||||
{
|
||||
u32 rb;
|
||||
stopThread = 0;
|
||||
DCFlushRange(&stopThread, sizeof(stopThread));
|
||||
do
|
||||
{
|
||||
SET (rb, fread(&buff[blockIdx*block], 1, block, fs ));
|
||||
SET (blockInfo[blockIdx], rb);
|
||||
SET (blockReady, 1);
|
||||
|
||||
while (blockReady && !stopThread) usleep(1);
|
||||
}
|
||||
while (stopThread == 0);
|
||||
|
||||
stopThread = -1;
|
||||
DCFlushRange(&stopThread, sizeof(stopThread));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fsop_CopyFile (char *source, char *target, progress_callback_t spinner, void *spinner_data)
|
||||
{
|
||||
gprintf("Creating file: %s\n",target);
|
||||
int err = 0;
|
||||
fsop.breakop = 0;
|
||||
|
||||
u8 *buff = NULL;
|
||||
|
||||
u32 size;
|
||||
u32 bytes, rb,wb;
|
||||
u32 block = 71680; //70KB
|
||||
FILE *fs = NULL, *ft = NULL;
|
||||
|
||||
|
||||
fs = fopen(source, "rb");
|
||||
if (!fs)
|
||||
{
|
||||
@ -142,63 +166,89 @@ bool fsop_CopyFile (char *source, char *target, progress_callback_t spinner, voi
|
||||
SAFE_CLOSE(fs);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//Get file size
|
||||
fseek (fs, 0, SEEK_END);
|
||||
size = ftell(fs);
|
||||
|
||||
fsop.size = size;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
SAFE_CLOSE(fs);
|
||||
SAFE_CLOSE(ft);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Return to beginning....
|
||||
fseek(fs, 0, SEEK_SET);
|
||||
|
||||
buff = MEM2_alloc(block);
|
||||
if (buff == NULL)
|
||||
{
|
||||
SAFE_CLOSE(fs);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
u8 * threadStack = NULL;
|
||||
lwp_t hthread = LWP_THREAD_NULL;
|
||||
|
||||
buff = MEM2_alloc(block*2);
|
||||
|
||||
blockIdx = 0;
|
||||
blockReady = 0;
|
||||
blockInfo[0] = 0;
|
||||
blockInfo[1] = 0;
|
||||
|
||||
threadStack = MEM2_alloc(STACKSIZE);
|
||||
LWP_CreateThread (&hthread, thread_CopyFileReader, NULL, threadStack, STACKSIZE, 30);
|
||||
|
||||
while (stopThread != 0)
|
||||
usleep (5);
|
||||
|
||||
bytes = 0;
|
||||
bool spinnerFlag = false;
|
||||
if (strstr (source, "game.iso")) {
|
||||
spinner(bytes, size, spinner_data);
|
||||
spinnerFlag = true;
|
||||
}
|
||||
|
||||
|
||||
u32 bi;
|
||||
do
|
||||
{
|
||||
rb = fread(buff, 1, block, fs);
|
||||
wb = fwrite(buff, 1, rb, ft);
|
||||
while (!blockReady) usleep (1); // Let's wait for incoming block from the thread
|
||||
|
||||
bi = blockIdx;
|
||||
|
||||
// let's th thread to read the next buff
|
||||
SET (blockIdx, 1 - blockIdx);
|
||||
SET (blockReady, 0);
|
||||
|
||||
rb = blockInfo[bi];
|
||||
// write current block
|
||||
wb = fwrite(&buff[bi*block], 1, rb, ft);
|
||||
|
||||
if (wb != wb) err = 1;
|
||||
if (rb == 0) err = 1;
|
||||
bytes += rb;
|
||||
|
||||
|
||||
if (spinnerFlag) spinner(bytes, size, spinner_data);
|
||||
|
||||
fsop.multy.bytes += rb;
|
||||
fsop.bytes = bytes;
|
||||
|
||||
if (fsop.breakop) break;
|
||||
}
|
||||
while (bytes < size && err == 0);
|
||||
|
||||
stopThread = 1;
|
||||
DCFlushRange(&stopThread, sizeof(stopThread));
|
||||
|
||||
while (stopThread != -1)
|
||||
usleep (5);
|
||||
|
||||
LWP_JoinThread(hthread, NULL);
|
||||
MEM2_free(threadStack);
|
||||
|
||||
stopThread = 1;
|
||||
DCFlushRange(&stopThread, sizeof(stopThread));
|
||||
|
||||
SAFE_CLOSE(fs);
|
||||
SAFE_CLOSE(ft);
|
||||
MEM2_free(buff);
|
||||
|
||||
if (err) unlink (target);
|
||||
|
||||
if (fsop.breakop || err) return false;
|
||||
|
||||
if (err)
|
||||
{
|
||||
unlink (target);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -211,21 +261,22 @@ static bool doCopyFolder (char *source, char *target, progress_callback_t spinne
|
||||
struct dirent *pent;
|
||||
char newSource[300], newTarget[300];
|
||||
bool ret = true;
|
||||
|
||||
|
||||
// If target folder doesn't exist, create it !
|
||||
if (!fsop_DirExist(target))
|
||||
{
|
||||
gprintf("Creating directory: %s\n",target);
|
||||
makedir(target);
|
||||
}
|
||||
|
||||
pdir=opendir(source);
|
||||
|
||||
pdir = opendir(source);
|
||||
|
||||
while ((pent=readdir(pdir)) != NULL && ret == true)
|
||||
{
|
||||
// Skip it
|
||||
if (strcmp (pent->d_name, ".") == 0 || strcmp (pent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
sprintf (newSource, "%s/%s", source, pent->d_name);
|
||||
sprintf (newTarget, "%s/%s", target, pent->d_name);
|
||||
|
||||
@ -236,11 +287,10 @@ static bool doCopyFolder (char *source, char *target, progress_callback_t spinne
|
||||
}
|
||||
else // It is a file !
|
||||
{
|
||||
strcpy(fsop.op, pent->d_name);
|
||||
ret = fsop_CopyFile(newSource, newTarget, spinner, spinner_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
closedir(pdir);
|
||||
|
||||
return ret;
|
||||
@ -248,10 +298,7 @@ static bool doCopyFolder (char *source, char *target, progress_callback_t spinne
|
||||
|
||||
bool fsop_CopyFolder (char *source, char *target, progress_callback_t spinner, void *spinner_data)
|
||||
{
|
||||
fsop.breakop = 0;
|
||||
fsop.multy.startms = ticks_to_millisecs(gettime());
|
||||
fsop.multy.bytes = 0;
|
||||
fsop.multy.size = fsop_GetFolderBytes (source);
|
||||
gprintf("DML game USB->SD job started!\n");
|
||||
|
||||
return doCopyFolder (source, target, spinner, spinner_data);
|
||||
return doCopyFolder(source, target, spinner, spinner_data);
|
||||
}
|
||||
|
@ -8,28 +8,6 @@ extern "C"
|
||||
|
||||
typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 size, bytes; // for operation that uses more than one file
|
||||
u32 startms;
|
||||
}
|
||||
s_fsopmulty;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char op[256]; // Calling process can set filename or any other info that fit
|
||||
|
||||
u32 size, bytes;
|
||||
|
||||
s_fsopmulty multy;
|
||||
|
||||
int flag1; // user defined flag
|
||||
bool breakop; // allow to stop a long operation
|
||||
}
|
||||
s_fsop;
|
||||
|
||||
extern s_fsop fsop;
|
||||
|
||||
bool fsop_GetFileSizeBytes (char *path, size_t *filesize);
|
||||
u64 fsop_GetFolderBytes (char *source);
|
||||
u32 fsop_GetFolderKb (char *source);
|
||||
|
@ -424,20 +424,24 @@ void CMenu::_game(bool launch)
|
||||
{
|
||||
_hideGame();
|
||||
dir_discHdr *hdr = m_cf.getHdr();
|
||||
|
||||
if(currentPartition != SD && m_current_view == COVERFLOW_DML)
|
||||
{
|
||||
char gcfolder[MAX_FAT_PATH];
|
||||
sprintf(gcfolder, "%s [%s]", m_cf.getTitle().toUTF8().c_str(), (char *)hdr->hdr.id);
|
||||
memset(hdr->path,0,sizeof(hdr->path));
|
||||
if (DML_GameIsInstalled((char *)hdr->hdr.id, DeviceName[SD]))
|
||||
{
|
||||
memset(hdr->path,0,sizeof(hdr->path));
|
||||
sprintf(hdr->path,"%s",(char*)hdr->hdr.id);
|
||||
}
|
||||
else if (DML_GameIsInstalled(gcfolder, DeviceName[SD]))
|
||||
{
|
||||
memset(hdr->path,0,sizeof(hdr->path));
|
||||
sprintf(hdr->path,"%s",gcfolder);
|
||||
}
|
||||
else if(!_wbfsOp(CMenu::WO_COPY_GAME))
|
||||
break;
|
||||
currentPartition = SD;
|
||||
}
|
||||
currentPartition = SD;
|
||||
|
||||
m_cf.clear();
|
||||
_showWaitMessage();
|
||||
|
@ -207,37 +207,40 @@ int CMenu::_GCgameInstaller(void *obj)
|
||||
int CMenu::_GCcopyGame(void *obj)
|
||||
{
|
||||
CMenu &m = *(CMenu *)obj;
|
||||
if(fsop_GetFreeSpaceKb((char*)"sd:/")<fsop_GetFolderKb(m.m_cf.getHdr()->path))
|
||||
char folder[12];
|
||||
char source[300];
|
||||
char target[300];
|
||||
snprintf(folder, sizeof(folder), DML_DIR, DeviceName[currentPartition]);
|
||||
snprintf(source, sizeof(source), "%s/%s", folder, m.m_cf.getHdr()->path);
|
||||
memset(folder, 0, sizeof(folder));
|
||||
snprintf(folder, sizeof(folder), DML_DIR, DeviceName[SD]);
|
||||
snprintf(target, sizeof(target), "%s/%s", folder, m.m_cf.getHdr()->path);
|
||||
int ret;
|
||||
if(fsop_GetFreeSpaceKb((char*)"sd:/")<fsop_GetFolderKb(source))
|
||||
{
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(wfmt(m._fmt("wbfsop10", L"Not enough space: %d blocks needed, %d available"), fsop_GetFolderKb(m.m_cf.getHdr()->path), fsop_GetFreeSpaceKb((char*)"sd:/")), 0.f);
|
||||
m._setThrdMsg(wfmt(m._fmt("wbfsop10", L"Not enough space: %d blocks needed, %d available"), fsop_GetFolderKb(source), fsop_GetFreeSpaceKb((char*)"sd:/")), 0.f);
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
m.m_thrdWorking = false;
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(L"", 0);
|
||||
char folder[MAX_FAT_PATH];
|
||||
snprintf(folder, sizeof(folder), DML_DIR, DeviceName[SD]);
|
||||
gprintf("Copying from:\n%s\nto:\n%s\n",source,target);
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
if (!fsop_DirExist(folder))
|
||||
makedir(folder);
|
||||
char source[MAX_FAT_PATH];
|
||||
char target[MAX_FAT_PATH];
|
||||
sprintf(source, "%s:/games/%s", DeviceName[currentPartition], m.m_cf.getHdr()->path);
|
||||
sprintf(target, "sd:/games/%s", m.m_cf.getHdr()->path);
|
||||
gprintf("Copying from: \n%s \nto: \n%s\n",source,target);
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
fsop_CopyFolder(source, target, CMenu::_addDiscProgress, obj);
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(m._t("wbfsop14", L"Game copied, press Back to boot the game."), 1.f);
|
||||
gprintf("Game copied.\n");
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
slotLight(true);
|
||||
ret = 0;
|
||||
}
|
||||
m.m_thrdWorking = false;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
@ -390,10 +393,10 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
m_btnMgr.hide(m_wbfsBtnBack);
|
||||
m_btnMgr.show(m_wbfsLblMessage);
|
||||
m_btnMgr.setText(m_wbfsLblMessage, L"");
|
||||
char* gameid = (char *)m_cf.getHdr()->hdr.id;
|
||||
cfPos = string(gameid);
|
||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop10", L"Copying [%s] %s..."), (u8*)gameid, (u8*)m_cf.getTitle().toUTF8().c_str()));
|
||||
cfPos = string((char*)m_cf.getHdr()->hdr.id);
|
||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop10", L"Copying [%s] %s..."), (u8*)m_cf.getHdr()->hdr.id, (u8*)m_cf.getTitle().toUTF8().c_str()));
|
||||
done = true;
|
||||
upd_dml = true;
|
||||
m_thrdWorking = true;
|
||||
m_thrdProgress = 0.f;
|
||||
m_thrdMessageAdded = false;
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\source\devicemounter\libwbfs" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="true"></e><e p="Wiiflow\source\network" x="false"></e><e p="Wiiflow\source\channel" x="true"></e><e p="Wiiflow\source\menu" x="true"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\source\cheats" x="true"></e><e p="Wiiflow\portlibs" x="false"></e><e p="Wiiflow\source\config" x="true"></e><e p="Wiiflow\source\devicemounter" x="true"></e><e p="Wiiflow\source\gc" x="false"></e><e p="Wiiflow\source\gecko" x="false"></e><e p="Wiiflow\source\gui" x="true"></e><e p="Wiiflow\source\homebrew" x="true"></e><e p="Wiiflow\source\list" x="true"></e><e p="Wiiflow\source\loader" x="true"></e><e p="Wiiflow\source\memory" x="false"></e><e p="Wiiflow\source\music" x="false"></e><e p="Wiiflow\source\unzip" x="false"></e><e p="Wiiflow\source\wstringEx" x="false"></e><e p="Wiiflow\wii" x="false"></e></ViewState></pd>
|
||||
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\source\devicemounter\libwbfs" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="true"></e><e p="Wiiflow\source\network" x="false"></e><e p="Wiiflow\source\channel" x="true"></e><e p="Wiiflow\source\menu" x="true"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\source\cheats" x="true"></e><e p="Wiiflow\portlibs" x="false"></e><e p="Wiiflow\source\config" x="true"></e><e p="Wiiflow\source\devicemounter" x="true"></e><e p="Wiiflow\source\gc" x="true"></e><e p="Wiiflow\source\gecko" x="false"></e><e p="Wiiflow\source\gui" x="true"></e><e p="Wiiflow\source\homebrew" x="true"></e><e p="Wiiflow\source\list" x="true"></e><e p="Wiiflow\source\loader" x="true"></e><e p="Wiiflow\source\memory" x="false"></e><e p="Wiiflow\source\music" x="false"></e><e p="Wiiflow\source\unzip" x="false"></e><e p="Wiiflow\source\wstringEx" x="false"></e><e p="Wiiflow\wii" x="false"></e></ViewState></pd>
|
Loading…
Reference in New Issue
Block a user