diff --git a/HBC/META.XML b/HBC/META.XML index d4f6a527..63d174e8 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r914 - 201002222228 + 1.0 r915 + 201002222143 Loads games from USB-devices 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. diff --git a/gui.pnproj b/gui.pnproj index 853fa818..5ab34d26 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/fatmounter.c b/source/fatmounter.c index 55fb3bed..89e68db3 100644 --- a/source/fatmounter.c +++ b/source/fatmounter.c @@ -6,15 +6,15 @@ #include #include -#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 @@ -62,7 +62,7 @@ int USBDevice_Init() { return -1; } // } - + fat_usb_mount = 1; fat_usb_sec = _FAT_startSector; #ifdef DEBUG_FAT @@ -88,7 +88,7 @@ int WBFSDevice_Init(u32 sector) { //right now mounts first FAT-partition //try first mount with cIOS -// if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) { +// if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) { //try now mount with libogc if (!fatMount("WBFS", &__io_usbstorage2, 0, CACHE, SECTORS)) { return -1; @@ -171,7 +171,7 @@ s32 MountNTFS(u32 sector) _FAT_mem_init(); ntfsInit(); // Call ntfs init here, to prevent locale resets - + // ntfsInit resets locale settings // which breaks unicode in console // so we change it back to C-UTF-8 @@ -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; @@ -206,7 +206,7 @@ s32 MountNTFS(u32 sector) fs_ntfs_mount = 1; fs_ntfs_sec = sector; //_FAT_startSector; - + return 0; } @@ -232,25 +232,10 @@ void* _FAT_mem_allocate(size_t size) void* _FAT_mem_align(size_t size) { - return memalign(32, size); + return memalign(32, size); } 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); -} diff --git a/source/libntfs/cache.c b/source/libntfs/cache.c index 0fe46543..6455b1f8 100644 --- a/source/libntfs/cache.c +++ b/source/libntfs/cache.c @@ -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) { diff --git a/source/libntfs/gekko_io.c b/source/libntfs/gekko_io.c index 61db831e..c03dec93 100644 --- a/source/libntfs/gekko_io.c +++ b/source/libntfs/gekko_io.c @@ -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) diff --git a/source/libntfs/inode.c b/source/libntfs/inode.c index 924e3bd5..f6398901 100644 --- a/source/libntfs/inode.c +++ b/source/libntfs/inode.c @@ -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) { diff --git a/source/libntfs/ntfsdir.c b/source/libntfs/ntfsdir.c index 0723e35a..71828cc4 100644 --- a/source/libntfs/ntfsdir.c +++ b/source/libntfs/ntfsdir.c @@ -328,12 +328,12 @@ int ntfs_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) // Zero out the stat buffer memset(buf, 0, sizeof(struct statvfs)); - if(ntfs_volume_get_free_space(vd->vol) < 0) - { - ntfsUnlock(vd); - return -1; - } - + if(ntfs_volume_get_free_space(vd->vol) < 0) + { + ntfsUnlock(vd); + return -1; + } + // File system block size buf->f_bsize = vd->vol->cluster_size; diff --git a/source/libntfs/ntfsfile.c b/source/libntfs/ntfsfile.c index beeb7cf4..262fb877 100644 --- a/source/libntfs/ntfsfile.c +++ b/source/libntfs/ntfsfile.c @@ -1,12 +1,13 @@ /** * 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 * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, or + * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program/include file is distributed in the hope that it will be @@ -52,23 +53,29 @@ void ntfsCloseFile (ntfs_file_state *file) // Special case fix ups for compressed and/or encrypted files if (file->compressed) - ntfs_attr_pclose(file->data_na); -#ifdef HAVE_SETXATTR + ntfs_attr_pclose(file->data_na); +#ifdef HAVE_SETXATTR if (file->encrypted) ntfs_efs_fixup_attribute(NULL, file->data_na); -#endif +#endif // Close the file data attribute (if open) if (file->data_na) ntfs_attr_close(file->data_na); - + // 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) ntfsCloseEntry(file->vd, file->ni); - + // Reset the file state file->ni = NULL; file->data_na = NULL; @@ -87,7 +94,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags ntfs_log_trace("fileStruct %p, path %s, flags %i, mode %i\n", fileStruct, path, flags, mode); ntfs_file_state* file = STATE(fileStruct); - + // Get the volume descriptor for this path file->vd = ntfsGetVolume(path); if (!file->vd) { @@ -117,7 +124,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags ntfsUnlock(file->vd); return -1; } - + // Try and find the file and (if found) ensure that it is not a directory file->ni = ntfsOpenEntry(file->vd, path); if (file->ni && (file->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { @@ -126,10 +133,10 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags r->_errno = EISDIR; return -1; } - + // Are we creating this file? if (flags & O_CREAT) { - + // The file SHOULD NOT already exist if (file->ni) { ntfsCloseEntry(file->vd, file->ni); @@ -137,7 +144,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags r->_errno = EEXIST; return -1; } - + // Create the file file->ni = ntfsCreate(file->vd, path, S_IFREG, NULL); if (!file->ni) { @@ -146,14 +153,14 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags } } - + // Sanity check, the file should be open by now if (!file->ni) { ntfsUnlock(file->vd); r->_errno = ENOENT; return -1; } - + // Open the files data attribute file->data_na = ntfs_attr_open(file->ni, AT_DATA, AT_UNNAMED, 0); if(!file->data_na) { @@ -165,7 +172,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags // Determine if this files data is compressed and/or encrypted file->compressed = NAttrCompressed(file->data_na) || (file->ni->flags & FILE_ATTR_COMPRESSED); file->encrypted = NAttrEncrypted(file->data_na) || (file->ni->flags & FILE_ATTR_ENCRYPTED); - + // We cannot read/write encrypted files if (file->encrypted) { ntfs_attr_close(file->data_na); @@ -174,7 +181,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags r->_errno = EACCES; return -1; } - + // Make sure we aren't trying to write to a read-only file if ((file->ni->flags & FILE_ATTR_READONLY) && file->write) { ntfs_attr_close(file->data_na); @@ -183,7 +190,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags r->_errno = EROFS; return -1; } - + // Truncate the file if requested if ((flags & O_TRUNC) && file->write) { if (ntfs_attr_truncate(file->data_na, 0)) { @@ -194,16 +201,16 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags return -1; } } - + // Set the files current position and length file->pos = 0; file->len = file->data_na->data_size; - + ntfs_log_trace("file->len %d\n", file->len); // Update file times ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME); - + // Insert the file into the double-linked FILO list of open files if (file->vd->firstOpenFile) { file->nextOpenFile = file->vd->firstOpenFile; @@ -214,31 +221,31 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags file->prevOpenFile = NULL; file->vd->firstOpenFile = file; file->vd->openFileCount++; - + // Unlock ntfsUnlock(file->vd); - + return (int)fileStruct; } int ntfs_close_r (struct _reent *r, int fd) { ntfs_log_trace("fd %p\n", fd); - + ntfs_file_state* file = STATE(fd); - + // Sanity check if (!file || !file->vd) { r->_errno = EBADF; return -1; } - + // Lock ntfsLock(file->vd); // Close the file ntfsCloseFile(file); - + // Remove the file from the double-linked FILO list of open files file->vd->openFileCount--; if (file->nextOpenFile) @@ -250,45 +257,45 @@ int ntfs_close_r (struct _reent *r, int fd) // Unlock ntfsUnlock(file->vd); - + return 0; } ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len) { ntfs_log_trace("fd %p, ptr %p, len %Li\n", fd, ptr, len); - + ntfs_file_state* file = STATE(fd); ssize_t written = 0; off_t old_pos = 0; - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Short circuit cases where we don't actually have to do anything if (!ptr || len <= 0) { return 0; } - + // Lock ntfsLock(file->vd); - + // Check that we are allowed to write to this file if (!file->write) { ntfsUnlock(file->vd); r->_errno = EACCES; return -1; } - + // If we are in append mode, backup the current position and move to the end of the file if (file->append) { old_pos = file->pos; file->pos = file->len; } - + // Write to the files data atrribute while (len) { ssize_t ret = ntfs_attr_pwrite(file->data_na, file->pos, len, ptr); @@ -301,57 +308,53 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len) file->pos += ret; written += ret; } - + // If we are in append mode, restore the current position to were it was prior to this write if (file->append) { file->pos = old_pos; } - + // Mark the file for archiving (if we actually wrote something) 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; - - // Unlock + + // Unlock ntfsUnlock(file->vd); - + return written; } ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len) { ntfs_log_trace("fd %p, ptr %p, len %Li\n", fd, ptr, len); - + ntfs_file_state* file = STATE(fd); ssize_t read = 0; - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Short circuit cases where we don't actually have to do anything if (!ptr || len <= 0) { return 0; } - + // Lock ntfsLock(file->vd); - + // Check that we are allowed to read from this file if (!file->read) { ntfsUnlock(file->vd); r->_errno = EACCES; return -1; } - + // Don't read past the end of file if (file->pos + len > file->len) { r->_errno = EOVERFLOW; @@ -360,7 +363,7 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len) } ntfs_log_trace("file->pos:%d, len:%d, file->len:%d \n", (u32)file->pos, (u32)len, (u32)file->len); - + // Read from the files data attribute while (len) { ssize_t ret = ntfs_attr_pread(file->data_na, file->pos, len, ptr); @@ -376,41 +379,39 @@ 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 + + // Unlock ntfsUnlock(file->vd); - + return read; } off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir) { ntfs_log_trace("fd %p, pos %Li, dir %i\n", fd, pos, dir); - + ntfs_file_state* file = STATE(fd); off_t position = 0; - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Lock ntfsLock(file->vd); - + // Set the files current position switch(dir) { case SEEK_SET: position = file->pos = MIN(MAX(pos, 0), file->len); break; case SEEK_CUR: position = file->pos = MIN(MAX(file->pos + pos, 0), file->len); break; case SEEK_END: position = file->pos = MIN(MAX(file->len + pos, 0), file->len); break; } - - // Unlock + + // Unlock ntfsUnlock(file->vd); - + return position; } int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st) @@ -419,47 +420,47 @@ int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st) ntfs_file_state* file = STATE(fd); int ret = 0; - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Short circuit cases were we don't actually have to do anything if (!st) return 0; - + // Get the file stats ret = ntfsStat(file->vd, file->ni, st); if (ret) r->_errno = errno; - + return ret; } int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len) { ntfs_log_trace("fd %p, len %Li\n", fd, len); - + ntfs_file_state* file = STATE(fd); - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Lock ntfsLock(file->vd); - + // Check that we are allowed to write to this file if (!file->write) { ntfsUnlock(file->vd); r->_errno = EACCES; return -1; } - + // For compressed files, only deleting and expanding contents are implemented if (file->compressed && len > 0 && @@ -488,20 +489,20 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len) // Mark the file for archiving (if we actually changed something) if (file->len != file->data_na->data_size) file->ni->flags |= FILE_ATTR_ARCHIVE; - + // 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; - // Sync the file (and its attributes) to disc + // Sync the file (and its attributes) to disc ntfsSync(file->vd, file->ni); // Unlock ntfsUnlock(file->vd); - + return 0; } @@ -511,23 +512,23 @@ int ntfs_fsync_r (struct _reent *r, int fd) ntfs_file_state* file = STATE(fd); int ret = 0; - + // Sanity check if (!file || !file->vd || !file->ni || !file->data_na) { r->_errno = EINVAL; return -1; } - + // Lock ntfsLock(file->vd); - + // Sync the file (and its attributes) to disc ret = ntfsSync(file->vd, file->ni); if (ret) r->_errno = errno; - + // Unlock ntfsUnlock(file->vd); - + return ret; } diff --git a/source/libntfs/ntfsinternal.c b/source/libntfs/ntfsinternal.c index fb5aa096..b4d39491 100644 --- a/source/libntfs/ntfsinternal.c +++ b/source/libntfs/ntfsinternal.c @@ -34,6 +34,7 @@ #include #endif +#include "usbloader/usbstorage2.h" #include "ntfsinternal.h" #include "ntfsdir.h" #include "ntfsfile.h" @@ -42,7 +43,6 @@ #include #include -#include "usbloader/usbstorage2.h" const INTERFACE_ID ntfs_disc_interfaces[] = { { "sd", &__io_wiisd }, diff --git a/source/libwbfs/libwbfs.h b/source/libwbfs/libwbfs.h index b4a9f132..0bdc502a 100644 --- a/source/libwbfs/libwbfs.h +++ b/source/libwbfs/libwbfs.h @@ -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 diff --git a/source/prompts/ProgressWindow.cpp b/source/prompts/ProgressWindow.cpp index 3dfb0db4..9a1610a9 100644 --- a/source/prompts/ProgressWindow.cpp +++ b/source/prompts/ProgressWindow.cpp @@ -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)) diff --git a/source/prompts/ProgressWindow.h b/source/prompts/ProgressWindow.h index a0df8864..204bdfc7 100644 --- a/source/prompts/ProgressWindow.h +++ b/source/prompts/ProgressWindow.h @@ -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 diff --git a/source/sys.cpp b/source/sys.cpp index eb56c0ce..68abdfc8 100644 --- a/source/sys.cpp +++ b/source/sys.cpp @@ -54,6 +54,7 @@ static void _ExitApp() { StopGX(); ShutdownAudio(); + UnmountNTFS(); SDCard_deInit(); USBDevice_deInit(); mload_set_ES_ioctlv_vector(NULL); @@ -68,23 +69,23 @@ void Sys_Reboot(void) { int Sys_ChangeIos(int ios) { s32 prevIos = IOS_GetVersion(); - + SDCard_deInit(); USBDevice_deInit(); - + WPAD_Flush(0); WPAD_Disconnect(0); WPAD_Shutdown(); - + WDVD_Close(); - + USBStorage2_Deinit(); - + s32 ret = IOS_ReloadIOSsafe(ios); if (ret < 0) { ios = prevIos; } - + SDCard_Init(); if (ios == 222 || ios == 223) { @@ -99,13 +100,13 @@ int Sys_ChangeIos(int ios) { WBFS_Init(WBFS_DEVICE_USB); Disc_Init(); - + if (Sys_IsHermes()) { WBFS_OpenNamed((char *) &game_partition); - } else { + } else { WBFS_Open(); } - + return ret; } @@ -228,34 +229,34 @@ s32 ios250rev = -69; s32 IOS_ReloadIOSsafe(int ios) { if (ios==222) - { + { if (ios222rev == -69) ios222rev = getIOSrev(0x00000001000000dell); - + if (ios222rev > 0 && (ios222rev != 4 && ios222rev != 5))return -2; } else if (ios==223) - { + { if (ios223rev == -69) ios223rev = getIOSrev(0x00000001000000dfll); - + if (ios223rev > 0 && (ios223rev != 4 && ios223rev != 5))return -2; } else if (ios==249) - { + { if (ios249rev == -69) - ios249rev = getIOSrev(0x00000001000000f9ll); - + ios249rev = getIOSrev(0x00000001000000f9ll); + if (ios249rev >= 0 && !(ios249rev>=9 && ios249rev<65280))return -2; } else if (ios==250) - { + { if (ios250rev == -69) ios250rev = getIOSrev(0x00000001000000fall); - + if (ios250rev >= 0 && !(ios250rev>=9 && ios250rev<65280))return -2; } - + s32 r = IOS_ReloadIOS(ios); if (r >= 0) { WII_Initialize(); diff --git a/source/usbloader/spinner.c b/source/usbloader/spinner.c deleted file mode 100644 index 14d22c6d..00000000 --- a/source/usbloader/spinner.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#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; -} diff --git a/source/usbloader/spinner.h b/source/usbloader/spinner.h deleted file mode 100644 index dc0e9c3a..00000000 --- a/source/usbloader/spinner.h +++ /dev/null @@ -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 diff --git a/source/usbloader/usbstorage2.c b/source/usbloader/usbstorage2.c index b0567125..be167bb7 100644 --- a/source/usbloader/usbstorage2.c +++ b/source/usbloader/usbstorage2.c @@ -3,7 +3,7 @@ usbstorage_starlet.c -- USB mass storage support, inside starlet Copyright (C) 2009 Kwiirk -If this driver is linked before libogc, this will replace the original +If this driver is linked before libogc, this will replace the original usbstorage driver by svpe from libogc This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -60,7 +60,7 @@ static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2"; static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc"; static char fsoff[] ATTRIBUTE_ALIGN(32) = "/dev/usb2/OFF"; - + static s32 hid = -1, fd = -1; static u32 sector_size; static int mounted=0; @@ -152,13 +152,13 @@ s32 USBStorage2_Init(void) if (hid < 0) { hid = iosCreateHeap(UMS_HEAPSIZE); if (hid < 0) - return IPC_ENOMEM; + return IPC_ENOMEM; } /* Open USB device */ fd = IOS_Open(fs, 0); if (fd < 0) fd = IOS_Open(fs2, 0); - + if (fd < 0) return fd; @@ -194,7 +194,7 @@ err: IOS_Close(fd); fd = -1; } - + return ret; } @@ -257,7 +257,7 @@ s32 USBStorage2_WriteSectors(u32 sector, u32 numSectors, const void *buffer) if (fd < 0) return fd; if(!mem2_ptr) mem2_ptr=SYS_AllocArena2MemLo(2048*256,32); - + /* MEM1 buffer */ if (!__USBStorage2_isMEM2Buffer(buffer)) { @@ -273,17 +273,13 @@ 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; } static bool __usbstorage_Startup(void) { - - + + return USBStorage2_Init()==0; } diff --git a/source/usbloader/wbfs/wbfs_fat.cpp b/source/usbloader/wbfs/wbfs_fat.cpp index 072ebefd..be539ebe 100644 --- a/source/usbloader/wbfs/wbfs_fat.cpp +++ b/source/usbloader/wbfs/wbfs_fat.cpp @@ -1,847 +1,847 @@ -// WBFS FAT by oggzee - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "settings/cfg.h" -#include "usbloader/disc.h" -#include "fatmounter.h" -#include "wbfs_fat.h" -#include "../spinner.h" -#include "wbfs_rw.h" - -#include "gecko.h" - -#define MAX_FAT_PATH 1024 -#define TITLE_LEN 64 - -using namespace std; - -char Wbfs_Fat::wbfs_fs_drive[16]; -char Wbfs_Fat::wbfs_fat_dir[16] = "/wbfs"; -char Wbfs_Fat::invalid_path[] = "/\\:|<>?*\"'"; -struct discHdr *Wbfs_Fat::fat_hdr_list = NULL; -u32 Wbfs_Fat::fat_hdr_count = 0; - -extern "C" -{ - int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data); - extern FragList *frag_list; -} - -u32 Wbfs_Fat::fat_sector_size = 512; - -Wbfs_Fat::Wbfs_Fat(u32 device, u32 lba, u32 size) : Wbfs(device, lba, size) -{ -} - -s32 Wbfs_Fat::Open() -{ - if (device == WBFS_DEVICE_USB && lba == fat_usb_sec) { - strcpy(wbfs_fs_drive, "USB:"); - } else if (device == WBFS_DEVICE_SDHC && lba == fat_sd_sec) { - strcpy(wbfs_fs_drive, "SD:"); - } else { - if (WBFSDevice_Init(lba)) return -1; - strcpy(wbfs_fs_drive, "WBFS:"); - } - - return 0; -} - -wbfs_disc_t* Wbfs_Fat::OpenDisc(u8 *discid) -{ - char fname[MAX_FAT_PATH]; - - // wbfs 'partition' file - if (!FindFilename(discid, fname, sizeof(fname)) ) return NULL; - - if (strcasecmp(strrchr(fname,'.'), ".iso") == 0) { - // .iso file - // create a fake wbfs_disc - int fd; - fd = open(fname, O_RDONLY); - if (fd == -1) return NULL; - wbfs_disc_t *iso_file = (wbfs_disc_t *)calloc(sizeof(wbfs_disc_t),1); - if (iso_file == NULL) return NULL; - // mark with a special wbfs_part - wbfs_iso_file.wbfs_sec_sz = 512; - iso_file->p = &wbfs_iso_file; - iso_file->header = (wbfs_disc_info_t*)fd; - return iso_file; - } - - wbfs_t *part = OpenPart(fname); - if (!part) return NULL; - return wbfs_open_disc(part, discid); -} - -void Wbfs_Fat::CloseDisc(wbfs_disc_t* disc) -{ - if (!disc) return; - wbfs_t *part = disc->p; - - // is this really a .iso file? - if (part == &wbfs_iso_file) { - close((int)disc->header); - free(disc); - return; - } - - wbfs_close_disc(disc); - ClosePart(part); - return; -} - -s32 Wbfs_Fat::GetCount(u32 *count) -{ - *count = 0; - GetHeadersCount(); - if (fat_hdr_count && fat_hdr_list) { - // for compacter mem - move up as it will be freed later - int size = fat_hdr_count * sizeof(struct discHdr); - struct discHdr *buf = (struct discHdr *) malloc(size); - if (buf) { - memcpy(buf, fat_hdr_list, size); - SAFE_FREE(fat_hdr_list); - fat_hdr_list = buf; - } - } - *count = fat_hdr_count; - return 0; -} - -s32 Wbfs_Fat::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) -{ - u32 i; - if (len > sizeof(struct discHdr)) { - len = sizeof(struct discHdr); - } -#ifdef DEBUG_WBFS - gprintf("\n\tGetHeaders"); -#endif - for (i=0; iwii_sec_sz; - - partition_selector_t part_sel; - if (Settings.fullcopy) { - part_sel = ALL_PARTITIONS; - } else { - part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; - } - return wbfs_estimate_disc(part, __ReadDVD, NULL, part_sel); -} - -// TITLE [GAMEID] -bool Wbfs_Fat::CheckLayoutB(char *fname, int len, u8* id, char *fname_title) -{ - if (len <= 8) return false; - if (fname[len-8] != '[' || fname[len-1] != ']') return false; - if (!is_gameid(&fname[len-7])) return false; - strncpy(fname_title, fname, TITLE_LEN); - // cut at '[' - fname_title[len-8] = 0; - int n = strlen(fname_title); - if (n == 0) return false; - // cut trailing _ or ' ' - if (fname_title[n - 1] == ' ' || fname_title[n - 1] == '_' ) { - fname_title[n - 1] = 0; - } - if (strlen(fname_title) == 0) return false; - if (id) { - memcpy(id, &fname[len-7], 6); - id[6] = 0; - } - return true; -} - -s32 Wbfs_Fat::GetHeadersCount() -{ - char path[MAX_FAT_PATH]; - char fname[MAX_FAT_PATH]; - char fpath[MAX_FAT_PATH]; - struct discHdr tmpHdr; - struct stat st; - wbfs_t *part = NULL; - u8 id[8]; - int ret; - char *p; - u32 size; - int is_dir; - int len; - char dir_title[65]; - char fname_title[TITLE_LEN]; - char *title; - DIR_ITER *dir_iter; - - //dbg_time1(); - - SAFE_FREE(fat_hdr_list); - fat_hdr_count = 0; - - strcpy(path, wbfs_fs_drive); - strcat(path, wbfs_fat_dir); - - dir_iter = diropen(path); - if (!dir_iter) return 0; - - dir_iter = diropen(path); - if (!dir_iter) return 0; - - while (dirnext(dir_iter, fname, &st) == 0) { - //printf("found: %s\n", fname); Wpad_WaitButtonsCommon(); - if ((char)fname[0] == '.') continue; - len = strlen(fname); - if (len < 8) continue; // "GAMEID_x" - - memcpy(id, fname, 6); - id[6] = 0; - *fname_title = 0; - - is_dir = S_ISDIR(st.st_mode); - //printf("mode: %d %d %x\n", is_dir, st.st_mode, st.st_mode); - if (is_dir) { - int lay_a = 0; - int lay_b = 0; - if (fname[6] == '_' && is_gameid((char*)id)) { - // usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs - lay_a = 1; - } - if (CheckLayoutB(fname, len, NULL, fname_title)) { - // usb:/wbfs/TITLE[GAMEID]/GAMEID.wbfs - lay_b = 1; - } - if (!lay_a && !lay_b) continue; - if (lay_a) { - strncpy(dir_title, &fname[7], sizeof(dir_title)); - } else { - try_lay_b: - if (!CheckLayoutB(fname, len, id, fname_title)) continue; - } - snprintf(fpath, sizeof(fpath), "%s/%s/%s.wbfs", path, fname, id); - //printf("path2: %s\n", fpath); - // if more than 50 games, skip second stat to improve speed - // but if ambiguous layout check anyway - if (fat_hdr_count < 50 || (lay_a && lay_b)) { - if (stat(fpath, &st) == -1) { - //printf("missing: %s\n", fpath); - // try .iso - strcpy(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso - if (stat(fpath, &st) == -1) { - //printf("missing: %s\n", fpath); - // try .ciso - strcpy(strrchr(fpath, '.'), ".ciso"); // replace .iso with .ciso - if (stat(fpath, &st) == -1 ) { - if (lay_a && lay_b == 1) { - // mark lay_b so that the stat check is still done, - // but lay_b is not re-tried again - lay_b = 2; - // retry with layout b - goto try_lay_b; - } - continue; - } - } - } - } else { - st.st_size = 1024*1024; - } - } else { - // usb:/wbfs/GAMEID.wbfs - // or usb:/wbfs/GAMEID.iso - // or usb:/wbfs/GAMEID.ciso - p = strrchr(fname, '.'); - if (!p) continue; - if ( (strcasecmp(p, ".wbfs") != 0) - && (strcasecmp(p, ".iso") != 0) - && (strcasecmp(p, ".ciso") != 0) ) continue; - int n = p - fname; // length withouth .wbfs - if (n != 6) { - // TITLE [GAMEID].wbfs - if (!CheckLayoutB(fname, n, id, fname_title)) continue; - } - snprintf(fpath, sizeof(fpath), "%s/%s", path, fname); - } - - //printf("found: %s %d MB\n", fpath, (int)(st.st_size/1024/1024)); - // size must be at least 1MB to be considered a valid wbfs file - if (st.st_size < 1024*1024) continue; - // if we have titles.txt entry use that - title = cfg_get_title(id); - // if no titles.txt get title from dir or file name - if (!title && *fname_title) { - title = fname_title; - } - if (title) { - memset(&tmpHdr, 0, sizeof(tmpHdr)); - memcpy(tmpHdr.id, id, 6); - strncpy(tmpHdr.title, title, sizeof(tmpHdr.title)-1); - tmpHdr.magic = 0x5D1C9EA3; - goto add_hdr; - } - - // else read it from file directly - if (strcasecmp(strrchr(fpath,'.'), ".wbfs") == 0) { - // wbfs file directly - FILE *fp = fopen(fpath, "rb"); - if (fp != NULL) { - fseek(fp, 512, SEEK_SET); - fread(&tmpHdr, sizeof(struct discHdr), 1, fp); - fclose(fp); - tmpHdr.is_ciso = 0; - if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { - goto add_hdr; - } - } - // no title found, read it from wbfs file - // but this is a little bit slower - // open 'partition' file - part = OpenPart(fpath); - if (!part) { - continue; - } - // Get header - ret = wbfs_get_disc_info(part, 0, (u8*)&tmpHdr, - sizeof(struct discHdr), &size); - ClosePart(part); - if (ret == 0) { - goto add_hdr; - } - } else if (strcasecmp(strrchr(fpath,'.'), ".iso") == 0) { - // iso file - FILE *fp = fopen(fpath, "rb"); - if (fp != NULL) { - fseek(fp, 0, SEEK_SET); - fread(&tmpHdr, sizeof(struct discHdr), 1, fp); - fclose(fp); - tmpHdr.is_ciso = 0; - if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { - goto add_hdr; - } - } - } else if (strcasecmp(strrchr(fpath,'.'), ".ciso") == 0) { - // ciso file - FILE *fp = fopen(fpath, "rb"); - if (fp != NULL) { - fseek(fp, 0x8000, SEEK_SET); - fread(&tmpHdr, sizeof(struct discHdr), 1, fp); - fclose(fp); - tmpHdr.is_ciso = 1; - if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { - goto add_hdr; - } - } - } - // fail: - continue; - - // succes: add tmpHdr to list: - add_hdr: - memset(&st, 0, sizeof(st)); - //printf("added: %.6s %.20s\n", tmpHdr.id, tmpHdr.title); Wpad_WaitButtons(); - fat_hdr_count++; - fat_hdr_list = (struct discHdr *) realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr)); - memcpy(&fat_hdr_list[fat_hdr_count-1], &tmpHdr, sizeof(struct discHdr)); - } - dirclose(dir_iter); - //dbg_time2("\nFAT_GetCount"); Wpad_WaitButtonsCommon(); - - return 0; -} - -int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len) -{ - struct stat st; - // look for direct .wbfs file - Filename(id, fname, len, NULL); - if (stat(fname, &st) == 0) return 1; - // look for direct .iso file - strcpy(strrchr(fname, '.'), ".iso"); // replace .wbfs with .iso - if (stat(fname, &st) == 0) return 1; - // look for direct .ciso file - strcpy(strrchr(fname, '.'), ".ciso"); // replace .iso with .ciso - if (stat(fname, &st) == 0) return 1; - // direct file not found, check subdirs - *fname = 0; - DIR_ITER *dir_iter; - char path[MAX_FAT_PATH]; - char name[MAX_FAT_PATH]; - strcpy(path, wbfs_fs_drive); - strcat(path, wbfs_fat_dir); - dir_iter = diropen(path); - //printf("dir: %s %p\n", path, dir); Wpad_WaitButtons(); - if (!dir_iter) { - return 0; - } - while (dirnext(dir_iter, name, &st) == 0) { - //dbg_printf("name:%s\n", name); - if (name[0] == '.') continue; - int n = strlen(name); - if (n < 8) continue; - if (S_ISDIR(st.st_mode)) { - if (name[6] == '_') { - // GAMEID_TITLE - if (strncmp(name, (char*)id, 6) != 0) goto try_alter; - } else { - try_alter: - // TITLE [GAMEID] - if (name[n-8] != '[' || name[n-1] != ']') continue; - if (strncmp(&name[n-7], (char*)id, 6) != 0) continue; - } - // look for .wbfs file - snprintf(fname, len, "%s/%s/%.6s.wbfs", path, name, id); - if (stat(fname, &st) == 0) break; - // look for .iso file - snprintf(fname, len, "%s/%s/%.6s.iso", path, name, id); - if (stat(fname, &st) == 0) break; - // look for .ciso file - snprintf(fname, len, "%s/%s/%.6s.ciso", path, name, id); - } else { - // TITLE [GAMEID].wbfs - char fn_title[TITLE_LEN]; - u8 fn_id[8]; - char *p = strrchr(name, '.'); - if (!p) continue; - if ( (strcasecmp(p, ".wbfs") != 0) - && (strcasecmp(p, ".iso") != 0) - && (strcasecmp(p, ".ciso") != 0) ) continue; - int n = p - name; // length withouth .wbfs - if (!CheckLayoutB(name, n, fn_id, fn_title)) continue; - if (strncmp((char*)fn_id, (char*)id, 6) != 0) continue; - snprintf(fname, len, "%s/%s", path, name); - } - if (stat(fname, &st) == 0) break; - *fname = 0; - } - dirclose(dir_iter); - if (*fname) { - // found - //printf("found:%s\n", fname); - return 2; - } - // not found - return 0; -} - -wbfs_t* Wbfs_Fat::OpenPart(char *fname) -{ - wbfs_t *part = NULL; - int ret; - - // wbfs 'partition' file - ret = split_open(&split, fname); - if (ret) return NULL; - part = wbfs_open_partition( - split_read_sector, - nop_rw_sector, //readonly //split_write_sector, - &split, fat_sector_size, split.total_sec, 0, 0); - if (!part) { - split_close(&split); - } - return part; -} - -void Wbfs_Fat::ClosePart(wbfs_t* part) -{ - if (!part) return; - split_info_t *s = (split_info_t*)part->callback_data; - wbfs_close(part); - if (s) split_close(s); -} - -void Wbfs_Fat::Filename(u8 *id, char *fname, int len, char *path) -{ - if (path == NULL) { - snprintf(fname, len, "%s%s/%.6s.wbfs", wbfs_fs_drive, wbfs_fat_dir, id); - } else { - snprintf(fname, len, "%s/%.6s.wbfs", path, id); - } -} - -void Wbfs_Fat::GetDir(struct discHdr *header, char *path) -{ - strcpy(path, wbfs_fs_drive); - strcat(path, wbfs_fat_dir); - if (Settings.FatInstallToDir) { - strcat(path, "/"); - int layout = 0; - if (Settings.FatInstallToDir == 2) layout = 1; - mk_gameid_title(header, path + strlen(path), 0, layout); - } -} - -wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path) -{ - char fname[MAX_FAT_PATH]; - wbfs_t *part = NULL; - u64 size = (u64)143432*2*0x8000ULL; - u32 n_sector = size / 512; - int ret; - - //printf("CREATE PART %s %lld %d\n", id, size, n_sector); - snprintf(fname, sizeof(fname), "%s%s", wbfs_fs_drive, wbfs_fat_dir); - mkdir(fname, 0777); // base usb:/wbfs - mkdir(path, 0777); // game subdir - Filename(id, fname, sizeof(fname), path); - printf("Writing to %s\n", fname); - ret = split_create(&split, fname, OPT_split_size, size, true); - if (ret) return NULL; - - // force create first file - u32 scnt = 0; - int fd = split_get_file(&split, 0, &scnt, 0); - if (fd<0) { - printf("ERROR creating file\n"); - sleep(2); - split_close(&split); - return NULL; - } - - part = wbfs_open_partition( - split_read_sector, - split_write_sector, - &split, fat_sector_size, n_sector, 0, 1); - if (!part) { - split_close(&split); - } - return part; -} - -void Wbfs_Fat::mk_title_txt(struct discHdr *header, char *path) -{ - char fname[MAX_FAT_PATH]; - FILE *f; - - strcpy(fname, path); - strcat(fname, "/"); - mk_gameid_title(header, fname+strlen(fname), 1, 0); - strcat(fname, ".txt"); - - f = fopen(fname, "wb"); - if (!f) return; - fprintf(f, "%.6s = %.64s\n", header->id, get_title(header)); - fclose(f); - printf("Info file: %s\n", fname); -} - -void Wbfs_Fat::mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout) -{ - int i, len; - char title[65]; - char id[8]; - - memcpy(name, header->id, 6); - name[6] = 0; - strncpy(title, get_title(header), sizeof(title)); - title_filename(title); - - if (layout == 0) { - sprintf(name, "%s_%s", id, title); - } else { - sprintf(name, "%s [%s]", title, id); - } - - // replace space with '_' - if (re_space) { - len = strlen(name); - for (i = 0; i < len; i++) { - if(name[i]==' ') name[i] = '_'; - } - } -} - -void Wbfs_Fat::title_filename(char *title) -{ - int i, len; - // trim leading space - len = strlen(title); - while (*title == ' ') { - memmove(title, title+1, len); - len--; - } - // trim trailing space - not allowed on windows directories - while (len && title[len-1] == ' ') { - title[len-1] = 0; - len--; - } - // replace silly chars with '_' - for (i=0; i 0) { - fname[strlen(fname)-1] = '0' + i; - if (stat(fname, &st) == -1) break; - } - strcpy(fname1, fname); - if ((ret = GetFragList((char *) &fname, &_frag_append, fs))) - { - ret_val = ret; - goto out; - } - frag_concat(fa, fs); - } - frag_list = (FragList *) malloc(sizeof(FragList)); - frag_init(frag_list, MAX_FRAG); - if (is_wbfs) { - // if wbfs file format, remap. - //printf("=====\n"); - wbfs_disc_t *d = OpenDisc(id); - if (!d) goto out; - frag_init(fw, MAX_FRAG); - ret = wbfs_get_fragments(d, &_frag_append, fw); - if (ret) goto out; - CloseDisc(d); - // DEBUG: - frag_list->num = MAX_FRAG-10; // stress test - ret = frag_remap(frag_list, fw, fa); - if (ret) goto out; - } else { - // .iso does not need remap just copy - //printf("fa:\n"); - memcpy(frag_list, fa, sizeof(FragList)); - } - - ret_val = 0; - -out: - if (ret_val) { - // error - SAFE_FREE(frag_list); - } - SAFE_FREE(fs); - SAFE_FREE(fa); - SAFE_FREE(fw); - return ret_val; -} - -int Wbfs_Fat::GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs) -{ - return _FAT_get_fragments(filename, append_fragment, fs); -} - -bool Wbfs_Fat::ShowFreeSpace(void) -{ - return false; -} +// WBFS FAT by oggzee + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "settings/cfg.h" +#include "usbloader/disc.h" +#include "fatmounter.h" +#include "wbfs_fat.h" +#include "prompts/ProgressWindow.h" +#include "wbfs_rw.h" + +#include "gecko.h" + +#define MAX_FAT_PATH 1024 +#define TITLE_LEN 64 + +using namespace std; + +char Wbfs_Fat::wbfs_fs_drive[16]; +char Wbfs_Fat::wbfs_fat_dir[16] = "/wbfs"; +char Wbfs_Fat::invalid_path[] = "/\\:|<>?*\"'"; +struct discHdr *Wbfs_Fat::fat_hdr_list = NULL; +u32 Wbfs_Fat::fat_hdr_count = 0; + +extern "C" +{ + int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data); + extern FragList *frag_list; +} + +u32 Wbfs_Fat::fat_sector_size = 512; + +Wbfs_Fat::Wbfs_Fat(u32 device, u32 lba, u32 size) : Wbfs(device, lba, size) +{ +} + +s32 Wbfs_Fat::Open() +{ + if (device == WBFS_DEVICE_USB && lba == fat_usb_sec) { + strcpy(wbfs_fs_drive, "USB:"); + } else if (device == WBFS_DEVICE_SDHC && lba == fat_sd_sec) { + strcpy(wbfs_fs_drive, "SD:"); + } else { + if (WBFSDevice_Init(lba)) return -1; + strcpy(wbfs_fs_drive, "WBFS:"); + } + + return 0; +} + +wbfs_disc_t* Wbfs_Fat::OpenDisc(u8 *discid) +{ + char fname[MAX_FAT_PATH]; + + // wbfs 'partition' file + if (!FindFilename(discid, fname, sizeof(fname)) ) return NULL; + + if (strcasecmp(strrchr(fname,'.'), ".iso") == 0) { + // .iso file + // create a fake wbfs_disc + int fd; + fd = open(fname, O_RDONLY); + if (fd == -1) return NULL; + wbfs_disc_t *iso_file = (wbfs_disc_t *)calloc(sizeof(wbfs_disc_t),1); + if (iso_file == NULL) return NULL; + // mark with a special wbfs_part + wbfs_iso_file.wbfs_sec_sz = 512; + iso_file->p = &wbfs_iso_file; + iso_file->header = (wbfs_disc_info_t*)fd; + return iso_file; + } + + wbfs_t *part = OpenPart(fname); + if (!part) return NULL; + return wbfs_open_disc(part, discid); +} + +void Wbfs_Fat::CloseDisc(wbfs_disc_t* disc) +{ + if (!disc) return; + wbfs_t *part = disc->p; + + // is this really a .iso file? + if (part == &wbfs_iso_file) { + close((int)disc->header); + free(disc); + return; + } + + wbfs_close_disc(disc); + ClosePart(part); + return; +} + +s32 Wbfs_Fat::GetCount(u32 *count) +{ + *count = 0; + GetHeadersCount(); + if (fat_hdr_count && fat_hdr_list) { + // for compacter mem - move up as it will be freed later + int size = fat_hdr_count * sizeof(struct discHdr); + struct discHdr *buf = (struct discHdr *) malloc(size); + if (buf) { + memcpy(buf, fat_hdr_list, size); + SAFE_FREE(fat_hdr_list); + fat_hdr_list = buf; + } + } + *count = fat_hdr_count; + return 0; +} + +s32 Wbfs_Fat::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) +{ + u32 i; + if (len > sizeof(struct discHdr)) { + len = sizeof(struct discHdr); + } +#ifdef DEBUG_WBFS + gprintf("\n\tGetHeaders"); +#endif + for (i=0; iwii_sec_sz; + + partition_selector_t part_sel; + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + } else { + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; + } + return wbfs_estimate_disc(part, __ReadDVD, NULL, part_sel); +} + +// TITLE [GAMEID] +bool Wbfs_Fat::CheckLayoutB(char *fname, int len, u8* id, char *fname_title) +{ + if (len <= 8) return false; + if (fname[len-8] != '[' || fname[len-1] != ']') return false; + if (!is_gameid(&fname[len-7])) return false; + strncpy(fname_title, fname, TITLE_LEN); + // cut at '[' + fname_title[len-8] = 0; + int n = strlen(fname_title); + if (n == 0) return false; + // cut trailing _ or ' ' + if (fname_title[n - 1] == ' ' || fname_title[n - 1] == '_' ) { + fname_title[n - 1] = 0; + } + if (strlen(fname_title) == 0) return false; + if (id) { + memcpy(id, &fname[len-7], 6); + id[6] = 0; + } + return true; +} + +s32 Wbfs_Fat::GetHeadersCount() +{ + char path[MAX_FAT_PATH]; + char fname[MAX_FAT_PATH]; + char fpath[MAX_FAT_PATH]; + struct discHdr tmpHdr; + struct stat st; + wbfs_t *part = NULL; + u8 id[8]; + int ret; + char *p; + u32 size; + int is_dir; + int len; + char dir_title[65]; + char fname_title[TITLE_LEN]; + char *title; + DIR_ITER *dir_iter; + + //dbg_time1(); + + SAFE_FREE(fat_hdr_list); + fat_hdr_count = 0; + + strcpy(path, wbfs_fs_drive); + strcat(path, wbfs_fat_dir); + + dir_iter = diropen(path); + if (!dir_iter) return 0; + + dir_iter = diropen(path); + if (!dir_iter) return 0; + + while (dirnext(dir_iter, fname, &st) == 0) { + //printf("found: %s\n", fname); Wpad_WaitButtonsCommon(); + if ((char)fname[0] == '.') continue; + len = strlen(fname); + if (len < 8) continue; // "GAMEID_x" + + memcpy(id, fname, 6); + id[6] = 0; + *fname_title = 0; + + is_dir = S_ISDIR(st.st_mode); + //printf("mode: %d %d %x\n", is_dir, st.st_mode, st.st_mode); + if (is_dir) { + int lay_a = 0; + int lay_b = 0; + if (fname[6] == '_' && is_gameid((char*)id)) { + // usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs + lay_a = 1; + } + if (CheckLayoutB(fname, len, NULL, fname_title)) { + // usb:/wbfs/TITLE[GAMEID]/GAMEID.wbfs + lay_b = 1; + } + if (!lay_a && !lay_b) continue; + if (lay_a) { + strncpy(dir_title, &fname[7], sizeof(dir_title)); + } else { + try_lay_b: + if (!CheckLayoutB(fname, len, id, fname_title)) continue; + } + snprintf(fpath, sizeof(fpath), "%s/%s/%s.wbfs", path, fname, id); + //printf("path2: %s\n", fpath); + // if more than 50 games, skip second stat to improve speed + // but if ambiguous layout check anyway + if (fat_hdr_count < 50 || (lay_a && lay_b)) { + if (stat(fpath, &st) == -1) { + //printf("missing: %s\n", fpath); + // try .iso + strcpy(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso + if (stat(fpath, &st) == -1) { + //printf("missing: %s\n", fpath); + // try .ciso + strcpy(strrchr(fpath, '.'), ".ciso"); // replace .iso with .ciso + if (stat(fpath, &st) == -1 ) { + if (lay_a && lay_b == 1) { + // mark lay_b so that the stat check is still done, + // but lay_b is not re-tried again + lay_b = 2; + // retry with layout b + goto try_lay_b; + } + continue; + } + } + } + } else { + st.st_size = 1024*1024; + } + } else { + // usb:/wbfs/GAMEID.wbfs + // or usb:/wbfs/GAMEID.iso + // or usb:/wbfs/GAMEID.ciso + p = strrchr(fname, '.'); + if (!p) continue; + if ( (strcasecmp(p, ".wbfs") != 0) + && (strcasecmp(p, ".iso") != 0) + && (strcasecmp(p, ".ciso") != 0) ) continue; + int n = p - fname; // length withouth .wbfs + if (n != 6) { + // TITLE [GAMEID].wbfs + if (!CheckLayoutB(fname, n, id, fname_title)) continue; + } + snprintf(fpath, sizeof(fpath), "%s/%s", path, fname); + } + + //printf("found: %s %d MB\n", fpath, (int)(st.st_size/1024/1024)); + // size must be at least 1MB to be considered a valid wbfs file + if (st.st_size < 1024*1024) continue; + // if we have titles.txt entry use that + title = cfg_get_title(id); + // if no titles.txt get title from dir or file name + if (!title && *fname_title) { + title = fname_title; + } + if (title) { + memset(&tmpHdr, 0, sizeof(tmpHdr)); + memcpy(tmpHdr.id, id, 6); + strncpy(tmpHdr.title, title, sizeof(tmpHdr.title)-1); + tmpHdr.magic = 0x5D1C9EA3; + goto add_hdr; + } + + // else read it from file directly + if (strcasecmp(strrchr(fpath,'.'), ".wbfs") == 0) { + // wbfs file directly + FILE *fp = fopen(fpath, "rb"); + if (fp != NULL) { + fseek(fp, 512, SEEK_SET); + fread(&tmpHdr, sizeof(struct discHdr), 1, fp); + fclose(fp); + tmpHdr.is_ciso = 0; + if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { + goto add_hdr; + } + } + // no title found, read it from wbfs file + // but this is a little bit slower + // open 'partition' file + part = OpenPart(fpath); + if (!part) { + continue; + } + // Get header + ret = wbfs_get_disc_info(part, 0, (u8*)&tmpHdr, + sizeof(struct discHdr), &size); + ClosePart(part); + if (ret == 0) { + goto add_hdr; + } + } else if (strcasecmp(strrchr(fpath,'.'), ".iso") == 0) { + // iso file + FILE *fp = fopen(fpath, "rb"); + if (fp != NULL) { + fseek(fp, 0, SEEK_SET); + fread(&tmpHdr, sizeof(struct discHdr), 1, fp); + fclose(fp); + tmpHdr.is_ciso = 0; + if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { + goto add_hdr; + } + } + } else if (strcasecmp(strrchr(fpath,'.'), ".ciso") == 0) { + // ciso file + FILE *fp = fopen(fpath, "rb"); + if (fp != NULL) { + fseek(fp, 0x8000, SEEK_SET); + fread(&tmpHdr, sizeof(struct discHdr), 1, fp); + fclose(fp); + tmpHdr.is_ciso = 1; + if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) { + goto add_hdr; + } + } + } + // fail: + continue; + + // succes: add tmpHdr to list: + add_hdr: + memset(&st, 0, sizeof(st)); + //printf("added: %.6s %.20s\n", tmpHdr.id, tmpHdr.title); Wpad_WaitButtons(); + fat_hdr_count++; + fat_hdr_list = (struct discHdr *) realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr)); + memcpy(&fat_hdr_list[fat_hdr_count-1], &tmpHdr, sizeof(struct discHdr)); + } + dirclose(dir_iter); + //dbg_time2("\nFAT_GetCount"); Wpad_WaitButtonsCommon(); + + return 0; +} + +int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len) +{ + struct stat st; + // look for direct .wbfs file + Filename(id, fname, len, NULL); + if (stat(fname, &st) == 0) return 1; + // look for direct .iso file + strcpy(strrchr(fname, '.'), ".iso"); // replace .wbfs with .iso + if (stat(fname, &st) == 0) return 1; + // look for direct .ciso file + strcpy(strrchr(fname, '.'), ".ciso"); // replace .iso with .ciso + if (stat(fname, &st) == 0) return 1; + // direct file not found, check subdirs + *fname = 0; + DIR_ITER *dir_iter; + char path[MAX_FAT_PATH]; + char name[MAX_FAT_PATH]; + strcpy(path, wbfs_fs_drive); + strcat(path, wbfs_fat_dir); + dir_iter = diropen(path); + //printf("dir: %s %p\n", path, dir); Wpad_WaitButtons(); + if (!dir_iter) { + return 0; + } + while (dirnext(dir_iter, name, &st) == 0) { + //dbg_printf("name:%s\n", name); + if (name[0] == '.') continue; + int n = strlen(name); + if (n < 8) continue; + if (S_ISDIR(st.st_mode)) { + if (name[6] == '_') { + // GAMEID_TITLE + if (strncmp(name, (char*)id, 6) != 0) goto try_alter; + } else { + try_alter: + // TITLE [GAMEID] + if (name[n-8] != '[' || name[n-1] != ']') continue; + if (strncmp(&name[n-7], (char*)id, 6) != 0) continue; + } + // look for .wbfs file + snprintf(fname, len, "%s/%s/%.6s.wbfs", path, name, id); + if (stat(fname, &st) == 0) break; + // look for .iso file + snprintf(fname, len, "%s/%s/%.6s.iso", path, name, id); + if (stat(fname, &st) == 0) break; + // look for .ciso file + snprintf(fname, len, "%s/%s/%.6s.ciso", path, name, id); + } else { + // TITLE [GAMEID].wbfs + char fn_title[TITLE_LEN]; + u8 fn_id[8]; + char *p = strrchr(name, '.'); + if (!p) continue; + if ( (strcasecmp(p, ".wbfs") != 0) + && (strcasecmp(p, ".iso") != 0) + && (strcasecmp(p, ".ciso") != 0) ) continue; + int n = p - name; // length withouth .wbfs + if (!CheckLayoutB(name, n, fn_id, fn_title)) continue; + if (strncmp((char*)fn_id, (char*)id, 6) != 0) continue; + snprintf(fname, len, "%s/%s", path, name); + } + if (stat(fname, &st) == 0) break; + *fname = 0; + } + dirclose(dir_iter); + if (*fname) { + // found + //printf("found:%s\n", fname); + return 2; + } + // not found + return 0; +} + +wbfs_t* Wbfs_Fat::OpenPart(char *fname) +{ + wbfs_t *part = NULL; + int ret; + + // wbfs 'partition' file + ret = split_open(&split, fname); + if (ret) return NULL; + part = wbfs_open_partition( + split_read_sector, + nop_rw_sector, //readonly //split_write_sector, + &split, fat_sector_size, split.total_sec, 0, 0); + if (!part) { + split_close(&split); + } + return part; +} + +void Wbfs_Fat::ClosePart(wbfs_t* part) +{ + if (!part) return; + split_info_t *s = (split_info_t*)part->callback_data; + wbfs_close(part); + if (s) split_close(s); +} + +void Wbfs_Fat::Filename(u8 *id, char *fname, int len, char *path) +{ + if (path == NULL) { + snprintf(fname, len, "%s%s/%.6s.wbfs", wbfs_fs_drive, wbfs_fat_dir, id); + } else { + snprintf(fname, len, "%s/%.6s.wbfs", path, id); + } +} + +void Wbfs_Fat::GetDir(struct discHdr *header, char *path) +{ + strcpy(path, wbfs_fs_drive); + strcat(path, wbfs_fat_dir); + if (Settings.FatInstallToDir) { + strcat(path, "/"); + int layout = 0; + if (Settings.FatInstallToDir == 2) layout = 1; + mk_gameid_title(header, path + strlen(path), 0, layout); + } +} + +wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path) +{ + char fname[MAX_FAT_PATH]; + wbfs_t *part = NULL; + u64 size = (u64)143432*2*0x8000ULL; + u32 n_sector = size / 512; + int ret; + + //printf("CREATE PART %s %lld %d\n", id, size, n_sector); + snprintf(fname, sizeof(fname), "%s%s", wbfs_fs_drive, wbfs_fat_dir); + mkdir(fname, 0777); // base usb:/wbfs + mkdir(path, 0777); // game subdir + Filename(id, fname, sizeof(fname), path); + printf("Writing to %s\n", fname); + ret = split_create(&split, fname, OPT_split_size, size, true); + if (ret) return NULL; + + // force create first file + u32 scnt = 0; + int fd = split_get_file(&split, 0, &scnt, 0); + if (fd<0) { + printf("ERROR creating file\n"); + sleep(2); + split_close(&split); + return NULL; + } + + part = wbfs_open_partition( + split_read_sector, + split_write_sector, + &split, fat_sector_size, n_sector, 0, 1); + if (!part) { + split_close(&split); + } + return part; +} + +void Wbfs_Fat::mk_title_txt(struct discHdr *header, char *path) +{ + char fname[MAX_FAT_PATH]; + FILE *f; + + strcpy(fname, path); + strcat(fname, "/"); + mk_gameid_title(header, fname+strlen(fname), 1, 0); + strcat(fname, ".txt"); + + f = fopen(fname, "wb"); + if (!f) return; + fprintf(f, "%.6s = %.64s\n", header->id, get_title(header)); + fclose(f); + printf("Info file: %s\n", fname); +} + +void Wbfs_Fat::mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout) +{ + int i, len; + char title[65]; + char id[8]; + + memcpy(name, header->id, 6); + name[6] = 0; + strncpy(title, get_title(header), sizeof(title)); + title_filename(title); + + if (layout == 0) { + sprintf(name, "%s_%s", id, title); + } else { + sprintf(name, "%s [%s]", title, id); + } + + // replace space with '_' + if (re_space) { + len = strlen(name); + for (i = 0; i < len; i++) { + if(name[i]==' ') name[i] = '_'; + } + } +} + +void Wbfs_Fat::title_filename(char *title) +{ + int i, len; + // trim leading space + len = strlen(title); + while (*title == ' ') { + memmove(title, title+1, len); + len--; + } + // trim trailing space - not allowed on windows directories + while (len && title[len-1] == ' ') { + title[len-1] = 0; + len--; + } + // replace silly chars with '_' + for (i=0; i 0) { + fname[strlen(fname)-1] = '0' + i; + if (stat(fname, &st) == -1) break; + } + strcpy(fname1, fname); + if ((ret = GetFragList((char *) &fname, &_frag_append, fs))) + { + ret_val = ret; + goto out; + } + frag_concat(fa, fs); + } + frag_list = (FragList *) malloc(sizeof(FragList)); + frag_init(frag_list, MAX_FRAG); + if (is_wbfs) { + // if wbfs file format, remap. + //printf("=====\n"); + wbfs_disc_t *d = OpenDisc(id); + if (!d) goto out; + frag_init(fw, MAX_FRAG); + ret = wbfs_get_fragments(d, &_frag_append, fw); + if (ret) goto out; + CloseDisc(d); + // DEBUG: + //frag_list->num = MAX_FRAG-10; // stress test + ret = frag_remap(frag_list, fw, fa); + if (ret) goto out; + } else { + // .iso does not need remap just copy + //printf("fa:\n"); + memcpy(frag_list, fa, sizeof(FragList)); + } + + ret_val = 0; + +out: + if (ret_val) { + // error + SAFE_FREE(frag_list); + } + SAFE_FREE(fs); + SAFE_FREE(fa); + SAFE_FREE(fw); + return ret_val; +} + +int Wbfs_Fat::GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs) +{ + return _FAT_get_fragments(filename, append_fragment, fs); +} + +bool Wbfs_Fat::ShowFreeSpace(void) +{ + return false; +} diff --git a/source/usbloader/wbfs/wbfs_wbfs.cpp b/source/usbloader/wbfs/wbfs_wbfs.cpp index ab538b98..20b713b1 100644 --- a/source/usbloader/wbfs/wbfs_wbfs.cpp +++ b/source/usbloader/wbfs/wbfs_wbfs.cpp @@ -1,206 +1,206 @@ -#include "wbfs_wbfs.h" -#include "../spinner.h" -#include "settings/cfg.h" -#include "wbfs_rw.h" - -extern u32 sector_size; - -s32 Wbfs_Wbfs::Open() -{ - wbfs_t *part = NULL; - - /* Open partition */ - part = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 0); - if (!part) return -1; - - /* Close current hard disk */ - Close(); - hdd = part; - - // Save the new sector size, so it will be used in read and write calls - sector_size = 1 << hdd->head->hd_sec_sz_s; - - return 0; -} - -wbfs_disc_t* Wbfs_Wbfs::OpenDisc(u8 *discid) -{ - /* No device open */ - if (!hdd) - return NULL; - - /* Open disc */ - return wbfs_open_disc(hdd, discid); -} - -void Wbfs_Wbfs::CloseDisc(wbfs_disc_t *disc) -{ - /* No device open */ - if (!hdd || !disc) - return; - - /* Close disc */ - wbfs_close_disc(disc); -} - -s32 Wbfs_Wbfs::Format() -{ - wbfs_t *partition = NULL; - - /* Reset partition */ - partition = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 1); - if (!partition) - return -1; - - /* Free memory */ - wbfs_close(partition); - - return 0; -} - -s32 Wbfs_Wbfs::GetCount(u32 *count) -{ - /* No device open */ - if (!hdd) - return -1; - - /* Get list length */ - *count = wbfs_count_discs(hdd); - - return 0; -} - -s32 Wbfs_Wbfs::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) -{ - u32 idx, size; - s32 ret; - - /* No device open */ - if (!hdd) - return -1; - - for (idx = 0; idx < cnt; idx++) { - u8 *ptr = ((u8 *)outbuf) + (idx * len); - - /* Get header */ - ret = wbfs_get_disc_info(hdd, idx, ptr, len, &size); - if (ret < 0) - return ret; - } - - return 0; -} - -s32 Wbfs_Wbfs::AddGame() -{ - s32 ret; - - /* No device open */ - if (!hdd) - return -1; - - /* Add game to device */ - partition_selector_t part_sel; - int copy_1_1 = 0; - - if (Settings.fullcopy) { - part_sel = ALL_PARTITIONS; - copy_1_1 = 1; - } else { - 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); - if (ret < 0) - return ret; - - return 0; -} - -s32 Wbfs_Wbfs::RemoveGame(u8 *discid) -{ - s32 ret; - - /* No device open */ - if (!hdd) - return -1; - - /* Remove game from USB device */ - ret = wbfs_rm_disc(hdd, discid); - if (ret < 0) - return ret; - - return 0; -} - -s32 Wbfs_Wbfs::DiskSpace(f32 *used, f32 *free) -{ - f32 ssize; - u32 cnt; - - /* No device open */ - if (!hdd) - return -1; - - /* Count used blocks */ - cnt = wbfs_count_usedblocks(hdd); - - /* Sector size in GB */ - ssize = hdd->wbfs_sec_sz / GB_SIZE; - - /* Copy values */ - *free = ssize * cnt; - *used = ssize * (hdd->n_wbfs_sec - cnt); - - return 0; -} - -s32 Wbfs_Wbfs::RenameGame(u8 *discid, const void *newname) -{ - s32 ret; - - /* No USB device open */ - if (!hdd) - return -1; - ret = wbfs_ren_disc(hdd, discid,(u8*)newname); - if (ret < 0) - return ret; - - return 0; -} - -s32 Wbfs_Wbfs::ReIDGame(u8 *discid, const void *newID) -{ - s32 ret; - - /* No USB device open */ - if (!hdd) - return -1; - ret = wbfs_rID_disc(hdd, discid,(u8*)newID); - if (ret < 0) - return ret; - - return 0; -} - -f32 Wbfs_Wbfs::EstimateGameSize() -{ - partition_selector_t part_sel = ONLY_GAME_PARTITION; - if (Settings.fullcopy) { - part_sel = ALL_PARTITIONS; - } else { - switch(Settings.partitions_to_install) - { - case install_game_only: - part_sel = ONLY_GAME_PARTITION; - break; - case install_all: - part_sel = ALL_PARTITIONS; - break; - case install_all_but_update: - part_sel = REMOVE_UPDATE_PARTITION; - break; - } - } - return wbfs_estimate_disc(hdd, __ReadDVD, NULL, part_sel); -} +#include "wbfs_wbfs.h" +#include "prompts/ProgressWindow.h" +#include "settings/cfg.h" +#include "wbfs_rw.h" + +extern u32 sector_size; + +s32 Wbfs_Wbfs::Open() +{ + wbfs_t *part = NULL; + + /* Open partition */ + part = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 0); + if (!part) return -1; + + /* Close current hard disk */ + Close(); + hdd = part; + + // Save the new sector size, so it will be used in read and write calls + sector_size = 1 << hdd->head->hd_sec_sz_s; + + return 0; +} + +wbfs_disc_t* Wbfs_Wbfs::OpenDisc(u8 *discid) +{ + /* No device open */ + if (!hdd) + return NULL; + + /* Open disc */ + return wbfs_open_disc(hdd, discid); +} + +void Wbfs_Wbfs::CloseDisc(wbfs_disc_t *disc) +{ + /* No device open */ + if (!hdd || !disc) + return; + + /* Close disc */ + wbfs_close_disc(disc); +} + +s32 Wbfs_Wbfs::Format() +{ + wbfs_t *partition = NULL; + + /* Reset partition */ + partition = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 1); + if (!partition) + return -1; + + /* Free memory */ + wbfs_close(partition); + + return 0; +} + +s32 Wbfs_Wbfs::GetCount(u32 *count) +{ + /* No device open */ + if (!hdd) + return -1; + + /* Get list length */ + *count = wbfs_count_discs(hdd); + + return 0; +} + +s32 Wbfs_Wbfs::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) +{ + u32 idx, size; + s32 ret; + + /* No device open */ + if (!hdd) + return -1; + + for (idx = 0; idx < cnt; idx++) { + u8 *ptr = ((u8 *)outbuf) + (idx * len); + + /* Get header */ + ret = wbfs_get_disc_info(hdd, idx, ptr, len, &size); + if (ret < 0) + return ret; + } + + return 0; +} + +s32 Wbfs_Wbfs::AddGame() +{ + s32 ret; + + /* No device open */ + if (!hdd) + return -1; + + /* Add game to device */ + partition_selector_t part_sel; + int copy_1_1 = 0; + + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + copy_1_1 = 1; + } else { + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; + } + + ret = wbfs_add_disc(hdd, __ReadDVD, NULL, ProgressCallback, part_sel, copy_1_1); + if (ret < 0) + return ret; + + return 0; +} + +s32 Wbfs_Wbfs::RemoveGame(u8 *discid) +{ + s32 ret; + + /* No device open */ + if (!hdd) + return -1; + + /* Remove game from USB device */ + ret = wbfs_rm_disc(hdd, discid); + if (ret < 0) + return ret; + + return 0; +} + +s32 Wbfs_Wbfs::DiskSpace(f32 *used, f32 *free) +{ + f32 ssize; + u32 cnt; + + /* No device open */ + if (!hdd) + return -1; + + /* Count used blocks */ + cnt = wbfs_count_usedblocks(hdd); + + /* Sector size in GB */ + ssize = hdd->wbfs_sec_sz / GB_SIZE; + + /* Copy values */ + *free = ssize * cnt; + *used = ssize * (hdd->n_wbfs_sec - cnt); + + return 0; +} + +s32 Wbfs_Wbfs::RenameGame(u8 *discid, const void *newname) +{ + s32 ret; + + /* No USB device open */ + if (!hdd) + return -1; + ret = wbfs_ren_disc(hdd, discid,(u8*)newname); + if (ret < 0) + return ret; + + return 0; +} + +s32 Wbfs_Wbfs::ReIDGame(u8 *discid, const void *newID) +{ + s32 ret; + + /* No USB device open */ + if (!hdd) + return -1; + ret = wbfs_rID_disc(hdd, discid,(u8*)newID); + if (ret < 0) + return ret; + + return 0; +} + +f32 Wbfs_Wbfs::EstimateGameSize() +{ + partition_selector_t part_sel = ONLY_GAME_PARTITION; + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + } else { + switch(Settings.partitions_to_install) + { + case install_game_only: + part_sel = ONLY_GAME_PARTITION; + break; + case install_all: + part_sel = ALL_PARTITIONS; + break; + case install_all_but_update: + part_sel = REMOVE_UPDATE_PARTITION; + break; + } + } + return wbfs_estimate_disc(hdd, __ReadDVD, NULL, part_sel); +}