Skip to content

Commit

Permalink
learning the art of callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
Naim2000 committed Nov 5, 2023
1 parent a210779 commit 19eaa8d
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 463 deletions.
4 changes: 2 additions & 2 deletions apps/cdbackup/meta.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>cdbackup</name>
<version>1.2.0</version>
<release_date>20230802000000</release_date>
<version>1.2.1</version>
<release_date>20231105004800</release_date>
<coder>thepikachugamer</coder>
<short_description>Backup/restore/delete Wii message board data.</short_description>
<long_description>Backup/restore your Wii message board data to cdbackup.vff on your SD card or USB drive, or delete it entirely.
Expand Down
26 changes: 7 additions & 19 deletions include/fatMounter.h
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();
13 changes: 13 additions & 0 deletions include/fs.h
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);
5 changes: 2 additions & 3 deletions include/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ extern uint16_t input_btns;
extern uint32_t wii_down;
extern uint16_t gcn_down;

void init_video(int row, int col);
[[gnu::constructor]] void init_video();
void input_scan(void);

int quit(int ret);
[[noreturn]] void quit(int ret);

bool confirmation(const char* message, unsigned int wait_time);

Expand Down
260 changes: 62 additions & 198 deletions source/fatMounter.c
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;
}
}

Loading

0 comments on commit 19eaa8d

Please sign in to comment.