From f5e66637841ce72388b66764e28515d463487f65 Mon Sep 17 00:00:00 2001 From: "ardi@ist-einmalig.de" Date: Tue, 9 Jun 2009 23:26:03 +0000 Subject: [PATCH] makes it possible to use a FAT-Partition on the USB WBFS-Disk Boot-Strategy: - is "argv[0]" set, then the boot-device extracted from the argv. - if no meaningful boot device found, then looking for "boot.dol"/"boot.elf" in "apps/usbloader_gx/" first on "SD:/" and then on "USB:/". When found, than use this Device. Otherwise use the default "SD:" - Set all default-Paths on this Device - Set the Path for config-Folder, GXGlobal.cfg, GXGameSettings.cfg and GXGameFavorites.cfg on this Device (e.g. USB:/config and so on) --- source/PromptWindows.cpp | 16 ++-- source/Settings.cpp | 38 ++++++--- source/SettingsPrompts.cpp | 9 ++- source/cfg.c | 73 +++++++++++------ source/cfg.h | 4 +- source/fatmounter.c | 162 ++++++++++++++++++++++++++++++++++--- source/fatmounter.h | 1 + source/fst.c | 4 - source/listfiles.c | 29 +++---- source/main.cpp | 23 +++++- source/menu.cpp | 18 +++-- source/usbstorage.c | 85 +++++++++++++++++++ source/usbstorage.h | 4 +- source/wbfs.h | 4 + 14 files changed, 379 insertions(+), 91 deletions(-) diff --git a/source/PromptWindows.cpp b/source/PromptWindows.cpp index 3c13b1a5..4625b92f 100644 --- a/source/PromptWindows.cpp +++ b/source/PromptWindows.cpp @@ -1216,7 +1216,8 @@ int GameWindowPrompt() favorite = game_num->favorite; count = game_num->count;//count+=1; }count+=1; - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { if (CFG_save_game_num(header->id)) { //WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0); @@ -1250,7 +1251,8 @@ int GameWindowPrompt() } else if(btnFavorite.GetState() == STATE_CLICKED){//switch favorite - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { faveChoice = !faveChoice; btnFavoriteImg.SetImage(faveChoice ? &imgFavorite : &imgNotFavorite); extern u8 favorite; @@ -2285,15 +2287,17 @@ ProgressUpdateWindow() if(file.data != NULL) { char revtxt[10]; - pfile = fopen("SD:/rev.txt", "w"); + char rev_txt[14]; + sprintf(rev_txt, "%s:/rev.txt", bootDevice); + pfile = fopen(rev_txt, "w"); fwrite(file.data,1,file.size,pfile); fclose(pfile); //has to be repeated or it isnt working (first file download bug) - pfile = fopen("SD:/rev.txt", "w"); + pfile = fopen(rev_txt, "w"); fwrite(file.data,1,file.size,pfile); fclose(pfile); //"w+" doesnt work, needs to be reopened as "r" - pfile = fopen("SD:/rev.txt", "r"); + pfile = fopen(rev_txt, "r"); int c = 0, i = 0; while(c != EOF || i < 10) { c = fgetc(pfile); @@ -2307,7 +2311,7 @@ ProgressUpdateWindow() } fclose(pfile); revnumber = atoi(revtxt); - remove("SD:/rev.txt"); + remove(rev_txt); free(file.data); } diff --git a/source/Settings.cpp b/source/Settings.cpp index fa943d5f..d017962c 100644 --- a/source/Settings.cpp +++ b/source/Settings.cpp @@ -601,7 +601,8 @@ int MenuSettings() switch (ret) { case 0: - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { if ( Settings.godmode == 1) { w.SetEffect(EFFECT_FADE, -20); @@ -1101,7 +1102,8 @@ int MenuSettings() switch (ret) { case 0: - if(isSdInserted()) + //if(isSdInserted()) + if(isInserted(bootDevice)) { w.SetEffect(EFFECT_FADE, -20); while(w.GetEffect()>0) usleep(50); @@ -1252,8 +1254,9 @@ int MenuSettings() strncat (entered, "/", 1); strncpy(Settings.covers_path, entered, sizeof(Settings.covers_path)); WindowPrompt(LANGUAGE.CoverpathChanged,0,LANGUAGE.ok,0,0,0); - if(!isSdInserted()) { - WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0); +// if(!isSdInserted()) { + if(!isInserted(bootDevice)) { + WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0); } } } else { @@ -1277,7 +1280,8 @@ int MenuSettings() strncat (entered, "/", 1); strncpy(Settings.disc_path, entered, sizeof(Settings.disc_path)); WindowPrompt(LANGUAGE.DiscpathChanged,0,LANGUAGE.ok,0,0,0); - if(!isSdInserted()) { +// if(!isSdInserted()) { + if(!isInserted(bootDevice)) { WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0); } } @@ -1302,7 +1306,8 @@ int MenuSettings() strncat (entered, "/", 1); strncpy(CFG.theme_path, entered, sizeof(CFG.theme_path)); WindowPrompt(LANGUAGE.ThemepathChanged,0,LANGUAGE.ok,0,0,0); - if(!isSdInserted()) { +// if(!isSdInserted()) { + if(!isInserted(bootDevice)) { WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0); } else { cfg_save_global(); @@ -1358,7 +1363,8 @@ int MenuSettings() strncat (entered, "/", 1); strncpy(Settings.titlestxt_path, entered, sizeof(Settings.titlestxt_path)); WindowPrompt(LANGUAGE.TitlestxtpathChanged,0,LANGUAGE.ok,0,0,0); - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); CFG_Load(); } else { @@ -1422,7 +1428,8 @@ int MenuSettings() w.Remove(&MainButton2); w.Remove(&MainButton3); w.Remove(&MainButton4); - if(isSdInserted() && Settings.godmode) { +// if(isSdInserted() && Settings.godmode) { + if(isInserted(bootDevice) && Settings.godmode) { w.Remove(&optionBrowser2); w.Remove(&backBtn); int ret = ProgressUpdateWindow(); @@ -1459,8 +1466,13 @@ int MenuSettings() if(Settings.godmode) { int choice = WindowPrompt(LANGUAGE.Areyousure, 0, LANGUAGE.Yes, LANGUAGE.Cancel, 0, 0); if(choice == 1) { - if(isSdInserted()) - remove("SD:/config/GXGlobal.cfg"); +// if(isSdInserted()) + if(isInserted(bootDevice)) + { + char GXGlobal_cfg[26]; + sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice); + remove(GXGlobal_cfg); + } lang_default(); CFG_Load(); menu = MENU_SETTINGS; @@ -1507,7 +1519,8 @@ int MenuSettings() if(backBtn.GetState() == STATE_CLICKED) { //Add the procedure call to save the global configuration - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); } menu = MENU_DISCLIST; @@ -1825,7 +1838,8 @@ int GameSettings(struct discHdr * header) if(saveBtn.GetState() == STATE_CLICKED) { - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { if (CFG_save_game_opt(header->id)) { WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0); diff --git a/source/SettingsPrompts.cpp b/source/SettingsPrompts.cpp index 59baa31e..0637f21d 100644 --- a/source/SettingsPrompts.cpp +++ b/source/SettingsPrompts.cpp @@ -231,7 +231,8 @@ bool MenuOGG() strncat (entered, "/", 1); strncpy(Settings.oggload_path, entered, sizeof(Settings.oggload_path)); WindowPrompt(LANGUAGE.Backgroundmusicpath,0,LANGUAGE.ok,0,0,0); - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { if(!strcmp("", Settings.oggload_path)) { sprintf(Settings.ogg_path, "notset"); bgMusic->Play(); @@ -473,7 +474,8 @@ int MenuLanguageSelect() strncat (entered, "/", 1); strncpy(Settings.languagefiles_path, entered, sizeof(Settings.languagefiles_path)); WindowPrompt(LANGUAGE.Languagepathchanged,0,LANGUAGE.ok,0,0,0); - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); returnhere = 1; break; @@ -492,7 +494,8 @@ int MenuLanguageSelect() if(ret>=0) { choice = WindowPrompt(LANGUAGE.Doyouwanttochangelanguage, 0, LANGUAGE.Yes, LANGUAGE.Cancel,0,0); if(choice == 1) { - if(isSdInserted()) { +// if(isSdInserted()) { + if(isInserted(bootDevice)) { snprintf(Settings.language_path, sizeof(Settings.language_path), "%s%s", Settings.languagefiles_path, GetFileName(ret)); cfg_save_global(); if(!checkfile(Settings.language_path)) { diff --git a/source/cfg.c b/source/cfg.c index 42e93b24..18834450 100644 --- a/source/cfg.c +++ b/source/cfg.c @@ -13,8 +13,9 @@ struct SSettings Settings; +char bootDevice[10] = "SD:"; -char *cfg_path = "SD:/apps/usbloader/"; +//char *cfg_path = "SD:/apps/usbloader/"; char current_path[100]; @@ -221,24 +222,24 @@ void CFG_Default(int widescreen) // -1 = non forced Mode CFG.widescreen = widescreen; if (CFG.widescreen) { - snprintf(CFG.theme_path, sizeof(CFG.theme_path), "SD:/wtheme/"); + snprintf(CFG.theme_path, sizeof(CFG.theme_path), "%s/wtheme/", bootDevice); } else { - snprintf(CFG.theme_path, sizeof(CFG.theme_path), "SD:/theme/"); + snprintf(CFG.theme_path, sizeof(CFG.theme_path), "%s/theme/", bootDevice); } if (widescreen == -1) { - snprintf(Settings.covers_path, sizeof(Settings.covers_path), "SD:/images/"); //default image path - snprintf(Settings.disc_path, sizeof(Settings.disc_path), "SD:/images/disc/"); - snprintf(Settings.titlestxt_path, sizeof(Settings.titlestxt_path), "SD:/config/");//default path for disc images + snprintf(Settings.covers_path, sizeof(Settings.covers_path), "%s/images/", bootDevice); //default image path + snprintf(Settings.disc_path, sizeof(Settings.disc_path), "%s/images/disc/", bootDevice); + snprintf(Settings.titlestxt_path, sizeof(Settings.titlestxt_path), "%s/config/", bootDevice);//default path for disc images char * empty = ""; snprintf(Settings.unlockCode, sizeof(Settings.unlockCode), empty); // default password snprintf(Settings.language_path, sizeof(Settings.language_path), "notset"); - snprintf(Settings.languagefiles_path, sizeof(Settings.languagefiles_path), "SD:/config/language/"); - snprintf(Settings.oggload_path, sizeof(Settings.oggload_path), "SD:/config/backgroundmusic/"); - snprintf(Settings.update_path, sizeof(Settings.update_path), "SD:/apps/usbloader_gx/"); + snprintf(Settings.languagefiles_path, sizeof(Settings.languagefiles_path), "%s/config/language/", bootDevice); + snprintf(Settings.oggload_path, sizeof(Settings.oggload_path), "%s/config/backgroundmusic/", bootDevice); + snprintf(Settings.update_path, sizeof(Settings.update_path), "%s/apps/usbloader_gx/", bootDevice); sprintf(Settings.ogg_path, "notset"); //all alignments are left top here @@ -1148,14 +1149,17 @@ void cfg_set_game_num(struct Game_NUM *game, u8 *id) bool cfg_save_global()// save global settings { + char GXGlobal_cfg[26]; + sprintf(GXGlobal_cfg, "%s/config", bootDevice); struct stat st; - if(stat("SD:/config/", &st) != 0) { - mkdir("SD:/config", 0777); + if(stat(GXGlobal_cfg, &st) != 0) { + mkdir(GXGlobal_cfg, 0777); } FILE *f; - f = fopen("SD:/config/GXGlobal.cfg", "w"); + sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice); + f = fopen(GXGlobal_cfg, "w"); if (!f) { - printf("Error saving %s\n", "GXGlobal.cfg"); + printf("Error saving %s\n", GXGlobal_cfg); sleep(1); return false; } @@ -1163,7 +1167,7 @@ bool cfg_save_global()// save global settings fprintf(f, "# Note: This file is automatically generated\n"); fclose(f); /* Closing and reopening because of a write issue we are having right now */ - f = fopen("SD:/config/GXGlobal.cfg", "w"); + f = fopen(GXGlobal_cfg, "w"); fprintf(f, "# USB Loader global settings file\n"); fprintf(f, "# Note: This file is automatically generated\n"); fprintf(f, "video = %d\n ", Settings.video); @@ -1373,20 +1377,28 @@ void game_set_num(char *name, char *val) bool cfg_load_games() { - return cfg_parsefile("SD:/config/GXGameSettings.cfg", &game_set); + char GXGameSettings_cfg[32]; + sprintf(GXGameSettings_cfg, "%s/config/GXGameSettings.cfg", bootDevice); + return cfg_parsefile(GXGameSettings_cfg, &game_set); } bool cfg_load_game_num() { - return cfg_parsefile("SD:/config/GXGameFavorites.cfg", &game_set_num); + char GXGameFavorites_cfg[32]; + sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice); + return cfg_parsefile(GXGameFavorites_cfg, &game_set_num); } bool cfg_save_games() { FILE *f; int i; - mkdir("SD:/config/", 0777); - f = fopen("SD:/config/GXGameSettings.cfg", "w"); + char GXGameSettings_cfg[32]; + sprintf(GXGameSettings_cfg, "%s/config", bootDevice); + mkdir(GXGameSettings_cfg, 0777); + + sprintf(GXGameSettings_cfg, "%s/config/GXGameSettings.cfg", bootDevice); + f = fopen(GXGameSettings_cfg, "w"); if (!f) { printf("Error saving %s\n", "GXGameSettings.cfg"); sleep(1); @@ -1396,7 +1408,7 @@ bool cfg_save_games() fprintf(f, "# note: this file is automatically generated\n"); fclose(f); /* Closing and reopening because of a write issue we are having right now */ - f = fopen("SD:/config/GXGameSettings.cfg", "w"); + f = fopen(GXGameSettings_cfg, "w"); fprintf(f, "# USB Loader settings file\n"); fprintf(f, "# note: this file is automatically generated\n"); fprintf(f, "# Num Games: %d\n", num_saved_games); @@ -1422,8 +1434,12 @@ bool cfg_save_game_num() { FILE *f; int i; - mkdir("SD:/config/", 0777); - f = fopen("SD:/config/GXGameFavorites.cfg", "w"); + char GXGameFavorites_cfg[32]; + sprintf(GXGameFavorites_cfg, "%s/config", bootDevice); + mkdir(GXGameFavorites_cfg, 0777); + + sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice); + f = fopen(GXGameFavorites_cfg, "w"); if (!f) { printf("Error saving %s\n", "GXGameFavorites.cfg"); sleep(1); @@ -1433,7 +1449,7 @@ bool cfg_save_game_num() fprintf(f, "# note: this file is automatically generated\n"); fclose(f); /* Closing and reopening because of a write issue we are having right now */ - f = fopen("SD:/config/GXGameFavorites.cfg", "w"); + f = fopen(GXGameFavorites_cfg, "w"); fprintf(f, "# USB Loader settings file\n"); fprintf(f, "# note: this file is automatically generated\n"); fprintf(f, "# Num Games: %d\n", num_saved_game_num); @@ -1449,6 +1465,8 @@ bool cfg_save_game_num() bool cfg_load_global() { + char GXGlobal_cfg[26]; + sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice); //Default values defined by dev team Settings.video = discdefault; Settings.vpatch = off; @@ -1469,7 +1487,7 @@ bool cfg_load_global() Settings.volume = 80; Settings.sfxvolume = 80; - return cfg_parsefile("SD:/config/GXGlobal.cfg", &global_cfg_set); + return cfg_parsefile(GXGlobal_cfg, &global_cfg_set); } @@ -1537,7 +1555,7 @@ void CFG_Load(void) CFG_Default(-1); // set defaults non forced - snprintf(pathname, sizeof(pathname), "SD:/config/GXGlobal.cfg"); + snprintf(pathname, sizeof(pathname), "%s/config/GXGlobal.cfg", bootDevice); cfg_parsefile(pathname, &widescreen_set); //first set widescreen cfg_parsefile(pathname, &path_set); //then set config and layout options @@ -1551,7 +1569,8 @@ void CFG_Load(void) snprintf(pathname, sizeof(pathname), "%stitles.txt", Settings.titlestxt_path); cfg_parsefile(pathname, &title_set); - cfg_parsefile("SD:/config/GXGameSettings.cfg", &parental_set); + snprintf(pathname, sizeof(pathname), "%s/config/GXGameSettings.cfg", bootDevice); + cfg_parsefile(pathname, &parental_set); // load per-game settings cfg_load_games(); @@ -1570,7 +1589,9 @@ void CFG_Load(void) void CFG_LoadGlobal(void) { - cfg_parsefile("SD:/config/GXGlobal.cfg", &global_cfg_set); + char GXGlobal_cfg[26]; + sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice); + cfg_parsefile(GXGlobal_cfg, &global_cfg_set); } void CFG_Cleanup(void) diff --git a/source/cfg.h b/source/cfg.h index 4fb3385e..b555ab25 100644 --- a/source/cfg.h +++ b/source/cfg.h @@ -41,7 +41,8 @@ extern "C" #define CFG_ALIGN_BOTTOM 4 #define CFG_ALIGN_MIDDLE 5 -extern char *cfg_path; +extern char bootDevice[10]; +//extern char *cfg_path; struct CFG { @@ -161,6 +162,7 @@ extern u8 wsprompt; extern u8 keyset; extern u8 gameDisplay; + struct Game_CFG { u8 id[8]; diff --git a/source/fatmounter.c b/source/fatmounter.c index cfa49165..d432d9b1 100644 --- a/source/fatmounter.c +++ b/source/fatmounter.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,21 +7,154 @@ #include #include #include +#include "usbstorage.h" //these are the only stable and speed is good #define CACHE 32 #define SECTORS 128 +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'}; + +#define BYTES_PER_READ 512 + +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 USBDevice_Init() { - return 0; //closing all open Files write back the cache and then shutdown em! - __io_usbstorage.startup(); - fatUnmount("USB:/"); - //right now only mounts first partition - if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) { + //right now mounts first FAT-partition + if (fatMount("USB", &__io_usbstorage, GetFATPartition(&__io_usbstorage), CACHE, SECTORS)) { + //try first mount with libogc + return 1; + } else if (fatMount("USB", &__io_wiiums, GetFATPartition(&__io_wiiums), CACHE, SECTORS)) { + //try now mount with cIOS return 1; } return -1; @@ -28,10 +162,8 @@ int USBDevice_Init() void USBDevice_deInit() { - return; //closing all open Files write back the cache and then shutdown em! fatUnmount("USB:/"); - __io_usbstorage.shutdown(); } int isSdInserted() @@ -39,14 +171,21 @@ int isSdInserted() return __io_wiisd.isInserted(); } +DISC_INTERFACE **_FAT_partition_getPartitionFromPath (const char* path); +int isInserted(const char *path) +{ + if(!strncmp(path, "USB:", 4)) + return 1; +// if(!strncmp(path, "SD:", 3)) + return __io_wiisd.isInserted(); + return 0; +} int SDCard_Init() { //closing all open Files write back the cache and then shutdown em! - __io_wiisd.startup(); - fatUnmount("SD:/"); - //right now only mounts first partition - if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) + //right now mounts first FAT-partition + if (fatMount("SD", &__io_wiisd, GetFATPartition(&__io_wiisd), CACHE, SECTORS)) return 1; return -1; } @@ -55,5 +194,4 @@ void SDCard_deInit() { //closing all open Files write back the cache and then shutdown em! fatUnmount("SD:/"); - __io_wiisd.shutdown(); } diff --git a/source/fatmounter.h b/source/fatmounter.h index e2357020..90154b6d 100644 --- a/source/fatmounter.h +++ b/source/fatmounter.h @@ -9,6 +9,7 @@ extern "C" int USBDevice_Init(); void USBDevice_deInit(); int isSdInserted(); +int isInserted(const char *path); int SDCard_Init(); void SDCard_deInit(); diff --git a/source/fst.c b/source/fst.c index 18770a8e..725891d0 100644 --- a/source/fst.c +++ b/source/fst.c @@ -54,7 +54,6 @@ u32 do_sd_code(char *filename) u32 ret; char filepath[128]; - __io_wiisd.startup(); ret = fatMountSimple("SD", &__io_wiisd); if (!ret) { @@ -74,7 +73,6 @@ u32 do_sd_code(char *filename) fp = fopen(filepath, "rb"); if (!fp) { fatUnmount("SD:/"); - __io_wiisd.shutdown(); return 0; } @@ -94,7 +92,6 @@ u32 do_sd_code(char *filename) free(filebuff); fclose(fp); fatUnmount("SD:/"); - __io_wiisd.shutdown(); return 0; } @@ -107,7 +104,6 @@ u32 do_sd_code(char *filename) fclose(fp); fatUnmount("SD:/"); - __io_wiisd.shutdown(); return 1; } diff --git a/source/listfiles.c b/source/listfiles.c index 9a1d1619..f36fd833 100644 --- a/source/listfiles.c +++ b/source/listfiles.c @@ -48,31 +48,24 @@ s32 filenamescmp(const void *a, const void *b) int GetAllDirFiles(char * filespath) { - -int countfiles = 0; - -struct stat st; -DIR_ITER* dir; -dir = diropen (filespath); - -if (dir == NULL) //If empty - { + int countfiles = 0; + + struct stat st; + DIR_ITER* dir; + dir = diropen (filespath); + + if (dir == NULL) //If empty return 0; - } - else - { while (dirnext(dir,filenames,&st) == 0) - { + { if ((st.st_mode & S_IFDIR) == 0) - { + { // st.st_mode & S_IFDIR indicates a directory snprintf(alldirfiles[countfiles], 70, "%s", filenames); countfiles++; - } } } - + dirclose(dir); qsort(alldirfiles, countfiles, sizeof(char[70]), filenamescmp); - -return countfiles; + return countfiles; } diff --git a/source/main.cpp b/source/main.cpp index e403b085..f8dabcc7 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -68,12 +69,32 @@ main(int argc, char *argv[]) { s32 ret2; + + SDCard_Init(); // mount SD for loading cfg's + USBDevice_Init(); // and mount USB:/ + bool bootDevice_found=false; + if(argc >= 1) + { + if(!strncasecmp(argv[0], "usb:/", 5)) + { + strcpy(bootDevice, "USB:"); + bootDevice_found = true; + } + else if(!strncasecmp(argv[0], "sd:/", 4)) + bootDevice_found = true; + } + if(!bootDevice_found) + { + //try USB + if((stat("USB:/apps/usbloader_gx/boot.dol", NULL) == 0) || (stat("USB:/apps/usbloader_gx/boot.elf", NULL) == 0)) + strcpy(bootDevice, "USB:"); + } - SDCard_Init(); // mount SD for loading cfg's lang_default(); CFG_Load(); SDCard_deInit();// unmount SD for reloading IOS + USBDevice_deInit();// unmount USB for reloading IOS /* Load Custom IOS */ if(Settings.cios == ios222) { diff --git a/source/menu.cpp b/source/menu.cpp index 77544a0e..db75d5c7 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -688,7 +688,8 @@ static int MenuDiscList() else if (Settings.gameDisplay==carousel){ startat = gameCarousel->GetSelectedOption(); offset = gameCarousel->GetOffset();} - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { CFG_Load(); } sdcardBtn.ResetState(); @@ -698,7 +699,8 @@ static int MenuDiscList() else if(DownloadBtn.GetState() == STATE_CLICKED) { - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { choice = WindowPrompt(LANGUAGE.CoverDownload, 0, LANGUAGE.NormalCovers, LANGUAGE.t3Covers, LANGUAGE.DiscImages, LANGUAGE.Back); // ask for download choice if (choice != 0) @@ -771,7 +773,8 @@ static int MenuDiscList() else if(favoriteBtn.GetState() == STATE_CLICKED) { Settings.fave=!Settings.fave; - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); } __Menu_GetEntries(); @@ -797,7 +800,8 @@ static int MenuDiscList() { if(Settings.sort != all) { Settings.sort=all; - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); } __Menu_GetEntries(); @@ -826,7 +830,8 @@ static int MenuDiscList() { if(Settings.sort != pcount) { Settings.sort=pcount; - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { cfg_save_global(); } __Menu_GetEntries(); @@ -1223,7 +1228,8 @@ static int MenuDiscList() }count+=1; - if(isSdInserted()) { + //if(isSdInserted()) { + if(isInserted(bootDevice)) { if (CFG_save_game_num(header->id)) { //WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0); diff --git a/source/usbstorage.c b/source/usbstorage.c index ed5ebc39..916e6417 100644 --- a/source/usbstorage.c +++ b/source/usbstorage.c @@ -184,3 +184,88 @@ s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer) return ret; } + + +#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S') + + +bool umsio_Startup() +{ + return USBStorage_Init() == 0; +} + +bool umsio_IsInserted() +{ + return true; // allways true +} +bool umsio_ReadSectors(sec_t sector, sec_t numSectors, u8 *buffer) +{ + u32 cnt = 0; + s32 ret; + /* Do reads */ + while (cnt < numSectors) + { + u32 sectors = (numSectors - cnt); + + /* Read sectors is too big */ + if (sectors > 32) + sectors = 32; + + /* USB read */ + ret = USBStorage_ReadSectors(sector + cnt, sectors, &buffer[cnt*512]); + if (ret < 0) + return false; + + /* Increment counter */ + cnt += sectors; + } + + return true; +} + +bool umsio_WriteSectors(sec_t sector, sec_t numSectors, const u8* buffer) +{ + u32 cnt = 0; + s32 ret; + + /* Do writes */ + while (cnt < numSectors) + { + u32 sectors = (numSectors - cnt); + + /* Write sectors is too big */ + if (sectors > 32) + sectors = 32; + + /* USB write */ + ret = USBStorage_WriteSectors(sector + cnt, sectors, &buffer[cnt * 512]); + if (ret < 0) + return false; + + /* Increment counter */ + cnt += sectors; + } + + return true; +} +bool umsio_ClearStatus(void) +{ + return true; +} + +bool umsio_Shutdown() +{ + USBStorage_Deinit(); + return true; +} +const DISC_INTERFACE __io_wiiums = +{ +DEVICE_TYPE_WII_UMS, +FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB, +(FN_MEDIUM_STARTUP)&umsio_Startup, + (FN_MEDIUM_ISINSERTED)&umsio_IsInserted, + (FN_MEDIUM_READSECTORS)&umsio_ReadSectors, + (FN_MEDIUM_WRITESECTORS)&umsio_WriteSectors, + (FN_MEDIUM_CLEARSTATUS)&umsio_ClearStatus, + (FN_MEDIUM_SHUTDOWN)&umsio_Shutdown +}; diff --git a/source/usbstorage.h b/source/usbstorage.h index ed6fc2e2..9cdb12c8 100644 --- a/source/usbstorage.h +++ b/source/usbstorage.h @@ -10,8 +10,8 @@ s32 USBStorage_GetCapacity(u32 *); s32 USBStorage_Init(void); void USBStorage_Deinit(void); s32 USBStorage_ReadSectors(u32, u32, void *); -s32 USBStorage_WriteSectors(u32, u32, void *); - +s32 USBStorage_WriteSectors(u32, u32, const void *); +extern const DISC_INTERFACE __io_wiiums; #ifdef __cplusplus } #endif diff --git a/source/wbfs.h b/source/wbfs.h index dda14c34..b396c00e 100644 --- a/source/wbfs.h +++ b/source/wbfs.h @@ -34,6 +34,10 @@ s32 WBFS_GameSize(u8 *, f32 *); s32 WBFS_DiskSpace(f32 *, f32 *); s32 WBFS_RenameGame(u8 *, const void *); f32 WBFS_EstimeGameSize(void); + +s32 __WBFS_ReadUSB(void *fp, u32 lba, u32 count, void *iobuf); +s32 __WBFS_WriteUSB(void *fp, u32 lba, u32 count, void *iobuf); + #ifdef __cplusplus }