-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
308 additions
and
463 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,7 @@ | ||
#ifndef _FATMOUNTER_H_ | ||
#define _FATMOUNTER_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
// Prototypes | ||
int MountSD(void); | ||
void UnmountSD(void); | ||
int MountUSB(void); | ||
void UnmountUSB(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif | ||
#include <stdbool.h> | ||
|
||
bool mountSD(); | ||
void unmountSD(); | ||
|
||
bool mountUSB(); | ||
void unmountUSB(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include <ogc/isfs.h> | ||
#include <fat.h> | ||
|
||
typedef int (*RWCallback)(size_t read, size_t filesize); | ||
|
||
#define MAXIMUM(max, size) ( ( size > max ) ? max : size ) | ||
#define FS_CHUNK 1048576 | ||
|
||
int FS_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback cb); | ||
int FS_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback cb); | ||
int FAT_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback cb); | ||
int FAT_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback cb); | ||
int progressbar(size_t read, size_t filesize); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,198 +1,62 @@ | ||
#include <fat.h> | ||
#include <gccore.h> | ||
#include <string.h> | ||
#include <sdcard/wiisd_io.h> | ||
#include <ogc/usbstorage.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <ogcsys.h> | ||
|
||
// These are the only stable and speed is good | ||
#define CACHE 8 | ||
#define SECTORS 64 | ||
#define BYTES_PER_READ 512 | ||
|
||
extern DISC_INTERFACE __io_usbstorage; | ||
|
||
enum BPB | ||
{ | ||
BPB_jmpBoot = 0x00, | ||
BPB_OEMName = 0x03, | ||
|
||
// BIOS Parameter Block | ||
BPB_bytesPerSector = 0x0B, | ||
BPB_sectorsPerCluster = 0x0D, | ||
BPB_reservedSectors = 0x0E, | ||
BPB_numFATs = 0x10, | ||
BPB_rootEntries = 0x11, | ||
BPB_numSectorsSmall = 0x13, | ||
BPB_mediaDesc = 0x15, | ||
BPB_sectorsPerFAT = 0x16, | ||
BPB_sectorsPerTrk = 0x18, | ||
BPB_numHeads = 0x1A, | ||
BPB_numHiddenSectors = 0x1C, | ||
BPB_numSectors = 0x20, | ||
|
||
// Ext BIOS Parameter Block for FAT16 | ||
BPB_FAT16_driveNumber = 0x24, | ||
BPB_FAT16_reserved1 = 0x25, | ||
BPB_FAT16_extBootSig = 0x26, | ||
BPB_FAT16_volumeID = 0x27, | ||
BPB_FAT16_volumeLabel = 0x2B, | ||
BPB_FAT16_fileSysType = 0x36, | ||
|
||
// Bootcode | ||
BPB_FAT16_bootCode = 0x3E, | ||
|
||
// FAT32 Extended Block | ||
BPB_FAT32_sectorsPerFAT32 = 0x24, | ||
BPB_FAT32_extFlags = 0x28, | ||
BPB_FAT32_fsVer = 0x2A, | ||
BPB_FAT32_rootClus = 0x2C, | ||
BPB_FAT32_fsInfo = 0x30, | ||
BPB_FAT32_bkBootSec = 0x32, | ||
|
||
// Ext BIOS Parameter Block for FAT32 | ||
BPB_FAT32_driveNumber = 0x40, | ||
BPB_FAT32_reserved1 = 0x41, | ||
BPB_FAT32_extBootSig = 0x42, | ||
BPB_FAT32_volumeID = 0x43, | ||
BPB_FAT32_volumeLabel = 0x47, | ||
BPB_FAT32_fileSysType = 0x52, | ||
|
||
// Bootcode | ||
BPB_FAT32_bootCode = 0x5A, | ||
BPB_bootSig_55 = 0x1FE, | ||
BPB_bootSig_AA = 0x1FF | ||
}; | ||
|
||
static const char FAT_SIG[3] = {'F', 'A', 'T'}; | ||
static bool sd_mounted = false; | ||
static bool usb_mounted = false; | ||
|
||
static bool _FAT_partition_isFAT(const DISC_INTERFACE* disc, sec_t startSector) | ||
{ | ||
uint8_t sectorBuffer[BYTES_PER_READ] = {0}; | ||
|
||
if (!disc->readSectors(startSector, 1, sectorBuffer)) return false; | ||
|
||
// Make sure it is a valid BPB | ||
if ((sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) return false; | ||
|
||
// Now verify that this is indeed a FAT partition | ||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) return false; | ||
|
||
// Check again for the last two cases to make sure that we really have a FAT filesystem here and won't corrupt any data | ||
if(memcmp(sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3) != 0 && memcmp(sectorBuffer + BPB_FAT32_fileSysType, "FAT32", 5) != 0) return false; | ||
|
||
return true; | ||
} | ||
|
||
static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) | ||
{ | ||
return (item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24)); | ||
} | ||
|
||
sec_t GetFATPartition(const DISC_INTERFACE* disc) | ||
{ | ||
int i; | ||
uint8_t sectorBuffer[BYTES_PER_READ] = {0}; | ||
sec_t startSector = 0; | ||
|
||
if (!disc->startup()) return 0; | ||
|
||
// Read first sector of disc | ||
if (!disc->readSectors(0, 1, sectorBuffer)) startSector = 0; | ||
|
||
// Make sure it is a valid MBR or boot sector | ||
if ((sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) startSector = 0; | ||
|
||
if (!memcmp(sectorBuffer+BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) | ||
{ | ||
// Check if there is a FAT string, which indicates this is a boot sector | ||
startSector = 0; | ||
} | ||
else if (!memcmp(sectorBuffer+BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) | ||
{ | ||
// Check for FAT32 | ||
startSector = 0; | ||
} | ||
else | ||
{ | ||
// This is an MBR | ||
// Find first valid partition from MBR | ||
// First check for an active partition | ||
for (i = 0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10); | ||
|
||
// If it find an active partition, check for FAT Partition | ||
if (i != 0x1FE && !_FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8+i))) i = 0x1FE; | ||
|
||
// If it didn't find an active partition, search for any valid partition | ||
if (i == 0x1FE) | ||
{ | ||
for (i = 0x1BE; i < 0x1FE; i+= 0x10) | ||
{ | ||
if (sectorBuffer[i+0x04] != 0x00 && _FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8+i))) break; | ||
} | ||
} | ||
|
||
if (i != 0x1FE) startSector = u8array_to_u32(sectorBuffer, 0x8+i); | ||
} | ||
|
||
disc->shutdown(); | ||
|
||
return startSector; | ||
} | ||
|
||
int MountSD(void) | ||
{ | ||
// Close all open files write back the cache and then shutdown them | ||
fatUnmount("sd"); | ||
|
||
// Mount first FAT partition | ||
if (fatMount("sd", &__io_wiisd, GetFATPartition(&__io_wiisd), CACHE, SECTORS)) | ||
{ | ||
sd_mounted = true; | ||
return 1; | ||
} | ||
return -1; | ||
} | ||
|
||
void UnmountSD(void) | ||
{ | ||
if (!sd_mounted) return; | ||
// Close all open files write back the cache and then shutdown them | ||
fatUnmount("sd"); | ||
sd_mounted = false; | ||
} | ||
|
||
int MountUSB() | ||
{ | ||
fatUnmount("usb"); | ||
__io_usbstorage.startup(); | ||
if ((usb_mounted = __io_usbstorage.isInserted())) | ||
{ | ||
int retry = 10; | ||
while ((retry) && ((usb_mounted = fatMountSimple("usb", &__io_usbstorage)) == false)) | ||
{ | ||
sleep(1); | ||
retry--; | ||
} | ||
} | ||
return usb_mounted; | ||
} | ||
|
||
void UnmountUSB(void) | ||
{ | ||
|
||
if(!usb_mounted) return; | ||
/* Unmount device */ | ||
fatUnmount("usb"); | ||
|
||
/* Shutdown interface */ | ||
__io_usbstorage.shutdown(); | ||
usb_mounted = false; | ||
} | ||
|
||
#include "fatMounter.h" | ||
|
||
#include <fat.h> | ||
#include <sdcard/wiisd_io.h> | ||
#include <ogc/usbstorage.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
|
||
static const DISC_INTERFACE *sd_card = &__io_wiisd, | ||
*usb_msc = &__io_usbstorage; | ||
|
||
static bool sd_mounted = false, | ||
usb_mounted = false; | ||
|
||
bool mountSD() { | ||
if (sd_mounted) return sd_mounted; | ||
|
||
sd_card->startup(); | ||
if (!sd_card->isInserted()) { | ||
sd_card->shutdown(); | ||
errno = ENODEV; | ||
return false; | ||
} | ||
sd_mounted = fatMountSimple("sd", sd_card); | ||
chdir("sd:/"); | ||
return sd_mounted; | ||
} | ||
|
||
void unmountSD() { | ||
if (sd_mounted) { | ||
fatUnmount("sd"); | ||
sd_card->shutdown(); | ||
sd_mounted = false; | ||
} | ||
} | ||
|
||
bool mountUSB() { | ||
if (usb_mounted) return usb_mounted; | ||
|
||
usb_msc->startup(); | ||
if (!usb_msc->isInserted()) { | ||
usb_msc->shutdown(); | ||
errno = ENODEV; | ||
return false; | ||
} | ||
|
||
// for(int r = 0; r < 10; r++) { | ||
usb_mounted = fatMountSimple("usb", usb_msc); | ||
// if(usb_mounted) break; | ||
// } | ||
chdir("usb:/"); | ||
return usb_mounted; | ||
} | ||
|
||
void unmountUSB() { | ||
if (usb_mounted) { | ||
fatUnmount("usb"); | ||
usb_msc->shutdown(); | ||
usb_mounted = false; | ||
} | ||
} | ||
|
Oops, something went wrong.