*Fix for ntfs writing

*Cache size reduced which results in a bit slower writing but is more stable
*Fix for the gameinstaller ProgressWindow
*Added NTFS unmount on exit

WARNING:
The USBLoaderGX installer seems to be broken in some places. There are sometimes random freezes or crashes even on fat32. Those arent bad on a fat32 filesystem but can damage the whole partition on ntfs. Using the installer on ntfs is still very risky. You have been warned!
This commit is contained in:
dimok321 2010-02-25 12:08:03 +00:00
parent ce5930f297
commit 0908027ad8
18 changed files with 1233 additions and 1280 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r914</version>
<release_date>201002222228</release_date>
<version>1.0 r915</version>
<release_date>201002222143</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

File diff suppressed because one or more lines are too long

View File

@ -6,15 +6,15 @@
#include <sdcard/wiisd_io.h>
#include <locale.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/sdhc.h"
#include "usbloader/wbfs.h"
#include "libfat/fat.h"
#include "libntfs/ntfs.h"
#include "gecko.h"
//these are the only stable and speed is good
#define CACHE 32
#define CACHE 8
#define SECTORS 64
#define SECTORS_SD 32
@ -195,9 +195,9 @@ s32 MountNTFS(u32 sector)
// }
} else if (wbfsDev == WBFS_DEVICE_SDHC) {
if (sdhc_mode_sd == 0) {
ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
ret = ntfsMount("NTFS", &__io_sdhc, 0, 8, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
} else {
ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS_SD, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
ret = ntfsMount("NTFS", &__io_sdhc, 0, 8, SECTORS_SD, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
}
if (!ret) {
return -5;
@ -239,18 +239,3 @@ void _FAT_mem_free(void *mem)
{
free(mem);
}
void* ntfs_alloc (size_t size)
{
return _FAT_mem_allocate(size);
}
void* ntfs_align (size_t size)
{
return _FAT_mem_align(size);
}
void ntfs_free (void* mem)
{
_FAT_mem_free(mem);
}

View File

@ -111,8 +111,12 @@ void _NTFS_cache_destructor (NTFS_CACHE* cache) {
ntfs_free (cache);
}
static u32 accessCounter = 0;
static inline u64 accessTime(){ return gettime(); }
static u32 accessTime(){
accessCounter++;
return accessCounter;
}
static NTFS_CACHE_ENTRY* _NTFS_cache_getPage(NTFS_CACHE *cache,sec_t sector)
{
@ -305,22 +309,6 @@ bool _NTFS_cache_writeSectors (NTFS_CACHE* cache, sec_t sector, sec_t numSectors
while(numSectors>0)
{
/*
entry = _NTFS_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
secs_to_write = entry->count - sec;
if(secs_to_write>numSectors) secs_to_write = numSectors;
memcpy(entry->cache + (sec*BYTES_PER_READ),src,(secs_to_write*BYTES_PER_READ));
src += (secs_to_write*BYTES_PER_READ);
sector += secs_to_write;
numSectors -= secs_to_write;
entry->dirty = true;
*/
entry = _NTFS_cache_findPage(cache,sector,numSectors);
if(entry!=NULL) {

View File

@ -272,8 +272,7 @@ static s64 ntfs_device_gekko_io_pwrite(struct ntfs_device *dev, const void *buf,
*/
static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s64 count, void *buf)
{
//ntfs_log_trace("dev %p, offset %Li, count %Li\n", dev, offset, count);
ntfs_log_trace("dev %p, offset %d, count %d\n", dev, (u32)offset, (u32)count);
ntfs_log_trace("dev %p, offset %Li, count %Li\n", dev, offset, count);
// Get the device driver descriptor
gekko_fd *fd = DEV_FD(dev);
@ -294,16 +293,19 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
sec_t sec_start = (sec_t) fd->startSector;
sec_t sec_count = 1;
u16 buffer_offset = 0;
u32 buffer_offset = 0;
u8 *buffer = NULL;
// Determine the range of sectors required for this read
if (offset > 0) {
sec_start += (sec_t) floor(offset / fd->sectorSize);
buffer_offset = (sec_t) offset % fd->sectorSize;
sec_start += (sec_t) floor((f64) offset/fd->sectorSize);
buffer_offset = (u32) (offset % fd->sectorSize);
}
if (count > fd->sectorSize) {
sec_count = (sec_t) ceil(count / (float)fd->sectorSize);
sec_count = (sec_t) ceil((f64) count/fd->sectorSize);
if(buffer_offset > 0)
sec_count += 1;
}
// If this read happens to be on the sector boundaries then do the read straight into the destination buffer
@ -319,7 +321,8 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
}
// Else read into a buffer and copy over only what was requested
} else
}
else
{
// Allocate a buffer to hold the read data
@ -353,7 +356,7 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
*/
static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset, s64 count, const void *buf)
{
ntfs_log_trace("dev %p, offset %Li, count %Li\n", dev, offset, count);
ntfs_log_trace("dev %p, offset %lli, count %lli\n", dev, offset, count);
// Get the device driver descriptor
gekko_fd *fd = DEV_FD(dev);
@ -385,11 +388,14 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// Determine the range of sectors required for this write
if (offset > 0) {
sec_start += (sec_t) floor(offset / fd->sectorSize);
buffer_offset = (u32) ceil(offset % fd->sectorSize);
sec_start += (sec_t) floor((f64) offset/fd->sectorSize);
buffer_offset = (u32) (offset % fd->sectorSize);
}
if (count > fd->sectorSize) {
sec_count = (sec_t) ceil((float) count / (float)fd->sectorSize);
sec_count = (sec_t) ceil((f64) count/fd->sectorSize);
if(buffer_offset > 0)
sec_count += 1;
}
// If this write happens to be on the sector boundaries then do the write straight to disc
@ -407,7 +413,7 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
} else {
// Allocate a buffer to hold the write data
buffer = (u8*)ntfs_alloc((sec_count+1) * fd->sectorSize);
buffer = (u8 *) ntfs_alloc(sec_count * fd->sectorSize);
if (!buffer) {
errno = ENOMEM;
return -1;
@ -423,7 +429,7 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
return -1;
}
}
if(count % fd->sectorSize != 0) {
if((count % fd->sectorSize != 0) || buffer_offset > 0) {
if (!ntfs_device_gekko_io_readsectors(dev, sec_start + sec_count-1, 1, buffer + ((sec_count - 1) * fd->sectorSize))) {
ntfs_log_perror("read failure @ sector %d\n", sec_start + sec_count);
ntfs_free(buffer);
@ -446,7 +452,6 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// Free the buffer
ntfs_free(buffer);
}
// Mark the device as dirty (if we actually wrote anything)

View File

@ -1129,8 +1129,6 @@ put_err_out:
*/
void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
{
return;
time_t now;
if (!ni) {

View File

@ -1,6 +1,7 @@
/**
* ntfsfile.c - devoptab file routines for NTFS-based devices.
*
* Copyright (c) 2010 Dimok
* Copyright (c) 2009 Rhys "Shareese" Koedijk
* Copyright (c) 2006 Michael "Chishm" Chisholm
*
@ -63,7 +64,13 @@ void ntfsCloseFile (ntfs_file_state *file)
// Sync the file (and its attributes) to disc
if(file->write)
{
ntfsSync(file->vd, file->ni);
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME | NTFS_UPDATE_CTIME);
}
if (file->read)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME);
// Close the file (if open)
if (file->ni)
@ -311,10 +318,6 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
if (written)
file->ni->flags |= FILE_ATTR_ARCHIVE;
// Update file times (if we actually wrote something)
if (written)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_MCTIME);
// Update the files data length
file->len = file->data_na->data_size;
@ -376,8 +379,6 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
}
//ntfs_log_trace("file->pos: %d \n", (u32)file->pos);
// Update file times (if we actually read something)
if (read)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME);
// Unlock
ntfsUnlock(file->vd);
@ -491,7 +492,7 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
// Update file times (if we actually changed something)
if (file->len != file->data_na->data_size)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_MCTIME);
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_AMCTIME);
// Update the files data length
file->len = file->data_na->data_size;

View File

@ -34,6 +34,7 @@
#include <string.h>
#endif
#include "usbloader/usbstorage2.h"
#include "ntfsinternal.h"
#include "ntfsdir.h"
#include "ntfsfile.h"
@ -42,7 +43,6 @@
#include <sdcard/wiisd_io.h>
#include <sdcard/gcsd.h>
#include "usbloader/usbstorage2.h"
const INTERFACE_ID ntfs_disc_interfaces[] = {
{ "sd", &__io_wiisd },

View File

@ -67,7 +67,7 @@ typedef struct wbfs_disc_info
// callback definition. Return 1 on fatal error (callback is supposed to make retries until no hopes..)
typedef int (*rw_sector_callback_t)(void*fp,u32 lba,u32 count,void*iobuf);
typedef void (*progress_callback_t)(u32 status, u32 total);
typedef void (*progress_callback_t)(s64 status, s64 total);
typedef struct wbfs_s

View File

@ -17,7 +17,6 @@
#include "prompts/ProgressWindow.h"
#include "usbloader/wbfs.h"
#include "usbloader/utils.h"
#include "usbloader/spinner.h"
/*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL;
@ -33,8 +32,8 @@ static f32 progressDone = 0.0;
static bool showTime = false;
static bool showSize = false;
static bool changed = true;
static u32 gameinstalldone = 0;
static u32 gameinstalltotal = 0;
static s64 gameinstalldone = 0;
static s64 gameinstalltotal = -1;
static time_t start;
/*** Extern variables ***/
@ -46,20 +45,22 @@ extern void ResumeGui();
extern void HaltGui();
/****************************************************************************
* ProgressCallback mainly for gameinstallation. Can be used for other C app.
***************************************************************************/
extern "C" void ProgressCallback(s64 done, s64 total)
{
gameinstalldone = done;
gameinstalltotal = total;
}
/****************************************************************************
* GameInstallProgress
* GameInstallValue updating function
***************************************************************************/
static void GameInstallProgress() {
if (gameinstalltotal == 0)
return;
u32 oldinstalldone = gameinstalldone;
GetProgressValue(&gameinstalldone, &gameinstalltotal);
if((oldinstalldone == gameinstalldone) && (gameinstalldone > 0))
static void GameInstallProgress()
{
if (gameinstalltotal <= 0)
return;
if (gameinstalldone > gameinstalltotal)
@ -313,7 +314,7 @@ static void * ProgressThread (void *arg) {
***************************************************************************/
void ProgressStop() {
showProgress = 0;
gameinstalltotal = 0;
gameinstalltotal = -1;
// wait for thread to finish
while (!LWP_ThreadIsSuspended(progressthread))

View File

@ -15,4 +15,14 @@ void ShowProgress (const char *title, const char *msg1, char *dynmsg2,
f32 done, f32 total, bool swSize = false, bool swTime = false);
void ProgressStop();
#ifdef __cplusplus
extern "C" {
#endif
void ProgressCallback(s64 gameinstalldone, s64 gameinstalltotal);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -54,6 +54,7 @@ static void _ExitApp() {
StopGX();
ShutdownAudio();
UnmountNTFS();
SDCard_deInit();
USBDevice_deInit();
mload_set_ES_ioctlv_vector(NULL);

View File

@ -1,17 +0,0 @@
#include <gccore.h>
#include "libwbfs/libwbfs.h"
static u32 done = 0;
static u32 total = 0;
void WBFS_Spinner(u32 d, u32 t)
{
done = d;
total = t;
}
void GetProgressValue(u32 * d, u32 * t)
{
*d = done;
*t = total;
}

View File

@ -1,15 +0,0 @@
#ifndef SPINNER_H_
#define SPINNER_H_
#ifdef __cplusplus
extern "C" {
#endif
void WBFS_Spinner(u32 d, u32 t);
void GetProgressValue(u32 * d, u32 * t);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -273,10 +273,6 @@ s32 USBStorage2_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
/* Write data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buf, len);
/* Free memory */
if (buf != buffer)
iosFree(hid, buf);
return ret;
}

View File

@ -15,7 +15,7 @@
#include "usbloader/disc.h"
#include "fatmounter.h"
#include "wbfs_fat.h"
#include "../spinner.h"
#include "prompts/ProgressWindow.h"
#include "wbfs_rw.h"
#include "gecko.h"
@ -172,7 +172,7 @@ s32 Wbfs_Fat::AddGame(void)
}
wbfs_t *old_hdd = hdd;
hdd = part; // used by spinner
ret = wbfs_add_disc(part, __ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1);
ret = wbfs_add_disc(part, __ReadDVD, NULL, ProgressCallback, part_sel, copy_1_1);
hdd = old_hdd;
wbfs_trim(part);
ClosePart(part);
@ -814,7 +814,7 @@ int Wbfs_Fat::GetFragList(u8 *id)
if (ret) goto out;
CloseDisc(d);
// DEBUG:
frag_list->num = MAX_FRAG-10; // stress test
//frag_list->num = MAX_FRAG-10; // stress test
ret = frag_remap(frag_list, fw, fa);
if (ret) goto out;
} else {

View File

@ -1,5 +1,5 @@
#include "wbfs_wbfs.h"
#include "../spinner.h"
#include "prompts/ProgressWindow.h"
#include "settings/cfg.h"
#include "wbfs_rw.h"
@ -110,7 +110,7 @@ s32 Wbfs_Wbfs::AddGame()
part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS;
}
ret = wbfs_add_disc(hdd, __ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1);
ret = wbfs_add_disc(hdd, __ReadDVD, NULL, ProgressCallback, part_sel, copy_1_1);
if (ret < 0)
return ret;