-lets use the old gui_sound.cpp, because we shouldnt force set

the memory we use for them, not that we get problems
-added debug prints about how much mem left before and after
cleanup
-updated devicehandler, partition handler and usb code to the 
latest usb loader gx one, should give more compatility and
port 1 support (not enabled yet)
This commit is contained in:
fix94.1 2012-07-18 14:09:28 +00:00
parent 71e0d1e425
commit 5640028b17
14 changed files with 953 additions and 928 deletions

View File

@ -23,7 +23,7 @@
* *
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <malloc.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <ogc/mutex.h> #include <ogc/mutex.h>
@ -42,7 +42,6 @@ extern const DISC_INTERFACE __io_sdhc;
#endif #endif
DeviceHandler * DeviceHandler::instance = NULL; DeviceHandler * DeviceHandler::instance = NULL;
unsigned int DeviceHandler::watchdog_timeout = 10;
DeviceHandler::~DeviceHandler() DeviceHandler::~DeviceHandler()
{ {
@ -52,14 +51,18 @@ DeviceHandler::~DeviceHandler()
DeviceHandler * DeviceHandler::Instance() DeviceHandler * DeviceHandler::Instance()
{ {
if (instance == NULL) if (instance == NULL)
{
instance = new DeviceHandler(); instance = new DeviceHandler();
}
return instance; return instance;
} }
void DeviceHandler::DestroyInstance() void DeviceHandler::DestroyInstance()
{ {
if(instance) delete instance; if(instance)
{
delete instance;
}
instance = NULL; instance = NULL;
} }
@ -67,38 +70,39 @@ bool DeviceHandler::MountAll()
{ {
bool result = false; bool result = false;
for(u32 i = SD; i <= USB8; i++) for(u32 i = SD; i < MAXDEVICES; i++)
if(Mount(i)) result = true; {
if(Mount(i))
result = true;
}
return result; return result;
} }
void DeviceHandler::UnMountAll() void DeviceHandler::UnMountAll()
{ {
for(u32 i = SD; i <= GCSDB; i++) for(u32 i = SD; i < MAXDEVICES; i++)
UnMount(i); UnMount(i);
if(sd) delete sd; if(sd)
if(usb) delete usb; delete sd;
if(gca) delete gca; if(usb0)
if(gcb) delete gca; delete usb0;
if(usb1)
delete usb1;
sd = NULL; sd = NULL;
usb = NULL; usb0 = NULL;
gca = NULL; usb1 = NULL;
gcb = NULL;
} }
bool DeviceHandler::Mount(int dev) bool DeviceHandler::Mount(int dev)
{ {
if(dev == SD) if(dev == SD)
return MountSD(); return MountSD();
else if(dev >= USB1 && dev <= USB8) else if(dev >= USB1 && dev <= USB8)
return MountUSB(dev-USB1); return MountUSB(dev-USB1);
else if(dev == GCSDA)
return MountGCA();
else if(dev == GCSDB)
return MountGCB();
return false; return false;
} }
@ -107,12 +111,14 @@ bool DeviceHandler::IsInserted(int dev)
{ {
if(dev == SD) if(dev == SD)
return SD_Inserted() && sd->IsMounted(0); return SD_Inserted() && sd->IsMounted(0);
else if(dev >= USB1 && dev <= USB8) else if(dev >= USB1 && dev <= USB8)
return USB_Inserted() && usb->IsMounted(dev-USB1); {
else if(dev == GCSDA) int portPart = PartitionToPortPartition(dev-USB1);
return GCA_Inserted() && gca->IsMounted(0); PartitionHandle *usb = instance->GetUSBHandleFromPartition(dev-USB1);
else if(dev == GCSDB) if(usb)
return GCB_Inserted() && gcb->IsMounted(0); return usb->IsMounted(portPart);
}
return false; return false;
} }
@ -121,12 +127,9 @@ void DeviceHandler::UnMount(int dev)
{ {
if(dev == SD) if(dev == SD)
UnMountSD(); UnMountSD();
else if(dev >= USB1 && dev <= USB8) else if(dev >= USB1 && dev <= USB8)
UnMountUSB(dev-USB1); UnMountUSB(dev-USB1);
else if(dev == GCSDA)
UnMountGCA();
else if(dev == GCSDB)
UnMountGCB();
} }
bool DeviceHandler::MountSD() bool DeviceHandler::MountSD()
@ -146,114 +149,121 @@ bool DeviceHandler::MountSD()
} }
//! Mount only one SD Partition //! Mount only one SD Partition
return sd->Mount(0, DeviceName[SD]); return sd->Mount(0, DeviceName[SD], true);
} }
bool DeviceHandler::MountUSB(int pos) bool DeviceHandler::MountUSB(int pos)
{ {
if(!usb) usb = new PartitionHandle(&__io_usbstorage); if(!usb0 && !usb1)
if(usb->GetPartitionCount() < 1)
{
delete usb;
usb = NULL;
return false;
}
// Set the watchdog
InternalSetWatchdog(watchdog_timeout);
if(pos >= usb->GetPartitionCount())
return false; return false;
return usb->Mount(pos, DeviceName[USB1+pos]); if(pos >= GetUSBPartitionCount())
return false;
int portPart = PartitionToPortPartition(pos);
if(PartitionToUSBPort(pos) == 0 && usb0)
return usb0->Mount(portPart, DeviceName[USB1+pos]);
else if(usb1)
return usb1->Mount(portPart, DeviceName[USB1+pos]);
return false;
} }
bool DeviceHandler::MountAllUSB() bool DeviceHandler::MountAllUSB()
{ {
if(!usb) usb = new PartitionHandle(&__io_usbstorage); if(!usb0)
usb0 = new PartitionHandle(GetUSB0Interface());
//if(!usb1 && (Settings.USBPort == 1 || Settings.USBPort == 2))
//usb1 = new PartitionHandle(GetUSB1Interface());
if(usb0 && usb0->GetPartitionCount() < 1)
{
delete usb0;
usb0 = NULL;
}
if(usb1 && usb1->GetPartitionCount() < 1)
{
delete usb1;
usb1 = NULL;
}
bool result = false; bool result = false;
int partCount = GetUSBPartitionCount();
for(int i = 0; i < usb->GetPartitionCount(); i++) for(int i = 0; i < partCount; i++)
{
if(MountUSB(i)) if(MountUSB(i))
result = true; result = true;
}
return result; return result;
} }
bool DeviceHandler::MountGCA() bool DeviceHandler::MountUSBPort1()
{ {
if(!gca) gca = new PartitionHandle(&__io_gcsda); if(!usb1)// && (Settings.USBPort == 1 || Settings.USBPort == 2))
usb1 = new PartitionHandle(GetUSB1Interface());
if(gca->GetPartitionCount() < 1) if(usb1 && usb1->GetPartitionCount() < 1)
{ {
delete gca; delete usb1;
gca = NULL; usb1 = NULL;
return false; return false;
} }
//! Mount only one Partition bool result = false;
return gca->Mount(0, DeviceName[GCSDA]); int partCount = GetUSBPartitionCount();
int partCount0 = 0;
if(usb0)
partCount0 = usb0->GetPartitionCount();
for(int i = partCount0; i < partCount; i++)
{
if(MountUSB(i))
result = true;
} }
bool DeviceHandler::MountGCB() return result;
{
if(!gcb) gcb = new PartitionHandle(&__io_gcsdb);
if(gcb->GetPartitionCount() < 1)
{
delete gcb;
gcb = NULL;
return false;
}
//! Mount only one Partition
return gcb->Mount(0, DeviceName[GCSDB]);;
} }
void DeviceHandler::UnMountUSB(int pos) void DeviceHandler::UnMountUSB(int pos)
{ {
if(!usb) return; if(pos >= GetUSBPartitionCount())
if(pos >= usb->GetPartitionCount())
return; return;
usb->UnMount(pos); int portPart = PartitionToPortPartition(pos);
if(PartitionToUSBPort(pos) == 0 && usb0)
return usb0->UnMount(portPart);
else if(usb1)
return usb1->UnMount(portPart);
} }
void DeviceHandler::UnMountAllUSB() void DeviceHandler::UnMountAllUSB()
{ {
if(!usb) return; int partCount = GetUSBPartitionCount();
for(int i = 0; i < usb->GetPartitionCount(); i++) for(int i = 0; i < partCount; i++)
usb->UnMount(i); UnMountUSB(i);
delete usb; delete usb0;
usb = NULL; usb0 = NULL;
} delete usb1;
usb1 = NULL;
bool DeviceHandler::InternalSetWatchdog(unsigned int timeout)
{
if (Instance()->USB_Inserted())
return USBStorage_SetWatchdog(timeout) == 0;
return false;
}
bool DeviceHandler::SetWatchdog(unsigned int timeout)
{
watchdog_timeout = timeout;
return InternalSetWatchdog(timeout);
} }
int DeviceHandler::PathToDriveType(const char * path) int DeviceHandler::PathToDriveType(const char * path)
{ {
if(!path) return -1; if(!path)
return -1;
for(int i = SD; i <= GCSDB; i++) for(int i = SD; i < MAXDEVICES; i++)
if(strncmp(path, DeviceName[i], strlen(DeviceName[i])) == 0) {
if(strncasecmp(path, DeviceName[i], strlen(DeviceName[i])) == 0)
return i; return i;
}
return -1; return -1;
} }
@ -261,61 +271,71 @@ int DeviceHandler::PathToDriveType(const char * path)
const char * DeviceHandler::GetFSName(int dev) const char * DeviceHandler::GetFSName(int dev)
{ {
if(dev == SD && DeviceHandler::instance->sd) if(dev == SD && DeviceHandler::instance->sd)
{
return DeviceHandler::instance->sd->GetFSName(0); return DeviceHandler::instance->sd->GetFSName(0);
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb) }
return DeviceHandler::instance->usb->GetFSName(dev-USB1); else if(dev >= USB1 && dev <= USB8)
else if(dev == GCSDA && DeviceHandler::instance->gca) {
return DeviceHandler::instance->gca->GetFSName(0); int partCount0 = 0;
else if(dev == GCSDB && DeviceHandler::instance->gcb) int partCount1 = 0;
return DeviceHandler::instance->gcb->GetFSName(0); if(DeviceHandler::instance->usb0)
partCount0 += DeviceHandler::instance->usb0->GetPartitionCount();
if(DeviceHandler::instance->usb1)
partCount1 += DeviceHandler::instance->usb1->GetPartitionCount();
return NULL; if(dev-USB1 < partCount0 && DeviceHandler::instance->usb0)
return DeviceHandler::instance->usb0->GetFSName(dev-USB1);
else if(DeviceHandler::instance->usb1)
return DeviceHandler::instance->usb1->GetFSName(dev-USB1-partCount0);
}
return "";
} }
int DeviceHandler::GetFSType(int dev) int DeviceHandler::GetFSType(int dev)
{ {
const char *name = GetFSName(dev); if(!instance)
if(!name) return -1; return -1;
if (strncasecmp(name, "WBFS", 4) == 0) const char *FSName = GetFSName(dev);
if(!FSName) return -1;
if(strncmp(FSName, "WBFS", 4) == 0)
return PART_FS_WBFS; return PART_FS_WBFS;
else if (strncasecmp(name, "FAT", 3) == 0) else if(strncmp(FSName, "FAT", 3) == 0)
return PART_FS_FAT; return PART_FS_FAT;
else if (strncasecmp(name, "NTFS", 4) == 0) else if(strncmp(FSName, "NTFS", 4) == 0)
return PART_FS_NTFS; return PART_FS_NTFS;
else if (strncasecmp(name, "LINUX", 5) == 0) else if(strncmp(FSName, "LINUX", 4) == 0)
return PART_FS_EXT; return PART_FS_EXT;
return -1; return -1;
} }
s16 DeviceHandler::GetMountedCount(int dev)
{
if(dev == SD && DeviceHandler::instance->sd && IsInserted(SD))
return 1;
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb)
for(int i = 0; i < usb->GetPartitionCount(); i++)
{
if(!IsInserted(i)) return i;
}
else if(dev == GCSDA && DeviceHandler::instance->gca && IsInserted(GCSDA))
return 1;
else if(dev == GCSDB && DeviceHandler::instance->gcb && IsInserted(GCSDB))
return 1;
return -1; u16 DeviceHandler::GetUSBPartitionCount()
{
if(!instance)
return 0;
u16 partCount0 = 0;
u16 partCount1 = 0;
if(instance->usb0)
partCount0 = instance->usb0->GetPartitionCount();
if(instance->usb1)
partCount1 = instance->usb1->GetPartitionCount();
return partCount0+partCount1;
} }
wbfs_t * DeviceHandler::GetWbfsHandle(int dev) wbfs_t * DeviceHandler::GetWbfsHandle(int dev)
{ {
if(dev == SD && DeviceHandler::instance->sd) if(dev == SD && DeviceHandler::instance->sd)
return DeviceHandler::instance->sd->GetWbfsHandle(0); return DeviceHandler::instance->sd->GetWbfsHandle(0);
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb) else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb0)
return DeviceHandler::instance->usb->GetWbfsHandle(dev-USB1); return DeviceHandler::instance->usb0->GetWbfsHandle(dev-USB1);
else if(dev == GCSDA && DeviceHandler::instance->gca) else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb1)
return DeviceHandler::instance->gca->GetWbfsHandle(0); return DeviceHandler::instance->usb1->GetWbfsHandle(dev-USB1);
else if(dev == GCSDB && DeviceHandler::instance->gcb)
return DeviceHandler::instance->gcb->GetWbfsHandle(0);
return NULL; return NULL;
} }
@ -331,13 +351,48 @@ s32 DeviceHandler::Open_WBFS(int dev)
else if(dev >= USB1 && dev <= USB8 && IsInserted(dev)) else if(dev >= USB1 && dev <= USB8 && IsInserted(dev))
{ {
part_idx = dev; part_idx = dev;
part_lba = Instance()->usb->GetLBAStart(dev - USB1); part_lba = Instance()->usb0->GetLBAStart(dev - USB1);
} }
else if(dev == GCSDA && IsInserted(dev)) else
part_lba = Instance()->gca->GetLBAStart(dev); return -1;
else if(dev == GCSDB && IsInserted(dev))
part_lba = Instance()->gcb->GetLBAStart(dev);
else return -1;
return WBFS_Init(GetWbfsHandle(dev), part_fs, part_idx, part_lba, partition, dev); return WBFS_Init(GetWbfsHandle(dev), part_fs, part_idx, part_lba, partition, dev);
} }
int DeviceHandler::PartitionToUSBPort(int part)
{
if(!DeviceHandler::instance)
return 0;
u16 partCount0 = 0;
if(DeviceHandler::instance->usb0)
partCount0 = instance->usb0->GetPartitionCount();
if(!instance->usb0 || part >= partCount0)
return 1;
else
return 0;
}
int DeviceHandler::PartitionToPortPartition(int part)
{
if(!DeviceHandler::instance)
return 0;
u16 partCount0 = 0;
if(instance->usb0)
partCount0 = instance->usb0->GetPartitionCount();
if(!instance->usb0 || part >= partCount0)
return part-partCount0;
else
return part;
}
PartitionHandle *DeviceHandler::GetUSBHandleFromPartition(int part) const
{
if(PartitionToUSBPort(part) == 0)
return usb0;
else
return usb1;
}

View File

@ -27,7 +27,12 @@
#define DEVICE_HANDLER_HPP_ #define DEVICE_HANDLER_HPP_
#include "PartitionHandle.h" #include "PartitionHandle.h"
#include "usbstorage.h"
#include "libwbfs/libwbfs.h"
/**
* libogc device names.
*/
enum enum
{ {
SD = 0, SD = 0,
@ -39,12 +44,13 @@ enum
USB6, USB6,
USB7, USB7,
USB8, USB8,
GCSDA,
GCSDB,
MAXDEVICES MAXDEVICES
}; };
const char DeviceName[MAXDEVICES][6] = /**
* libogc device names.
*/
const char DeviceName[MAXDEVICES][8] =
{ {
"sd", "sd",
"usb1", "usb1",
@ -55,8 +61,6 @@ const char DeviceName[MAXDEVICES][6] =
"usb6", "usb6",
"usb7", "usb7",
"usb8", "usb8",
"gca",
"gcb",
}; };
class DeviceHandler class DeviceHandler
@ -73,49 +77,46 @@ class DeviceHandler
//! Individual Mounts/UnMounts... //! Individual Mounts/UnMounts...
bool MountSD(); bool MountSD();
bool MountUSB(int part);
bool MountAllUSB(); bool MountAllUSB();
bool MountGCA(); bool MountUSBPort1();
bool MountGCB();
bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; }; bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; }
bool USB_Inserted() { if(usb) return usb->IsInserted(); return false; }; bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; }
bool GCA_Inserted() { if(gca) return gca->IsInserted(); return false; }; bool USB1_Inserted() { if(usb1) return usb1->IsInserted(); return false; }
bool GCB_Inserted() { if(gcb) return gcb->IsInserted(); return false; };
void UnMountSD() { if(sd) delete sd; sd = NULL; }; void UnMountSD() { if(sd) delete sd; sd = NULL; }
void UnMountUSB(int pos); void UnMountUSB(int pos);
void UnMountAllUSB(); void UnMountAllUSB();
void UnMountGCA() { if(gca) delete gca; gca = NULL; };
void UnMountGCB() { if(gcb) delete gcb; gcb = NULL; };
const PartitionHandle * GetSDHandle() { return sd; }; PartitionHandle * GetSDHandle() const { return sd; }
const PartitionHandle * GetUSBHandle() { return usb; }; PartitionHandle * GetUSB0Handle() const { return usb0; }
const PartitionHandle * GetGCAHandle() { return gca; }; PartitionHandle * GetUSB1Handle() const { return usb1; }
const PartitionHandle * GetGCBHandle() { return gcb; };
PartitionHandle * GetUSBHandleFromPartition(int part) const;
static const DISC_INTERFACE *GetUSB0Interface() { return &__io_usbstorage2_port0; }
static const DISC_INTERFACE *GetUSB1Interface() { return &__io_usbstorage2_port1; }
static bool SetWatchdog(unsigned int timeout);
static int PathToDriveType(const char * path); static int PathToDriveType(const char * path);
static const char * GetFSName(int dev); static const char * GetFSName(int dev);
static int GetFSType(int dev); static int GetFSType(int dev);
s16 GetMountedCount(int dev); static u16 GetUSBPartitionCount();
static const char * PathToFSName(const char * path) { return GetFSName(PathToDriveType(path)); }; static const char * PathToFSName(const char * path) { return GetFSName(PathToDriveType(path)); }
static wbfs_t *GetWbfsHandle(int dev); static wbfs_t *GetWbfsHandle(int dev);
//static u32 GetLBAStart(int dev);
s32 Open_WBFS(int dev); s32 Open_WBFS(int dev);
static int PartitionToUSBPort(int part);
static int PartitionToPortPartition(int part);
private: private:
DeviceHandler() : sd(0), usb(0), gca(0), gcb(0) { }; DeviceHandler() : sd(0), gca(0), gcb(0), usb0(0), usb1(0) { }
~DeviceHandler(); ~DeviceHandler();
static bool InternalSetWatchdog(unsigned int timeout); bool MountUSB(int part);
static DeviceHandler *instance; static DeviceHandler *instance;
static unsigned int watchdog_timeout;
PartitionHandle * sd; PartitionHandle * sd;
PartitionHandle * usb;
PartitionHandle * gca; PartitionHandle * gca;
PartitionHandle * gcb; PartitionHandle * gcb;
PartitionHandle * usb0;
PartitionHandle * usb1;
}; };
#endif #endif

View File

@ -1,7 +1,6 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2010 * Copyright (C) 2010
* by Dimok * by Dimok
* modified for Debugging, GPT, WBFS, and EXT by Miigotu
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
@ -22,8 +21,7 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
* *
* By Dimok for WiiXplorer 2010 * for WiiXplorer 2010
* By Miigotu for WiiFlow 2010
***************************************************************************/ ***************************************************************************/
#include <gccore.h> #include <gccore.h>
#include <stdio.h> #include <stdio.h>
@ -47,18 +45,21 @@ extern const DISC_INTERFACE __io_sdhc;
#define PARTITION_TYPE_DOS33_EXTENDED 0x05 /* DOS 3.3+ extended partition */ #define PARTITION_TYPE_DOS33_EXTENDED 0x05 /* DOS 3.3+ extended partition */
#define PARTITION_TYPE_WIN95_EXTENDED 0x0F /* Windows 95 extended partition */ #define PARTITION_TYPE_WIN95_EXTENDED 0x0F /* Windows 95 extended partition */
#define PARTITION_TYPE_GPT_TABLE 0xEE /* New Standard */
//! libfat stuff
extern "C"
{
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc);
}
#define CACHE 32 #define CACHE 32
#define SECTORS 64 #define SECTORS 64
extern u32 sector_size;
static inline const char * PartFromType(int type) static inline const char * PartFromType(int type)
{ {
switch (type) switch (type)
{ {
case 0x00: return "Unused"; //Or WBFS case 0x00: return "Unused";
case 0x01: return "FAT12"; case 0x01: return "FAT12";
case 0x04: return "FAT16"; case 0x04: return "FAT16";
case 0x05: return "Extended"; case 0x05: return "Extended";
@ -74,22 +75,25 @@ static inline const char * PartFromType(int type)
case 0xa8: return "OSX"; case 0xa8: return "OSX";
case 0xab: return "OSXBT"; case 0xab: return "OSXBT";
case 0xaf: return "OSXHF"; case 0xaf: return "OSXHF";
case 0xbf: return "WBFS";
case 0xe8: return "LUKS"; case 0xe8: return "LUKS";
case 0xee: return "GPT";
default: return "Unknown"; default: return "Unknown";
} }
} }
PartitionHandle::PartitionHandle(const DISC_INTERFACE *discio) PartitionHandle::PartitionHandle(const DISC_INTERFACE *discio)
: interface(discio)
{ {
interface = discio;
// Sanity check // Sanity check
if(!interface) return; if (!interface)
return;
// Start the device and check that it is inserted // Start the device and check that it is inserted
if(!interface->startup()) return; if (!interface->startup())
if(!interface->isInserted()) return; return;
if (!interface->isInserted())
return;
FindPartitions(); FindPartitions();
} }
@ -114,42 +118,71 @@ bool PartitionHandle::IsMounted(int pos)
return true; return true;
} }
bool PartitionHandle::Mount(int pos, const char * name) bool PartitionHandle::Mount(int pos, const char * name, bool forceFAT)
{ {
if(!valid(pos)) return false; if(!valid(pos))
if(!name) return false; return false;
if(!name)
return false;
UnMount(pos); UnMount(pos);
if(pos >= (int) MountNameList.size()) if(pos >= (int) MountNameList.size())
MountNameList.resize(GetPartitionCount()); MountNameList.resize(pos+1);
MountNameList[pos] = name; MountNameList[pos] = name;
SetWbfsHandle(pos, NULL); SetWbfsHandle(pos, NULL);
if(strncmp(GetFSName(pos), "FAT", 3) == 0) //! Some stupid partition manager think they don't need to edit the freaken MBR.
//! So we need to check the first 64 sectors and see if some partition is there.
//! libfat does that by default so let's use it.
//! We do that only on sd not on usb.
if(forceFAT && (!GetFSName(pos) || strcmp(GetFSName(pos), "Unknown") == 0))
{
if (fatMount(MountNameList[pos].c_str(), interface, 0, CACHE, SECTORS))
{
sec_t FAT_startSector = FindFirstValidPartition(interface);
AddPartition("FAT", FAT_startSector, 0xdeadbeaf, true, 0x0c, 0);
return true;
}
}
if(strncmp(GetFSName(pos), "FAT", 3) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0)
{ {
if (fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS)) if (fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS))
return true;
}
else if(strncmp(GetFSName(pos), "NTFS", 4) == 0)
{ {
if(ntfsMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, NTFS_SU | NTFS_RECOVER)) if(strcmp(GetFSName(pos), "GUID-Entry") == 0)
PartitionList[pos].FSName = "FAT";
return true; return true;
} }
else if(strncmp(GetFSName(pos), "LINUX", 5) == 0) }
if(strncmp(GetFSName(pos), "NTFS", 4) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0)
{
if(ntfsMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER))
{
PartitionList[pos].FSName = "NTFS";
return true;
}
}
if(strncmp(GetFSName(pos), "LINUX", 5) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0)
{ {
if(ext2Mount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, EXT2_FLAG_DEFAULT)) if(ext2Mount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, EXT2_FLAG_DEFAULT))
{
PartitionList[pos].FSName = "LINUX";
return true; return true;
} }
}
else if(strncmp(GetFSName(pos), "WBFS", 4) == 0) else if(strncmp(GetFSName(pos), "WBFS", 4) == 0)
{ {
if(interface == &__io_usbstorage) if(interface == &__io_usbstorage2_port0 || interface == &__io_usbstorage2_port1)
SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadUSB, __WBFS_WriteUSB, NULL, sector_size, GetSecCount(pos), GetLBAStart(pos), 0)); SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadUSB, __WBFS_WriteUSB, NULL, USBStorage2_GetSectorSize(), GetSecCount(pos), GetLBAStart(pos), 0));
else if((neek2o() && interface == &__io_wiisd) || (!neek2o() && interface == &__io_sdhc)) else if((neek2o() && interface == &__io_wiisd) || (!neek2o() && interface == &__io_sdhc))
SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadSDHC, __WBFS_WriteSDHC, NULL, sector_size, GetSecCount(pos), GetLBAStart(pos), 0)); SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadSDHC, __WBFS_WriteSDHC, NULL, 512, GetSecCount(pos), GetLBAStart(pos), 0));
if(GetWbfsHandle(pos))
if(GetWbfsHandle(pos)) return true; return true;
} }
MountNameList[pos].clear(); MountNameList[pos].clear();
@ -159,105 +192,97 @@ bool PartitionHandle::Mount(int pos, const char * name)
void PartitionHandle::UnMount(int pos) void PartitionHandle::UnMount(int pos)
{ {
if(!interface) return; if(!interface)
return;
if(pos >= (int) MountNameList.size()) return; if(pos >= (int) MountNameList.size())
return;
if(MountNameList[pos].size() == 0) return; if(MountNameList[pos].size() == 0)
return;
char DeviceName[20]; char DeviceSyn[20];
snprintf(DeviceName, sizeof(DeviceName), "%s:", MountNameList[pos].c_str()); snprintf(DeviceSyn, sizeof(DeviceSyn), "%s:", MountNameList[pos].c_str());
wbfs_t* wbfshandle = GetWbfsHandle(pos); wbfs_t* wbfshandle = GetWbfsHandle(pos);
if(wbfshandle) wbfs_close(wbfshandle); if(wbfshandle) wbfs_close(wbfshandle);
SetWbfsHandle(pos, NULL); SetWbfsHandle(pos, NULL);
WBFS_Close(); WBFS_Close();
fatUnmount(DeviceName); //closing all open Files write back the cache
ntfsUnmount(DeviceName, true); fatUnmount(DeviceSyn);
ext2Unmount(DeviceName); //closing all open Files write back the cache
ntfsUnmount(DeviceSyn, true);
//Remove mount name from the list //closing all open Files write back the cache
ext2Unmount(DeviceSyn);
//Remove name from list
MountNameList[pos].clear(); MountNameList[pos].clear();
} }
bool PartitionHandle::IsExisting(u64 lba)
{
for(u32 i = 0; i < PartitionList.size(); ++i)
{
if(PartitionList[i].LBA_Start == lba)
return true;
}
return false;
}
int PartitionHandle::FindPartitions() int PartitionHandle::FindPartitions()
{ {
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR); MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
if(mbr == NULL) if(!mbr) return -1;
return -1;
// Read the first sector on the device // Read the first sector on the device
if (!interface->readSectors(0, 1, mbr)) if (!interface->readSectors(0, 1, mbr))
{ {
MEM2_free(mbr); free(mbr);
return 0; return -1;
} }
// Check if it's a RAW disc, without a partition table // If this is the devices master boot record
if(CheckRAW((VOLUME_BOOT_RECORD *)mbr))
{
MEM2_free(mbr);
return 1;
}
// Verify this is the device's master boot record
if (mbr->signature != MBR_SIGNATURE) if (mbr->signature != MBR_SIGNATURE)
{ {
MEM2_free(mbr); free(mbr);
return 0; return -1;
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i]; PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i];
VOLUME_BOOT_RECORD *vbr = (VOLUME_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR);
if(!vbr) if(partition->type == PARTITION_TYPE_GPT)
{ {
MEM2_free(mbr); int ret = CheckGPT(i);
return -1; if(ret == 0) // if it's a GPT we don't need to go on looking through the mbr anymore
return ret;
} }
if (le32(partition->lba_start) == 0) continue; // Invalid partition if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED)
if(!interface->readSectors(le32(partition->lba_start), 1, vbr)) continue;
// Check if the partition is WBFS
bool isWBFS = memcmp((u8 *)vbr, WBFS_SIGNATURE, sizeof(WBFS_SIGNATURE)) == 0;
if(!isWBFS && i == 0 && partition->type == PARTITION_TYPE_GPT_TABLE)
return CheckGPT() ? PartitionList.size() : 0;
if(!isWBFS && vbr->Signature != VBR_SIGNATURE && partition->type != 0x83) continue;
if(!isWBFS && (partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED))
{ {
CheckEBR(i, le32(partition->lba_start)); CheckEBR(i, le32(partition->lba_start));
continue; continue;
} }
if(isWBFS || le32(partition->block_count) > 0)
{
PartitionFS PartitionEntry = {"0",0,0,0,0,0,0,0};
PartitionEntry.FSName = isWBFS ? "WBFS" : PartFromType(partition->type);
PartitionEntry.LBA_Start = le32(partition->lba_start);
PartitionEntry.SecCount = isWBFS ? ((wbfs_head_t *)vbr)->n_hd_sec : le32(partition->block_count);
PartitionEntry.Bootable = (partition->status == PARTITION_BOOTABLE);
PartitionEntry.PartitionType = partition->type;
PartitionEntry.PartitionNum = i;
PartitionEntry.EBR_Sector = 0;
PartitionList.push_back(PartitionEntry); if(le32(partition->block_count) > 0 && !IsExisting(le32(partition->lba_start)))
{
AddPartition(PartFromType(partition->type), le32(partition->lba_start),
le32(partition->block_count), (partition->status == PARTITION_BOOTABLE),
partition->type, i);
} }
MEM2_free(vbr);
} }
MEM2_free(mbr);
return PartitionList.size(); free(mbr);
return 0;
} }
void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba) void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
{ {
EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR); EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
if(ebr == NULL) if(!ebr) return;
return;
sec_t next_erb_lba = 0; sec_t next_erb_lba = 0;
do do
@ -265,176 +290,136 @@ void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
// Read and validate the extended boot record // Read and validate the extended boot record
if (!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr)) if (!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr))
{ {
MEM2_free(ebr); free(ebr);
return; return;
} }
// Check if the partition is WBFS if (ebr->signature != EBR_SIGNATURE)
bool isWBFS = memcmp((u8 *)ebr, WBFS_SIGNATURE, sizeof(WBFS_SIGNATURE)) == 0;
if(!isWBFS && ebr->signature != EBR_SIGNATURE)
{ {
MEM2_free(ebr); free(ebr);
return; return;
} }
if(isWBFS || le32(ebr->partition.block_count) > 0) if(le32(ebr->partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr->partition.lba_start)))
{ {
PartitionFS PartitionEntry = {"0",0,0,0,0,0,0,0}; AddPartition(PartFromType(ebr->partition.type), ebr_lba + next_erb_lba + le32(ebr->partition.lba_start),
PartitionEntry.FSName = isWBFS ? "WBFS" : PartFromType(ebr->partition.type); le32(ebr->partition.block_count), (ebr->partition.status == PARTITION_BOOTABLE),
PartitionEntry.LBA_Start = ebr_lba + next_erb_lba + le32(ebr->partition.lba_start); ebr->partition.type, PartNum);
PartitionEntry.SecCount = isWBFS ? ((wbfs_head_t *)&ebr)->n_hd_sec : le32(ebr->partition.block_count);
PartitionEntry.Bootable = (ebr->partition.status == PARTITION_BOOTABLE);
PartitionEntry.PartitionType = ebr->partition.type;
PartitionEntry.PartitionNum = PartNum;
PartitionEntry.EBR_Sector = ebr_lba + next_erb_lba;
PartitionList.push_back(PartitionEntry);
} }
// Get the start sector of the current partition // Get the start sector of the current partition
// and the next extended boot record in the chain // and the next extended boot record in the chain
next_erb_lba = le32(ebr->next_ebr.lba_start); next_erb_lba = le32(ebr->next_ebr.lba_start);
} }
while(next_erb_lba > 0); while(next_erb_lba > 0);
MEM2_free(ebr);
free(ebr);
} }
bool PartitionHandle::CheckGPT(void) static const u8 TYPE_UNUSED[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
{ static const u8 TYPE_BIOS[16] = { 0x48,0x61,0x68,0x21,0x49,0x64,0x6F,0x6E,0x74,0x4E,0x65,0x65,0x64,0x45,0x46,0x49 };
GPT_PARTITION_TABLE *gpt = (GPT_PARTITION_TABLE *)MEM2_alloc(MAX_BYTES_PER_SECTOR); static const u8 TYPE_LINUX_MS_BASIC_DATA[16] = { 0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7 };
if(gpt == NULL)
return false;
bool success = false; // To return false unless at least 1 partition is verified
if(!interface->readSectors(1, 33, gpt)) int PartitionHandle::CheckGPT(u8 PartNum)
{ {
MEM2_free(gpt); GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_BYTES_PER_SECTOR);
return false; // To read all 128 possible partitions if(!gpt_header) return -1;
// Read and validate the extended boot record
if (!interface->readSectors(1, 1, gpt_header))
{
free(gpt_header);
return -1;
} }
// Verify this is the Primary GPT entry if(strncmp(gpt_header->magic, "EFI PART", 8) != 0)
if((strncmp(gpt->magic, GPT_SIGNATURE, 8) != 0)
|| (le32(gpt->Entry_Size) != 128)
|| (le64(gpt->Table_LBA) != 2)
|| (le64(gpt->Header_LBA) != 1)
|| (le64(gpt->First_Usable_LBA) != 34)
|| (gpt->Reserved != 0))
{ {
MEM2_free(gpt); free(gpt_header);
return false; return -1;
} }
for(u8 i = 0; i < le32(gpt->Num_Entries) && PartitionList.size() <= 8; i++) gpt_header->part_table_lba = le64(gpt_header->part_table_lba);
gpt_header->part_entries = le32(gpt_header->part_entries);
gpt_header->part_entry_size = le32(gpt_header->part_entry_size);
gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum);
u8 * sector_buf = new u8[MAX_BYTES_PER_SECTOR];
u64 next_lba = gpt_header->part_table_lba;
for(u32 i = 0; i < gpt_header->part_entries; ++i)
{ {
GUID_PARTITION_ENTRY *entry = (GUID_PARTITION_ENTRY *) &gpt->partitions[i]; if (!interface->readSectors(next_lba, 1, sector_buf))
VOLUME_BOOT_RECORD *vbr = (VOLUME_BOOT_RECORD*)MEM2_alloc(MAX_BYTES_PER_SECTOR); break;
if(vbr == NULL)
for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header->part_entry_size; ++n, ++i)
{ {
MEM2_free(gpt); GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n);
return false;
if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0)
continue;
if(IsExisting(le64(part_entry->part_first_lba)))
continue;
bool bootable = (memcmp(part_entry->part_type_guid, TYPE_BIOS, 16) == 0);
AddPartition("GUID-Entry", le64(part_entry->part_first_lba), le64(part_entry->part_last_lba), bootable, PARTITION_TYPE_GPT, PartNum);
} }
int Start = le64(entry->First_LBA); next_lba++;
int End = le64(entry->Last_LBA);
int Size = End - Start;
if(!interface->readSectors(Start, 1, vbr)) continue;
PartitionFS PartitionEntry = {"0",0,0,0,0,0,0,0};
if(memcmp((u8 *)vbr + BPB_NTFS_ADDR, NTFS_SIGNATURE, sizeof(NTFS_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "NTFS";
PartitionEntry.PartitionType = 0x07;
PartitionEntry.SecCount = le64(vbr->Number_of_Sectors);
}
else if(memcmp((u8 *)vbr + BPB_FAT32_ADDR, FAT_SIGNATURE, sizeof(FAT_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "FAT32";
PartitionEntry.PartitionType = 0x0c;
PartitionEntry.SecCount = le16(vbr->bpb.FatSectors);
if (PartitionEntry.SecCount == 0)
PartitionEntry.SecCount = le32(vbr->bpb.Large_Sectors);
}
else if(memcmp((u8 *)vbr + BPB_FAT16_ADDR, FAT_SIGNATURE, sizeof(FAT_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "FAT16";
PartitionEntry.PartitionType = 0x0e;
PartitionEntry.SecCount = le16(vbr->bpb.FatSectors);
if (PartitionEntry.SecCount == 0)
PartitionEntry.SecCount = le32(vbr->bpb.Large_Sectors);
}
else if(memcmp((u8 *)vbr, WBFS_SIGNATURE, sizeof(WBFS_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "WBFS";
PartitionEntry.SecCount = ((wbfs_head_t *)vbr)->n_hd_sec;
}
else
{
bzero(&PartitionEntry, sizeof(PartitionFS));
if(interface->readSectors(Start + 1, 1, vbr))
{
if(memcmp((u8 *)vbr + BPB_EXT2_ADDR, EXT_SIGNATURE, sizeof(EXT_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "LINUX";
PartitionEntry.PartitionType = 0x83;
PartitionEntry.SecCount = Size;
}
else continue;
}
else continue;
} }
if(PartitionEntry.SecCount != 0 && PartitionEntry.FSName[0] != '0') delete [] sector_buf;
{ free(gpt_header);
PartitionEntry.LBA_Start = Start;
PartitionEntry.PartitionNum = i;
success = true; return 0;
PartitionList.push_back(PartitionEntry);
}
MEM2_free(vbr);
}
MEM2_free(gpt);
return success;
} }
bool PartitionHandle::CheckRAW(VOLUME_BOOT_RECORD * vbr) void PartitionHandle::AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num)
{ {
PartitionFS PartitionEntry = {"0",0,0,0,0,0,0,0}; char *buffer = (char *) malloc(MAX_BYTES_PER_SECTOR);
if(memcmp((u8 *)vbr + BPB_NTFS_ADDR, NTFS_SIGNATURE, sizeof(NTFS_SIGNATURE)) == 0)
if (!interface->readSectors(lba_start, 1, buffer))
{ {
PartitionEntry.FSName = "NTFS"; free(buffer);
PartitionEntry.PartitionType = 0x07; return;
PartitionEntry.SecCount = le64(vbr->Number_of_Sectors);
}
else if(memcmp((u8 *)vbr + BPB_FAT32_ADDR, FAT_SIGNATURE, sizeof(FAT_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "FAT32";
PartitionEntry.PartitionType = 0x0c;
PartitionEntry.SecCount = le16(vbr->bpb.FatSectors);
if (PartitionEntry.SecCount == 0)
PartitionEntry.SecCount = le32(vbr->bpb.Large_Sectors);
}
else if(memcmp((u8 *)vbr + BPB_FAT16_ADDR, FAT_SIGNATURE, sizeof(FAT_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "FAT16";
PartitionEntry.PartitionType = 0x0e;
PartitionEntry.SecCount = le16(vbr->bpb.FatSectors);
if (PartitionEntry.SecCount == 0)
PartitionEntry.SecCount = le32(vbr->bpb.Large_Sectors);
}
else if(memcmp((u8 *)vbr, WBFS_SIGNATURE, sizeof(WBFS_SIGNATURE)) == 0)
{
PartitionEntry.FSName = "WBFS";
PartitionEntry.SecCount = ((wbfs_head_t *)vbr)->n_hd_sec;
} }
if(PartitionEntry.FSName[0] != '0') wbfs_head_t *head = (wbfs_head_t *) buffer;
if (head->magic == wbfs_htonl(WBFS_MAGIC))
{ {
PartitionList.push_back(PartitionEntry); name = "WBFS";
return true; part_type = 0xBF; //Override partition type on WBFS
//! correct sector size in physical sectors (512 bytes per sector)
sec_count = (u64) head->n_hd_sec * (u64) (1 << head->hd_sec_sz_s) / (u64) BYTES_PER_SECTOR;
} }
return false; else if(*((u16 *) (buffer + 0x1FE)) == 0x55AA)
{
//! Partition typ can be missleading the correct partition format. Stupid lazy ass Partition Editors.
if((memcmp(buffer + 0x36, "FAT", 3) == 0 || memcmp(buffer + 0x52, "FAT", 3) == 0) &&
strncmp(PartFromType(part_type), "FAT", 3) != 0)
{
name = "FAT32";
part_type = 0x0c;
}
if (memcmp(buffer + 0x03, "NTFS", 4) == 0)
{
name = "NTFS";
part_type = 0x07;
}
}
PartitionFS PartitionEntrie;
PartitionEntrie.FSName = name;
PartitionEntrie.LBA_Start = lba_start;
PartitionEntrie.SecCount = sec_count;
PartitionEntrie.Bootable = bootable;
PartitionEntrie.PartitionType = part_type;
PartitionEntrie.PartitionNum = part_num;
PartitionList.push_back(PartitionEntrie);
free(buffer);
} }

View File

@ -28,6 +28,7 @@
#include <gccore.h> #include <gccore.h>
#include "libwbfs/libwbfs.h" #include "libwbfs/libwbfs.h"
#include "usbstorage.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -39,27 +40,19 @@ using namespace std;
#define MBR_SIGNATURE 0x55AA #define MBR_SIGNATURE 0x55AA
#define EBR_SIGNATURE MBR_SIGNATURE #define EBR_SIGNATURE MBR_SIGNATURE
#define VBR_SIGNATURE MBR_SIGNATURE
#define GPT_SIGNATURE "EFI PART"
#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */ #define PARTITION_BOOTABLE 0x80 /* Bootable (active) */
#define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */ #define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */
#define PARTITION_TYPE_GPT 0xEE /* Indicates that a GPT header is available */
#define GUID_SYSTEM_PARTITION 0x0000000000000001LL /* System partition (disk partitioning utilities must reserve the partition as is) */
#define GUID_READ_ONLY_PARTITION 0x0800000000000000LL /* Read-only partition */
#define GUID_HIDDEN_PARTITION 0x2000000000000000LL /* Hidden partition */
#define GUID_NO_AUTOMOUNT_PARTITION 0x4000000000000000LL /* Do not automount (e.g., do not assign drive letter) */
#define BYTES_PER_SECTOR 512 /* Default in libogc */ #define BYTES_PER_SECTOR 512 /* Default in libogc */
#define MAX_BYTES_PER_SECTOR 4096 /* Max bytes per sector */ #define MAX_BYTES_PER_SECTOR 4096 /* Max bytes per sector */
enum SIG_OFFSETS {
BPB_NTFS_ADDR = 0x3,
BPB_FAT16_ADDR = 0x36,
BPB_EXT2_ADDR = 0x38,
BPB_FAT32_ADDR = 0x52,
};
static const char FAT_SIGNATURE[3] = {'F', 'A', 'T'};
static const char NTFS_SIGNATURE[4] = {'N', 'T', 'F', 'S'};
static const char WBFS_SIGNATURE[4] = {'W', 'B', 'F', 'S'};
static const char EXT_SIGNATURE[2] = {0x53, 0xEF};
typedef struct _PARTITION_RECORD { typedef struct _PARTITION_RECORD {
u8 status; /* Partition status; see above */ u8 status; /* Partition status; see above */
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */ u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
@ -69,10 +62,9 @@ typedef struct _PARTITION_RECORD {
u32 block_count; /* Number of blocks in partition */ u32 block_count; /* Number of blocks in partition */
} __attribute__((__packed__)) PARTITION_RECORD; } __attribute__((__packed__)) PARTITION_RECORD;
typedef struct _MASTER_BOOT_RECORD { typedef struct _MASTER_BOOT_RECORD {
u8 code_area[440]; /* Code area; normally empty */ u8 code_area[446]; /* Code area; normally empty */
u8 disk_guid[4]; /* Disk signature (optional) */
u8 reserved[2]; /* Usually zeroed */
PARTITION_RECORD partitions[4]; /* 4 primary partitions */ PARTITION_RECORD partitions[4]; /* 4 primary partitions */
u16 signature; /* MBR signature; 0xAA55 */ u16 signature; /* MBR signature; 0xAA55 */
} __attribute__((__packed__)) MASTER_BOOT_RECORD; } __attribute__((__packed__)) MASTER_BOOT_RECORD;
@ -85,81 +77,45 @@ typedef struct _EXTENDED_BOOT_RECORD {
u16 signature; /* EBR signature; 0xAA55 */ u16 signature; /* EBR signature; 0xAA55 */
} __attribute__((__packed__)) EXTENDED_BOOT_RECORD; } __attribute__((__packed__)) EXTENDED_BOOT_RECORD;
typedef struct _GUID_PARTITION_ENTRY typedef struct _GUID_PART_ENTRY
{ {
u8 Type_GUID[16]; /* Partition type GUID */ u8 part_type_guid[16]; /* Partition type GUID */
u8 Unique_GUID[16]; /* Unique partition GUID */ u8 uniq_part_guid[16]; /* Unique partition GUID */
u64 First_LBA; /* First LBA (little-endian) */ u64 part_first_lba; /* First LBA (little-endian) */
u64 Last_LBA; /* Last LBA (inclusive, usually odd) */ u64 part_last_lba; /* Last LBA (inclusive, usually odd) */
u64 Attributes; /* GUID Attribute flags (e.g. bit 60 denotes read-only) */ u64 attribute_flags; /* GUID Attribute flags (e.g. bit 60 denotes read-only) */
char Name[72]; /* Partition name (36 UTF-16LE code units) */ char partition_name[72]; /* Partition name (36 UTF-16LE code units) */
} __attribute__((__packed__)) GUID_PARTITION_ENTRY; } __attribute__((__packed__)) GUID_PART_ENTRY;
typedef struct _GPT_PARTITION_TABLE { typedef struct _GPT_HEADER
{
char magic[8]; /* "EFI PART" */ char magic[8]; /* "EFI PART" */
u32 Revision; u32 revision; /* For version 1.0 */
u32 Header_Size; /* Size of this header */ u32 header_size; /* Header size in bytes */
u32 CheckSum; u32 checksum; /* CRC32 of header (0 to header size), with this field zeroed during calculation */
u32 Reserved; /* Must be 0 */ u32 reserved; /* must be 0 */
u64 Header_LBA; /* Location of this header, always 1 in primary copy */ u64 header_lba; /* Current LBA (location of this header copy) */
u64 Backup_Header_LBA; /* Location of backup header, always max lba - 1 */ u64 backup_lba; /* Backup LBA (location of the other header copy) */
u64 First_Usable_LBA; /* Primary GPT partition table's last LBA + 1 */ u64 first_part_lba; /* First usable LBA for partitions (primary partition table last LBA + 1) */
u64 Last_Usable_LBA; /* Secondary GPT partition table's first LBA - 1 */ u64 last_part_lba; /* Last usable LBA (secondary partition table first LBA - 1) */
u8 GUID[16]; /* Disk GUID (also referred as UUID on UNIXes) */ u8 disk_guid[16]; /* Disk GUID (also referred as UUID on UNIXes) */
u64 Table_LBA; /* Always 2 in primary copy, or Header_LBA + 1. Secondary copy is Backup_Header_LBA - 1 */ u64 part_table_lba; /* Partition entries starting LBA (always 2 in primary copy) */
u32 Num_Entries; /* Number of entries in the partition info array */ u32 part_entries; /* Number of partition entries */
u32 Entry_Size; /* Size of each array entry, usually 128 */ u32 part_entry_size; /* Size of a partition entry (usually 128) */
u32 Entries_CheckSum; /* CRC32 of partition array */ u32 part_entry_checksum; /* CRC32 of partition array */
u8 Zeroes[420]; /* Pad to a total 512 byte LBA or sizeof 1 LBA */ u8 zeros[420];
GUID_PARTITION_ENTRY partitions[128]; /* Max 128 Partition Entries */ } __attribute__((__packed__)) GPT_HEADER;
} __attribute__((__packed__)) GPT_PARTITION_TABLE;
typedef struct _PartitionFS { typedef struct _PartitionFS {
const char * FSName; const char * FSName;
u32 LBA_Start; u64 LBA_Start;
u32 SecCount; u64 SecCount;
bool Bootable; bool Bootable;
u8 PartitionType; u8 PartitionType;
u8 PartitionNum; u8 PartitionNum;
u32 EBR_Sector;
wbfs_t *wbfshandle; wbfs_t *wbfshandle;
} PartitionFS; } __attribute__((__packed__)) PartitionFS;
typedef struct _BIOS_PARAMETER_BLOCK {
u16 Bytes_Per_Sector; /* Size of a sector in bytes. */
u8 Sectors_Per_Cluster; /* Size of a cluster in sectors. */
u16 ReservedSsectors; /* zero on ntfs */
u8 Fats; /* zero on ntfs */
u16 Root_Entries; /* zero on ntfs */
u16 FatSectors; /* Number of sectors in volume. (FAT) Zero on ntfs */
u8 Media_Type; /* 0xf8 = hard disk */
u16 Sectors_Per_Fat; /* zero on ntfs*/
u16 Sectors_Per_Track; /* Required to boot Windows. (0x0d) */
u16 Heads; /* Required to boot Windows. (0x0f) */
u32 Hidden_Sectors; /* Offset to the start of the partition (0x11) in sectors. */
u32 Large_Sectors; /* Number of sectors in volume if Sectors is 0 (FAT) Zero on ntfs (0x15) */
} __attribute__((__packed__)) BIOS_PARAMETER_BLOCK; /* 25 (0x19) bytes */
typedef struct _VOLUME_BOOT_RECORD {
u8 Jump[3]; /* Irrelevant (jump to boot up code).*/
char Name[8]; /* Magic "NTFS ". */
BIOS_PARAMETER_BLOCK bpb; /* See BIOS_PARAMETER_BLOCK. (0x0b) */
u8 Drive_Type; /* 0x00 floppy, 0x80 hard disk */
u8 Current_Head; /* zero on ntfs */
u8 Extended_Boot_Signature; /* 0x80 on ntfs (Doesnt show this in M$ docs)*/
u8 Reserved0; /* zero on ntfs */
s64 Number_of_Sectors; /* Number of sectors in volume. (NTFS)(0x28)*/
s64 MFT; /* Cluster location of mft data. */
s64 MFT_Mirror; /* Cluster location of copy of mft. */
s8 Clusters_Per_MFT; /* Mft record size in clusters. */
u8 Reserved1[3]; /* zero */
s8 Clusters_Per_Index; /* Index block size in clusters. */
u8 Reserved2[3]; /* zero */
u64 Volume_Serial_Number; /* Irrelevant (serial number). */
u8 Checksum[4]; /* Boot sector checksum. */
u8 Bootstrap[426]; /* Irrelevant (boot up code). (0x54) */
u16 Signature; /* End of bootsector magic. LE 0xaa55 */
} __attribute__((__packed__)) VOLUME_BOOT_RECORD; /* 512 (0x200) bytes */
class PartitionHandle class PartitionHandle
{ {
@ -173,7 +129,7 @@ class PartitionHandle
//! Is the partition Mounted //! Is the partition Mounted
bool IsMounted(int pos); bool IsMounted(int pos);
//! Mount a specific Partition //! Mount a specific Partition
bool Mount(int pos, const char * name); bool Mount(int pos, const char * name, bool forceFAT = false);
//! UnMount a specific Partition //! UnMount a specific Partition
void UnMount(int pos); void UnMount(int pos);
//! UnMount all Partition //! UnMount all Partition
@ -192,30 +148,29 @@ class PartitionHandle
int GetPartitionType(int pos) { if(valid(pos)) return PartitionList[pos].PartitionType; else return -1; }; int GetPartitionType(int pos) { if(valid(pos)) return PartitionList[pos].PartitionType; else return -1; };
//! Get the entrie number in MBR of this partition //! Get the entrie number in MBR of this partition
int GetPartitionNum(int pos) { if(valid(pos)) return PartitionList[pos].PartitionNum; else return -1; }; int GetPartitionNum(int pos) { if(valid(pos)) return PartitionList[pos].PartitionNum; else return -1; };
//! Get the EBR sector where this partition is described
int GetEBRSector(int pos) { if(valid(pos)) return PartitionList[pos].EBR_Sector; else return 0; };
//! Get the count of found partitions //! Get the count of found partitions
int GetPartitionCount() { return PartitionList.size(); }; int GetPartitionCount() const { return PartitionList.size(); };
//! Get the partition size in bytes //! Get the partition size in bytes
u64 GetSize(int pos) { if(valid(pos)) return (u64) PartitionList[pos].SecCount*BYTES_PER_SECTOR; else return 0; }; u64 GetSize(int pos) { if(valid(pos)) return (u64) PartitionList[pos].SecCount*BYTES_PER_SECTOR; else return 0; };
//! Get the wbfs mount handle
wbfs_t * GetWbfsHandle(int pos) { if(valid(pos)) return PartitionList[pos].wbfshandle; else return 0; };
//! Set the wbfs mount handle
bool SetWbfsHandle(int pos, wbfs_t * wbfshandle) { if(valid(pos)) {PartitionList[pos].wbfshandle = wbfshandle; return true;} else return false; };
//! Get the whole partition record struct //! Get the whole partition record struct
PartitionFS * GetPartitionRecord(int pos) { if(valid(pos)) return &PartitionList[pos]; else return NULL; }; PartitionFS * GetPartitionRecord(int pos) { if(valid(pos)) return &PartitionList[pos]; else return NULL; };
//! Get the disc interface of this handle //! Get the disc interface of this handle
const DISC_INTERFACE * GetDiscInterface() { return interface; }; const DISC_INTERFACE * GetDiscInterface() { return interface; };
//! Get the wbfs mount handle
wbfs_t *GetWbfsHandle(int pos) { if(valid(pos)) return PartitionList[pos].wbfshandle; else return 0; };
//! Set the wbfs mount handle
bool SetWbfsHandle(int pos, wbfs_t * wbfshandle) { if(valid(pos)) {PartitionList[pos].wbfshandle = wbfshandle; return true;} else return false; };
protected: protected:
bool valid(int pos) { return (pos >= 0 && pos < (int) PartitionList.size()); } bool valid(int pos) { return (pos >= 0 && pos < (int) PartitionList.size()); }
bool CheckRAW(VOLUME_BOOT_RECORD * vbr); void AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num);
bool IsExisting(u64 lba);
int FindPartitions(); int FindPartitions();
void CheckEBR(u8 PartNum, sec_t ebr_lba); void CheckEBR(u8 PartNum, sec_t ebr_lba);
bool CheckGPT(void); int CheckGPT(u8 PartNum);
const DISC_INTERFACE *interface; const DISC_INTERFACE *interface;
vector<PartitionFS> PartitionList; vector<PartitionFS> PartitionList;
vector<std::string> MountNameList; vector<string> MountNameList;
}; };
#endif #endif

View File

@ -1,6 +1,8 @@
/*------------------------------------------------------------- /*-------------------------------------------------------------
usbstorage_starlet.c -- USB mass storage support, inside starlet usbstorage_starlet.c -- USB mass storage support, inside starlet
Copyright (C) 2011 Dimok
Copyright (C) 2011 Rodries
Copyright (C) 2009 Kwiirk 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
@ -30,9 +32,11 @@ distribution.
#include <malloc.h> #include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "usbstorage.h"
#include "memory/mem2.hpp"
#include "gecko.h" #include "gecko.h"
/* IOCTL commands */ /* IOCTL commands */
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8)) #define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1) #define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
@ -41,259 +45,292 @@ distribution.
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4) #define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5) #define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6) #define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80) #define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
#define UMS_HEAPSIZE 0x8000 #define USB_IOCTL_UMS_TESTMODE (UMS_BASE+0x81)
#define USB_MEM2_SIZE 0x10000 #define USB_IOCTL_SET_PORT (UMS_BASE+0x83)
#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x50)
#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x51)
#define isMEM2Buffer(p) (((u32) p & 0x10000000) != 0)
#define MAX_SECTOR_SIZE 4096
#define MAX_BUFFER_SECTORS 128
#define UMS_HEAPSIZE 2*1024
/* Variables */ /* Variables */
static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2"; static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2";
static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb123"; static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb123";
static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc"; static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
static u8 * mem2_ptr = NULL;
static s32 hid = -1, fd = -1; static s32 hid = -1, fd = -1;
u32 sector_size; static u32 usb2_port = -1; //current USB port
static void *usb_buf2; bool hddInUse[2] = { false, false };
u32 hdd_sector_size[2] = { 512, 512 };
extern void* SYS_AllocArena2MemLo(u32 size,u32 align); s32 USBStorage2_Init(u32 port)
inline s32 __USBStorage_isMEM2Buffer(const void *buffer)
{ {
u32 high_addr = ((u32)buffer) >> 24; if(hddInUse[port])
return (high_addr == 0x90) || (high_addr == 0xD0);
}
u32 USBStorage_GetCapacity(u32 *_sector_size)
{
if (fd >= 0)
{
u32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", &sector_size);
static bool first = true;
if (first)
{
gprintf("\nSECTORS: %lu\n", ret);
gprintf("SEC SIZE: %lu\n", sector_size);
u32 size = ((((ret / 1024U) * sector_size) / 1024U) / 1024U);
if(size >= 1000U)
{
gprintf("HDD SIZE: %lu.%lu TB [%u]\n", size / 1024U, (size * 100U) % 1024U, sector_size);
}
else
{
gprintf("HDD SIZE: %lu GB [%u]\n", size, sector_size);
}
first = false;
}
if (ret && _sector_size)
*_sector_size = sector_size;
return ret;
}
return 0; return 0;
}
s32 USBStorage_OpenDev()
{
/* Already open */
if (fd >= 0) return fd;
/* Create heap */ /* Create heap */
if (hid < 0) if (hid < 0)
{ {
hid = iosCreateHeap(UMS_HEAPSIZE); hid = iosCreateHeap(UMS_HEAPSIZE);
if (hid < 0) return IPC_ENOMEM; // = -22 if (hid < 0) return IPC_ENOMEM;
} }
// allocate buf2
if (usb_buf2 == NULL) usb_buf2 = SYS_AllocArena2MemLo(USB_MEM2_SIZE, 32);
/* Open USB device */ /* Open USB device */
fd = IOS_Open(fs, 0); if (fd < 0) fd = IOS_Open(fs, 0);
if (fd < 0) fd = IOS_Open(fs2, 0); if (fd < 0) fd = IOS_Open(fs2, 0);
if (fd < 0) fd = IOS_Open(fs3, 0); if (fd < 0) fd = IOS_Open(fs3, 0);
return fd;
}
s32 USBStorage_SetWatchdog(u32 seconds)
{
if (fd < 0) return fd; if (fd < 0) return fd;
static ioctlv vector[1] ATTRIBUTE_ALIGN(32); USBStorage2_SetPort(port);
static u32 secs[8] ATTRIBUTE_ALIGN(32);
secs[0] = seconds;
vector[0].data = secs;
vector[0].len = 4;
return IOS_Ioctlv(fd, USB_IOCTL_UMS_WATCHDOG, 1, 0, vector);
}
s32 USBStorage_Init(void)
{
s32 ret;
USBStorage_OpenDev();
if (fd < 0) return fd;
/* Initialize USB storage */ /* Initialize USB storage */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":"); IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
/* Get device capacity */ /* Get device capacity */
ret = USBStorage_GetCapacity(NULL); if (USBStorage2_GetCapacity(port, &hdd_sector_size[port]) == 0)
if (!ret) goto err; return IPC_ENOENT;
hddInUse[port] = true;
return 0; // 0->HDD, 1->DVD
}
void USBStorage2_Deinit()
{
/* Close USB device */
if (fd >= 0)
{
IOS_Close(fd); // not sure to close the fd is needed
fd = -1;
}
}
s32 USBStorage2_SetPort(u32 port)
{
//! Port = 2 is handle in the loader, no need to handle it in cIOS
if(port > 1)
return -1;
if(port == usb2_port)
return 0; return 0;
err: s32 ret = -1;
/* Close USB device */ usb2_port = port;
gprintf("Changing USB port to port %i....\n", port);
//must be called before USBStorage2_Init (default port 0)
if (fd >= 0) if (fd >= 0)
{ ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_SET_PORT, "i:", usb2_port);
IOS_Close(fd);
fd = -1;
}
/*
if (hid > 0) {
iosDestroyHeap(hid);
hid = -1;
} */
//USB_Deinitialize(); //Screwing up inputs even worse if i do this here..grr
return -1;
}
void USBStorage_Deinit(void)
{
/* Close USB device */
if (fd >= 0)
{
IOS_Close(fd);
fd = -1;
}
/* if (hid > 0) {
iosDestroyHeap(hid);
hid = -1;
} */
USB_Deinitialize();
}
s32 USBStorage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
{
void *buf = (void *)buffer;
u32 len = (sector_size * numSectors);
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
/* MEM1 buffer */
if (!__USBStorage_isMEM2Buffer(buffer))
{
/* Allocate memory */
//buf = iosAlloc(hid, len);
buf = usb_buf2;
if (!buf) return IPC_ENOMEM;
}
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, numSectors, buf, len);
/* Copy data */
if (buf != buffer)
{
memcpy(buffer, buf, len);
//iosFree(hid, buf);
}
return ret; return ret;
} }
s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer) s32 USBStorage2_GetPort()
{
return usb2_port;
}
s32 USBStorage2_GetCapacity(u32 port, u32 *_sector_size)
{
if (fd >= 0)
{ {
void *buf = (void *)buffer;
u32 len = (sector_size * numSectors);
s32 ret; s32 ret;
u32 sector_size = 0;
USBStorage2_SetPort(port);
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", &sector_size);
if (ret && _sector_size) *_sector_size = sector_size;
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage2_ReadSectors(u32 port, u32 sector, u32 numSectors, void *buffer)
{
u8 *buf = (u8 *) buffer;
s32 ret = -1;
/* Device not opened */ /* Device not opened */
if (fd < 0) return fd; if (fd < 0) return fd;
/* MEM1 buffer */ if (!mem2_ptr)
if (!__USBStorage_isMEM2Buffer(buffer)) mem2_ptr = (u8 *) MEM2_alloc(MAX_SECTOR_SIZE * MAX_BUFFER_SECTORS);
{
/* Allocate memory */
//buf = iosAlloc(hid, len);
buf = usb_buf2;
if (!buf) return IPC_ENOMEM;
/* Copy data */ USBStorage2_SetPort(port);
memcpy(buf, buffer, len);
s32 read_secs, read_size;
while(numSectors > 0)
{
read_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
read_size = read_secs*hdd_sector_size[port];
// Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow!
if (!isMEM2Buffer(buffer))
{
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, read_secs, mem2_ptr, read_size);
if(ret < 0)
return ret;
memcpy(buf, mem2_ptr, read_size);
}
else
{
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, read_secs, buf, read_size);
if(ret < 0)
return ret;
} }
/* Write data */ sector += read_secs;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buf, len); numSectors -= read_secs;
buf += read_size;
/* Free memory */ }
//if (buf != buffer)
// iosFree(hid, buf);
return ret; return ret;
} }
// DISC_INTERFACE methods s32 USBStorage2_WriteSectors(u32 port, u32 sector, u32 numSectors, const void *buffer)
static bool __io_usb_IsInserted(void)
{ {
s32 ret; u8 *buf = (u8 *) buffer;
u32 sec_size; s32 ret = -1;
if (fd < 0)
return false;
ret = USBStorage_GetCapacity(&sec_size); /* Device not opened */
if (ret == 0) if (fd < 0) return fd;
return false;
return true; /* Device not opened */
if (!mem2_ptr)
mem2_ptr = (u8 *) MEM2_alloc(MAX_SECTOR_SIZE * MAX_BUFFER_SECTORS);
USBStorage2_SetPort(port);
s32 write_size, write_secs;
while(numSectors > 0)
{
write_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
write_size = write_secs*hdd_sector_size[port];
/* MEM1 buffer */
if (!isMEM2Buffer(buffer))
{
// Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow!
memcpy(mem2_ptr, buf, write_size);
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, write_secs, mem2_ptr, write_size);
if(ret < 0)
return ret;
}
else
{
/* Write data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, write_secs, buf, write_size);
if(ret < 0)
return ret;
} }
static bool __io_usb_Startup(void) sector += write_secs;
{ numSectors -= write_secs;
if (USBStorage_Init() < 0) return false; buf += write_size;
return __io_usb_IsInserted();
} }
bool __io_usb_ReadSectors(u32 sector, u32 count, void *buffer) return ret;
{
return USBStorage_ReadSectors(sector, count, buffer) >= 0;
} }
bool __io_usb_WriteSectors(u32 sector, u32 count, void *buffer) s32 USBStorage2_GetSectorSize()
{ {
return USBStorage_WriteSectors(sector, count, buffer) >= 0; return hdd_sector_size[usb2_port];
} }
static bool __io_usb_ClearStatus(void) static bool __usbstorage_Startup(void)
{
return USBStorage2_Init(0) >= 0;
}
static bool __usbstorage_IsInserted(void)
{
return (USBStorage2_GetCapacity(0, NULL) != 0);
}
static bool __usbstorage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
{
return (USBStorage2_ReadSectors(0, sector, numSectors, buffer) >= 0);
}
static bool __usbstorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
{
return (USBStorage2_WriteSectors(0, sector, numSectors, buffer) >= 0);
}
static bool __usbstorage_ClearStatus(void)
{ {
return true; return true;
} }
static bool __io_usb_Shutdown(void) static bool __usbstorage_Shutdown(void)
{ {
// do nothing hddInUse[0] = false;
hdd_sector_size[0] = 512;
return true; return true;
} }
DISC_INTERFACE __io_usbstorage = { const DISC_INTERFACE __io_usbstorage2_port0 = {
DEVICE_TYPE_WII_USB, DEVICE_TYPE_WII_UMS, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB, (FN_MEDIUM_STARTUP) &__usbstorage_Startup,
(FN_MEDIUM_STARTUP) &__io_usb_Startup, (FN_MEDIUM_ISINSERTED) &__usbstorage_IsInserted,
(FN_MEDIUM_ISINSERTED) &__io_usb_IsInserted, (FN_MEDIUM_READSECTORS) &__usbstorage_ReadSectors,
(FN_MEDIUM_READSECTORS) &__io_usb_ReadSectors, (FN_MEDIUM_WRITESECTORS) &__usbstorage_WriteSectors,
(FN_MEDIUM_WRITESECTORS) &__io_usb_WriteSectors, (FN_MEDIUM_CLEARSTATUS) &__usbstorage_ClearStatus,
(FN_MEDIUM_CLEARSTATUS) &__io_usb_ClearStatus, (FN_MEDIUM_SHUTDOWN) &__usbstorage_Shutdown
(FN_MEDIUM_SHUTDOWN) &__io_usb_Shutdown };
static bool __usbstorage_Startup2(void)
{
return USBStorage2_Init(1) >= 0;
}
static bool __usbstorage_IsInserted2(void)
{
return (USBStorage2_GetCapacity(1, NULL) != 0);
}
static bool __usbstorage_ReadSectors2(u32 sector, u32 numSectors, void *buffer)
{
return (USBStorage2_ReadSectors(1, sector, numSectors, buffer) >= 0);
}
static bool __usbstorage_WriteSectors2(u32 sector, u32 numSectors, const void *buffer)
{
return (USBStorage2_WriteSectors(1, sector, numSectors, buffer) >= 0);
}
static bool __usbstorage_Shutdown2(void)
{
hddInUse[1] = false;
hdd_sector_size[1] = 512;
return true;
}
const DISC_INTERFACE __io_usbstorage2_port1 = {
DEVICE_TYPE_WII_UMS, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP) &__usbstorage_Startup2,
(FN_MEDIUM_ISINSERTED) &__usbstorage_IsInserted2,
(FN_MEDIUM_READSECTORS) &__usbstorage_ReadSectors2,
(FN_MEDIUM_WRITESECTORS) &__usbstorage_WriteSectors2,
(FN_MEDIUM_CLEARSTATUS) &__usbstorage_ClearStatus,
(FN_MEDIUM_SHUTDOWN) &__usbstorage_Shutdown2
}; };

View File

@ -1,22 +1,32 @@
#ifndef _USBSTORAGE_H_ #ifndef _USBSTORAGE2_H_
#define _USBSTORAGE_H_ #define _USBSTORAGE2_H_
#include <ogcsys.h> #include "ogc/disc_io.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
#endif /* __cplusplus */ {
#endif
/* Prototypes */ /* Prototypes */
s32 USBStorage_GetCapacity(u32 *); s32 USBStorage2_Init(u32 port);
s32 USBStorage_SetWatchdog(u32); void USBStorage2_Deinit();
s32 USBStorage_Init(void); s32 USBStorage2_GetCapacity(u32 port, u32 *size);
void USBStorage_Deinit(void);
s32 USBStorage_ReadSectors(u32, u32, void *); s32 USBStorage2_ReadSectors(u32 port, u32 sector, u32 numSectors, void *buffer);
s32 USBStorage_WriteSectors(u32, u32, void *); s32 USBStorage2_WriteSectors(u32 port, u32 sector, u32 numSectors, const void *buffer);
s32 USBStorage2_GetSectorSize();
s32 USBStorage2_SetPort(u32 port);
s32 USBStorage2_GetPort();
#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S')
extern const DISC_INTERFACE __io_usbstorage2_port0;
extern const DISC_INTERFACE __io_usbstorage2_port1;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif
#endif #endif

View File

@ -87,7 +87,7 @@ bool loadIOS(int ios, bool launch_game)
DeviceHandler::Instance()->UnMountAll(); DeviceHandler::Instance()->UnMountAll();
WDVD_Close(); WDVD_Close();
USBStorage_Deinit(); USBStorage2_Deinit();
mload_close(); mload_close();
bool iosOK = IOS_ReloadIOS(ios) == 0; bool iosOK = IOS_ReloadIOS(ios) == 0;

View File

@ -29,8 +29,6 @@
/* WBFS device */ /* WBFS device */
s32 wbfsDev = WBFS_MIN_DEVICE; s32 wbfsDev = WBFS_MIN_DEVICE;
extern u32 sector_size;
// partition // partition
int wbfs_part_fs = PART_FS_WBFS; int wbfs_part_fs = PART_FS_WBFS;
u32 wbfs_part_idx = 0; u32 wbfs_part_idx = 0;
@ -99,7 +97,7 @@ s32 __WBFS_ReadUSB(void* fp, u32 lba, u32 count, void *iobuf)
/* Do reads */ /* Do reads */
while (cnt < count) while (cnt < count)
{ {
fp = ((u8 *)iobuf) + (cnt * sector_size); fp = ((u8 *)iobuf) + (cnt * USBStorage2_GetSectorSize());
u32 sectors = (count - cnt); u32 sectors = (count - cnt);
/* Read sectors is too big */ /* Read sectors is too big */
@ -107,7 +105,7 @@ s32 __WBFS_ReadUSB(void* fp, u32 lba, u32 count, void *iobuf)
sectors = MAX_NB_SECTORS; sectors = MAX_NB_SECTORS;
/* USB read */ /* USB read */
s32 ret = USBStorage_ReadSectors(lba + cnt, sectors, fp); s32 ret = USBStorage2_ReadSectors(USBStorage2_GetPort(), lba + cnt, sectors, fp);
if (ret < 0) return ret; if (ret < 0) return ret;
/* Increment counter */ /* Increment counter */
@ -124,7 +122,7 @@ s32 __WBFS_WriteUSB(void* fp, u32 lba, u32 count, void *iobuf)
/* Do writes */ /* Do writes */
while (cnt < count) while (cnt < count)
{ {
fp = ((u8 *)iobuf) + (cnt * sector_size); fp = ((u8 *)iobuf) + (cnt * USBStorage2_GetSectorSize());
u32 sectors = (count - cnt); u32 sectors = (count - cnt);
/* Write sectors is too big */ /* Write sectors is too big */
@ -132,7 +130,7 @@ s32 __WBFS_WriteUSB(void* fp, u32 lba, u32 count, void *iobuf)
sectors = MAX_NB_SECTORS; sectors = MAX_NB_SECTORS;
/* USB write */ /* USB write */
s32 ret = USBStorage_WriteSectors(lba + cnt, sectors, fp); s32 ret = USBStorage2_WriteSectors(USBStorage2_GetPort(), lba + cnt, sectors, fp);
if (ret < 0) return ret; if (ret < 0) return ret;
/* Increment counter */ /* Increment counter */
@ -149,7 +147,7 @@ s32 __WBFS_ReadSDHC(void* fp, u32 lba, u32 count, void *iobuf)
/* Do reads */ /* Do reads */
while (cnt < count) while (cnt < count)
{ {
fp = ((u8 *)iobuf) + (cnt * sector_size); fp = ((u8 *)iobuf) + (cnt * 512);
u32 sectors = (count - cnt); u32 sectors = (count - cnt);
/* Read sectors is too big */ /* Read sectors is too big */
@ -175,7 +173,7 @@ s32 __WBFS_WriteSDHC(void* fp, u32 lba, u32 count, void *iobuf)
/* Do writes */ /* Do writes */
while (cnt < count) while (cnt < count)
{ {
fp = ((u8 *)iobuf) + (cnt * sector_size); fp = ((u8 *)iobuf) + (cnt * 512);
u32 sectors = (count - cnt); u32 sectors = (count - cnt);
/* Write sectors is too big */ /* Write sectors is too big */
@ -231,6 +229,7 @@ s32 WBFS_Init(wbfs_t * handle, u32 part_fs, u32 part_idx, u32 part_lba, char *pa
s32 WBFS_Format(u32 lba, u32 size) s32 WBFS_Format(u32 lba, u32 size)
{ {
u32 sector_size = (currentPartition == 0) ? 512 : USBStorage2_GetSectorSize();
u32 wbfs_sector_size = sector_size; u32 wbfs_sector_size = sector_size;
u32 partition_num_sec = size; u32 partition_num_sec = size;
@ -310,7 +309,7 @@ s32 WBFS_GameSize(u8 *discid, char *path, f32 *size)
s32 WBFS_DVD_Size(u64 *comp_size, u64 *real_size) s32 WBFS_DVD_Size(u64 *comp_size, u64 *real_size)
{ {
if (wbfs_part_fs) return WBFS_Ext_DVD_Size(comp_size, real_size); if (wbfs_part_fs) return WBFS_Ext_DVD_Size(comp_size, real_size, (currentPartition == 0));
u32 comp_sec = 0, last_sec = 0; u32 comp_sec = 0, last_sec = 0;

View File

@ -26,8 +26,6 @@
#define MAX_FAT_PATH 1024 #define MAX_FAT_PATH 1024
#define TITLE_LEN 64 #define TITLE_LEN 64
extern u32 sector_size;
char wbfs_fs_drive[16]; char wbfs_fs_drive[16];
char wbfs_ext_dir[16] = "/wbfs"; char wbfs_ext_dir[16] = "/wbfs";
char invalid_path[] = "/\\:|<>?*\"'"; char invalid_path[] = "/\\:|<>?*\"'";
@ -46,6 +44,7 @@ char* strcopy(char *dest, const char *src, int size)
wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname) wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname)
{ {
bool sd = strstr(fname, "sd") != NULL;
if (strcasecmp(strrchr(fname,'.'), ".iso") == 0) if (strcasecmp(strrchr(fname,'.'), ".iso") == 0)
{ {
// .iso file // .iso file
@ -58,7 +57,7 @@ wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname)
return NULL; return NULL;
// mark with a special wbfs_part // mark with a special wbfs_part
wbfs_iso_file.wbfs_sec_sz = sector_size; wbfs_iso_file.wbfs_sec_sz = sd ? 512 : USBStorage2_GetSectorSize();
iso_file->p = &wbfs_iso_file; iso_file->p = &wbfs_iso_file;
iso_file->header = (void*)fd; iso_file->header = (void*)fd;
return iso_file; return iso_file;
@ -116,12 +115,13 @@ s32 WBFS_Ext_DiskSpace(f32 *used, f32 *free)
wbfs_t* WBFS_Ext_OpenPart(char *fname) wbfs_t* WBFS_Ext_OpenPart(char *fname)
{ {
bool sd = strstr(fname, "sd") != NULL;
if(split_open(&split, fname) < 0) if(split_open(&split, fname) < 0)
return NULL; return NULL;
wbfs_set_force_mode(1); wbfs_set_force_mode(1);
wbfs_t *part = wbfs_open_partition(split_read_sector, 0, //readonly //split_write_sector, wbfs_t *part = wbfs_open_partition(split_read_sector, 0, //readonly //split_write_sector,
&split, sector_size, split.total_sec, 0, 0); &split, sd ? 512 : USBStorage2_GetSectorSize(), split.total_sec, 0, 0);
wbfs_set_force_mode(0); wbfs_set_force_mode(0);
if (!part) if (!part)
@ -223,17 +223,16 @@ s32 WBFS_Ext_AddGame(progress_callback_t spinner, void *spinner_data)
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
s32 WBFS_Ext_DVD_Size(u64 *comp_size, u64 *real_size) s32 WBFS_Ext_DVD_Size(u64 *comp_size, u64 *real_size, bool sd)
{ {
u64 size = (u64)143432*2*0x8000ULL; u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / 512; u32 n_sector = size / 512;
// init a temporary dummy part // init a temporary dummy part
// as a placeholder for wbfs_size_disc // as a placeholder for wbfs_size_disc
wbfs_t *part = wbfs_open_partition( wbfs_t *part = wbfs_open_partition(0, 0, NULL, sd ? 512 : USBStorage2_GetSectorSize(), n_sector, 0, 1);
0, 0, if (!part)
NULL, sector_size, n_sector, 0, 1); return -1;
if (!part) return -1;
u32 comp_sec = 0, last_sec = 0; u32 comp_sec = 0, last_sec = 0;
s32 ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION, &comp_sec, &last_sec); s32 ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION, &comp_sec, &last_sec);

View File

@ -16,7 +16,7 @@ void WBFS_Ext_CloseDisc(wbfs_disc_t* disc);
s32 WBFS_Ext_DiskSpace(f32 *used, f32 *free); s32 WBFS_Ext_DiskSpace(f32 *used, f32 *free);
s32 WBFS_Ext_RemoveGame(u8 *discid, char *path); s32 WBFS_Ext_RemoveGame(u8 *discid, char *path);
s32 WBFS_Ext_AddGame(progress_callback_t spinner, void *spinner_data); s32 WBFS_Ext_AddGame(progress_callback_t spinner, void *spinner_data);
s32 WBFS_Ext_DVD_Size(u64 *comp_size, u64 *real_size); s32 WBFS_Ext_DVD_Size(u64 *comp_size, u64 *real_size, bool sd);
int WBFS_Ext_find_fname(u8 *id, char *path, char *fname, int len); int WBFS_Ext_find_fname(u8 *id, char *path, char *fname, int len);
char* strcopy(char *dest, const char *src, int size); char* strcopy(char *dest, const char *src, int size);

View File

@ -88,19 +88,18 @@ int main(int argc, char **argv)
{ {
Open_Inputs(); //(re)init wiimote Open_Inputs(); //(re)init wiimote
#ifndef DOLPHIN #ifndef DOLPHIN
const DISC_INTERFACE *handle = DeviceHandler::GetUSB0Interface();
bool deviceAvailable = false; bool deviceAvailable = false;
u8 timeout = 0; u8 timeout = 0;
DeviceHandler::Instance()->MountSD();
while(!deviceAvailable && timeout++ != 20) while(!deviceAvailable && timeout++ != 20)
{ {
DeviceHandler::Instance()->MountAll(); deviceAvailable = (handle->startup() && handle->isInserted());
sleep(1); if(deviceAvailable)
break;
for(u8 device = USB1; device <= USB8; device++) usleep(50000);
{
if(DeviceHandler::Instance()->IsInserted(device))
deviceAvailable = true;
}
} }
DeviceHandler::Instance()->MountAllUSB();
if(DeviceHandler::Instance()->IsInserted(SD)) if(DeviceHandler::Instance()->IsInserted(SD))
deviceAvailable = true; deviceAvailable = true;
#else #else

View File

@ -309,7 +309,7 @@ void CMenu::init(void)
m_screenshotDir = m_cfg.getString("GENERAL", "dir_screenshot", sfmt("%s/screenshots", m_dataDir.c_str())); m_screenshotDir = m_cfg.getString("GENERAL", "dir_screenshot", sfmt("%s/screenshots", m_dataDir.c_str()));
m_helpDir = m_cfg.getString("GENERAL", "dir_help", sfmt("%s/help", m_dataDir.c_str())); m_helpDir = m_cfg.getString("GENERAL", "dir_help", sfmt("%s/help", m_dataDir.c_str()));
DeviceHandler::SetWatchdog(m_cfg.getUInt("GENERAL", "watchdog_timeout", 10)); //DeviceHandler::SetWatchdog(m_cfg.getUInt("GENERAL", "watchdog_timeout", 10));
const char *domain = _domainFromView(); const char *domain = _domainFromView();
const char *checkDir = m_current_view == COVERFLOW_HOMEBREW ? HOMEBREW_DIR : GAMES_DIR; const char *checkDir = m_current_view == COVERFLOW_HOMEBREW ? HOMEBREW_DIR : GAMES_DIR;
@ -491,7 +491,7 @@ void CMenu::cleanup()
{ {
if(cleaned_up) if(cleaned_up)
return; return;
gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize());
m_cf.stopCoverLoader(); m_cf.stopCoverLoader();
_cleanupDefaultFont(); _cleanupDefaultFont();
m_cf.clear(); m_cf.clear();
@ -542,6 +542,7 @@ void CMenu::cleanup()
cleaned_up = true; cleaned_up = true;
gprintf(" \nMemory cleaned up\n"); gprintf(" \nMemory cleaned up\n");
gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize());
} }
void CMenu::_reload_wifi_gecko(void) void CMenu::_reload_wifi_gecko(void)

View File

@ -61,7 +61,6 @@ extern const u8 blank_png[];
extern const u8 gc_ogg[]; extern const u8 gc_ogg[];
extern const u32 gc_ogg_size; extern const u32 gc_ogg_size;
extern u32 sector_size;
extern u32 boot2version; extern u32 boot2version;
extern int mainIOS; extern int mainIOS;
static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32); static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32);
@ -871,7 +870,7 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
cleanup(); cleanup();
#ifndef DOLPHIN #ifndef DOLPHIN
ISFS_Deinitialize(); ISFS_Deinitialize();
USBStorage_Deinit(); USBStorage2_Deinit();
SDHC_Init(); SDHC_Init();
#endif #endif
GC_SetVideoMode(videoMode, videoSetting); GC_SetVideoMode(videoMode, videoSetting);
@ -910,7 +909,7 @@ void CMenu::_launchHomebrew(const char *filepath, vector<string> arguments)
AddBootArgument(arguments[i].c_str()); AddBootArgument(arguments[i].c_str());
#ifndef DOLPHIN #ifndef DOLPHIN
ISFS_Deinitialize(); ISFS_Deinitialize();
USBStorage_Deinit(); USBStorage2_Deinit();
#endif #endif
//MEM2_clear(); //MEM2_clear();
BootHomebrew(title); BootHomebrew(title);
@ -1285,8 +1284,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
Nand::Instance()->Do_Region_Change(id); Nand::Instance()->Do_Region_Change(id);
} }
} }
if(!dvd && get_frag_list((u8 *)id.c_str(), (char*)path.c_str(), currentPartition == 0 ? 0x200 : USBStorage2_GetSectorSize()) < 0)
if(!dvd && get_frag_list((u8 *)id.c_str(), (char*)path.c_str(), currentPartition == 0 ? 0x200 : sector_size) < 0)
return; return;
u8 patchVidMode = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u); u8 patchVidMode = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u);
@ -1406,7 +1404,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
} }
#ifndef DOLPHIN #ifndef DOLPHIN
ISFS_Deinitialize(); ISFS_Deinitialize();
USBStorage_Deinit(); USBStorage2_Deinit();
if(currentPartition == 0) if(currentPartition == 0)
SDHC_Init(); SDHC_Init();
#endif #endif

View File

@ -56,8 +56,7 @@ static inline int GetFirstUnusedVoice()
extern "C" void SoundCallback(s32 voice) extern "C" void SoundCallback(s32 voice)
{ {
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder) return;
return;
if(decoder->IsBufferReady()) if(decoder->IsBufferReady())
{ {
@ -99,13 +98,12 @@ GuiSound::GuiSound(GuiSound *g)
voice = -1; voice = -1;
Init(); Init();
if (g == NULL) if (g == NULL) return;
return;
if (g->sound != NULL) if (g->sound != NULL)
{ {
u8 *snd = (u8 *)MEM1_alloc(g->length); u8 * snd = (u8 *) malloc(g->length);
memcpy(snd, g->sound, length); memcpy(snd, g->sound, g->length);
Load(snd, g->length, true); Load(snd, g->length, true);
} }
else else
@ -144,9 +142,11 @@ void GuiSound::FreeMemory()
if(allocated) if(allocated)
{ {
MEM1_free(sound); free(sound);
allocated = false; allocated = false;
} }
sound = NULL;
length = 0;
filepath = ""; filepath = "";
SoundEffectLength = 0; SoundEffectLength = 0;
@ -161,8 +161,7 @@ bool GuiSound::Load(const char * filepath)
FILE * f = fopen(filepath, "rb"); FILE * f = fopen(filepath, "rb");
if(!f) if(!f)
{ { gprintf("Failed to load file %s!!\n", filepath);
gprintf("Failed to load file %s!!\n", filepath);
return false; return false;
} }
@ -174,14 +173,12 @@ bool GuiSound::Load(const char * filepath)
gprintf("Loading %s using voice %d\n", filepath, voice); gprintf("Loading %s using voice %d\n", filepath, voice);
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder)
{ { gprintf("No Decoder!!!\n");
gprintf("No Decoder!!!\n");
return false; return false;
} }
if(!decoder->IsBufferReady()) if(!decoder->IsBufferReady())
{ { gprintf("Buffer not ready!!n");
gprintf("Buffer not ready!!\n");
SoundHandler::Instance()->RemoveDecoder(voice); SoundHandler::Instance()->RemoveDecoder(voice);
return false; return false;
} }
@ -197,14 +194,15 @@ bool GuiSound::Load(const u8 * snd, u32 len, bool isallocated)
FreeMemory(); FreeMemory();
this->voice = voice; this->voice = voice;
if(!snd) if(!snd) return false;
return false;
if(!isallocated && *((u32 *) snd) == 'RIFF') if(!isallocated && *((u32 *) snd) == 'RIFF')
return LoadSoundEffect(snd, len); return LoadSoundEffect(snd, len);
if(*((u32 *) snd) == 'IMD5') if(*((u32 *) snd) == 'IMD5')
{
UncompressSoundbin(snd, len, isallocated); UncompressSoundbin(snd, len, isallocated);
}
else else
{ {
sound = (u8 *) snd; sound = (u8 *) snd;
@ -216,7 +214,9 @@ bool GuiSound::Load(const u8 * snd, u32 len, bool isallocated)
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder)
{
return false; return false;
}
if(!decoder->IsBufferReady()) if(!decoder->IsBufferReady())
{ {
@ -237,15 +237,15 @@ bool GuiSound::LoadSoundEffect(const u8 * snd, u32 len)
decoder.Rewind(); decoder.Rewind();
u32 done = 0; u32 done = 0;
sound = (u8 *)MEM1_alloc(4096); sound = (u8 *)malloc(4096);
memset(sound, 0, 4096); memset(sound, 0, 4096);
while(1) while(1)
{ {
u8 * tmpsnd = (u8 *)MEM1_realloc(sound, done+4096); u8 * tmpsnd = (u8 *)realloc(sound, done+4096);
if(!tmpsnd) if(!tmpsnd)
{ {
MEM1_free(sound); free(sound);
return false; return false;
} }
@ -258,7 +258,7 @@ bool GuiSound::LoadSoundEffect(const u8 * snd, u32 len)
done += read; done += read;
} }
sound = (u8 *)MEM1_realloc(sound, done); sound = (u8 *)realloc(sound, done);
SoundEffectLength = done; SoundEffectLength = done;
allocated = true; allocated = true;
@ -274,15 +274,10 @@ void GuiSound::Play(int vol, bool restart)
return; return;
} }
if(IsPlaying() && !restart) if((IsPlaying() && !restart) || voice < 0 || voice >= 16) return;
return;
if(voice < 0 || voice >= 16)
return;
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder) return;
return;
ASND_StopVoice(voice); ASND_StopVoice(voice);
if(decoder->IsEOF()) if(decoder->IsEOF())
@ -307,16 +302,14 @@ void GuiSound::Play()
void GuiSound::Stop() void GuiSound::Stop()
{ {
if (!IsPlaying()) return; volume = 0;
if (!IsPlaying() || voice < 0 || voice >= 16)
if(voice < 0 || voice >= 16)
return; return;
ASND_StopVoice(voice); ASND_StopVoice(voice);
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder) return;
return;
decoder->ClearBuffer(); decoder->ClearBuffer();
Rewind(); Rewind();
@ -357,10 +350,7 @@ int GuiSound::GetVolume()
void GuiSound::SetVolume(int vol) void GuiSound::SetVolume(int vol)
{ {
if(voice < 0 || voice >= 16) if(voice < 0 || voice >= 16 || vol < 0)
return;
if(vol < 0)
return; return;
volume = vol; volume = vol;
@ -372,8 +362,7 @@ void GuiSound::SetLoop(u8 l)
loop = l; loop = l;
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder) return;
return;
decoder->SetLoop(l == 1); decoder->SetLoop(l == 1);
} }
@ -381,8 +370,7 @@ void GuiSound::SetLoop(u8 l)
void GuiSound::Rewind() void GuiSound::Rewind()
{ {
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
if(!decoder) if(!decoder) return;
return;
decoder->Rewind(); decoder->Rewind();
} }
@ -407,10 +395,9 @@ u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size)
const u8 *inBufEnd = inBuf + inLength; const u8 *inBufEnd = inBuf + inLength;
inBuf += 8; inBuf += 8;
buffer = (u8 *)MEM1_alloc(uncSize); buffer = (u8 *)malloc(uncSize);
if (!buffer) if (!buffer) return buffer;
return buffer;
u8 *bufCur = buffer; u8 *bufCur = buffer;
u8 *bufEnd = buffer + uncSize; u8 *bufEnd = buffer + uncSize;
@ -452,8 +439,7 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
const u8 * file = snd+32; const u8 * file = snd+32;
length = len-32; length = len-32;
if (length <= 0) if (length <= 0) return;
return;
if(*((u32 *) file) == 'LZ77') if(*((u32 *) file) == 'LZ77')
{ {
@ -468,7 +454,7 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
} }
else else
{ {
sound = (u8 *)MEM1_alloc(length); sound = (u8 *)malloc(length);
if (!sound) if (!sound)
{ {
length = 0; length = 0;