mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 09:05:06 +01:00
-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:
parent
71e0d1e425
commit
5640028b17
@ -23,7 +23,7 @@
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ogc/mutex.h>
|
||||
@ -42,91 +42,94 @@ extern const DISC_INTERFACE __io_sdhc;
|
||||
#endif
|
||||
|
||||
DeviceHandler * DeviceHandler::instance = NULL;
|
||||
unsigned int DeviceHandler::watchdog_timeout = 10;
|
||||
|
||||
DeviceHandler::~DeviceHandler()
|
||||
{
|
||||
UnMountAll();
|
||||
UnMountAll();
|
||||
}
|
||||
|
||||
DeviceHandler * DeviceHandler::Instance()
|
||||
{
|
||||
if (instance == NULL)
|
||||
{
|
||||
instance = new DeviceHandler();
|
||||
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DeviceHandler::DestroyInstance()
|
||||
{
|
||||
if(instance) delete instance;
|
||||
instance = NULL;
|
||||
if(instance)
|
||||
{
|
||||
delete instance;
|
||||
}
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountAll()
|
||||
{
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
|
||||
for(u32 i = SD; i <= USB8; i++)
|
||||
if(Mount(i)) result = true;
|
||||
for(u32 i = SD; i < MAXDEVICES; i++)
|
||||
{
|
||||
if(Mount(i))
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeviceHandler::UnMountAll()
|
||||
{
|
||||
for(u32 i = SD; i <= GCSDB; i++)
|
||||
UnMount(i);
|
||||
for(u32 i = SD; i < MAXDEVICES; i++)
|
||||
UnMount(i);
|
||||
|
||||
if(sd) delete sd;
|
||||
if(usb) delete usb;
|
||||
if(gca) delete gca;
|
||||
if(gcb) delete gca;
|
||||
if(sd)
|
||||
delete sd;
|
||||
if(usb0)
|
||||
delete usb0;
|
||||
if(usb1)
|
||||
delete usb1;
|
||||
|
||||
sd = NULL;
|
||||
usb = NULL;
|
||||
gca = NULL;
|
||||
gcb = NULL;
|
||||
sd = NULL;
|
||||
usb0 = NULL;
|
||||
usb1 = NULL;
|
||||
}
|
||||
|
||||
bool DeviceHandler::Mount(int dev)
|
||||
{
|
||||
if(dev == SD)
|
||||
if(dev == SD)
|
||||
return MountSD();
|
||||
|
||||
else if(dev >= USB1 && dev <= USB8)
|
||||
return MountUSB(dev-USB1);
|
||||
else if(dev == GCSDA)
|
||||
return MountGCA();
|
||||
else if(dev == GCSDB)
|
||||
return MountGCB();
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceHandler::IsInserted(int dev)
|
||||
{
|
||||
if(dev == SD)
|
||||
if(dev == SD)
|
||||
return SD_Inserted() && sd->IsMounted(0);
|
||||
else if(dev >= USB1 && dev <= USB8)
|
||||
return USB_Inserted() && usb->IsMounted(dev-USB1);
|
||||
else if(dev == GCSDA)
|
||||
return GCA_Inserted() && gca->IsMounted(0);
|
||||
else if(dev == GCSDB)
|
||||
return GCB_Inserted() && gcb->IsMounted(0);
|
||||
|
||||
return false;
|
||||
else if(dev >= USB1 && dev <= USB8)
|
||||
{
|
||||
int portPart = PartitionToPortPartition(dev-USB1);
|
||||
PartitionHandle *usb = instance->GetUSBHandleFromPartition(dev-USB1);
|
||||
if(usb)
|
||||
return usb->IsMounted(portPart);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceHandler::UnMount(int dev)
|
||||
{
|
||||
if(dev == SD)
|
||||
if(dev == SD)
|
||||
UnMountSD();
|
||||
|
||||
else if(dev >= USB1 && dev <= USB8)
|
||||
UnMountUSB(dev-USB1);
|
||||
else if(dev == GCSDA)
|
||||
UnMountGCA();
|
||||
else if(dev == GCSDB)
|
||||
UnMountGCB();
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountSD()
|
||||
@ -145,177 +148,194 @@ bool DeviceHandler::MountSD()
|
||||
}
|
||||
}
|
||||
|
||||
//! Mount only one SD Partition
|
||||
return sd->Mount(0, DeviceName[SD]);
|
||||
//! Mount only one SD Partition
|
||||
return sd->Mount(0, DeviceName[SD], true);
|
||||
}
|
||||
|
||||
|
||||
bool DeviceHandler::MountUSB(int pos)
|
||||
{
|
||||
if(!usb) usb = new PartitionHandle(&__io_usbstorage);
|
||||
if(!usb0 && !usb1)
|
||||
return false;
|
||||
|
||||
if(usb->GetPartitionCount() < 1)
|
||||
{
|
||||
delete usb;
|
||||
usb = NULL;
|
||||
return false;
|
||||
}
|
||||
if(pos >= GetUSBPartitionCount())
|
||||
return false;
|
||||
|
||||
// Set the watchdog
|
||||
InternalSetWatchdog(watchdog_timeout);
|
||||
int portPart = PartitionToPortPartition(pos);
|
||||
|
||||
if(pos >= usb->GetPartitionCount())
|
||||
return false;
|
||||
|
||||
return usb->Mount(pos, DeviceName[USB1+pos]);
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountAllUSB()
|
||||
{
|
||||
if(!usb) usb = new PartitionHandle(&__io_usbstorage);
|
||||
|
||||
bool result = false;
|
||||
|
||||
for(int i = 0; i < usb->GetPartitionCount(); i++)
|
||||
if(MountUSB(i))
|
||||
result = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountGCA()
|
||||
{
|
||||
if(!gca) gca = new PartitionHandle(&__io_gcsda);
|
||||
|
||||
if(gca->GetPartitionCount() < 1)
|
||||
{
|
||||
delete gca;
|
||||
gca = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Mount only one Partition
|
||||
return gca->Mount(0, DeviceName[GCSDA]);
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountGCB()
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(!usb) return;
|
||||
|
||||
if(pos >= usb->GetPartitionCount())
|
||||
return;
|
||||
|
||||
usb->UnMount(pos);
|
||||
}
|
||||
|
||||
void DeviceHandler::UnMountAllUSB()
|
||||
{
|
||||
if(!usb) return;
|
||||
|
||||
for(int i = 0; i < usb->GetPartitionCount(); i++)
|
||||
usb->UnMount(i);
|
||||
|
||||
delete usb;
|
||||
usb = NULL;
|
||||
}
|
||||
|
||||
bool DeviceHandler::InternalSetWatchdog(unsigned int timeout)
|
||||
{
|
||||
if (Instance()->USB_Inserted())
|
||||
return USBStorage_SetWatchdog(timeout) == 0;
|
||||
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::SetWatchdog(unsigned int timeout)
|
||||
bool DeviceHandler::MountAllUSB()
|
||||
{
|
||||
watchdog_timeout = timeout;
|
||||
return InternalSetWatchdog(timeout);
|
||||
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;
|
||||
int partCount = GetUSBPartitionCount();
|
||||
|
||||
for(int i = 0; i < partCount; i++)
|
||||
{
|
||||
if(MountUSB(i))
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeviceHandler::MountUSBPort1()
|
||||
{
|
||||
if(!usb1)// && (Settings.USBPort == 1 || Settings.USBPort == 2))
|
||||
usb1 = new PartitionHandle(GetUSB1Interface());
|
||||
|
||||
if(usb1 && usb1->GetPartitionCount() < 1)
|
||||
{
|
||||
delete usb1;
|
||||
usb1 = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
int partCount = GetUSBPartitionCount();
|
||||
int partCount0 = 0;
|
||||
if(usb0)
|
||||
partCount0 = usb0->GetPartitionCount();
|
||||
|
||||
for(int i = partCount0; i < partCount; i++)
|
||||
{
|
||||
if(MountUSB(i))
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeviceHandler::UnMountUSB(int pos)
|
||||
{
|
||||
if(pos >= GetUSBPartitionCount())
|
||||
return;
|
||||
|
||||
int portPart = PartitionToPortPartition(pos);
|
||||
|
||||
if(PartitionToUSBPort(pos) == 0 && usb0)
|
||||
return usb0->UnMount(portPart);
|
||||
else if(usb1)
|
||||
return usb1->UnMount(portPart);
|
||||
}
|
||||
|
||||
void DeviceHandler::UnMountAllUSB()
|
||||
{
|
||||
int partCount = GetUSBPartitionCount();
|
||||
|
||||
for(int i = 0; i < partCount; i++)
|
||||
UnMountUSB(i);
|
||||
|
||||
delete usb0;
|
||||
usb0 = NULL;
|
||||
delete usb1;
|
||||
usb1 = NULL;
|
||||
}
|
||||
|
||||
int DeviceHandler::PathToDriveType(const char * path)
|
||||
{
|
||||
if(!path) return -1;
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
for(int i = SD; i <= GCSDB; i++)
|
||||
if(strncmp(path, DeviceName[i], strlen(DeviceName[i])) == 0)
|
||||
return i;
|
||||
for(int i = SD; i < MAXDEVICES; i++)
|
||||
{
|
||||
if(strncasecmp(path, DeviceName[i], strlen(DeviceName[i])) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char * DeviceHandler::GetFSName(int dev)
|
||||
{
|
||||
if(dev == SD && DeviceHandler::instance->sd)
|
||||
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 == GCSDA && DeviceHandler::instance->gca)
|
||||
return DeviceHandler::instance->gca->GetFSName(0);
|
||||
else if(dev == GCSDB && DeviceHandler::instance->gcb)
|
||||
return DeviceHandler::instance->gcb->GetFSName(0);
|
||||
if(dev == SD && DeviceHandler::instance->sd)
|
||||
{
|
||||
return DeviceHandler::instance->sd->GetFSName(0);
|
||||
}
|
||||
else if(dev >= USB1 && dev <= USB8)
|
||||
{
|
||||
int partCount0 = 0;
|
||||
int partCount1 = 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)
|
||||
{
|
||||
const char *name = GetFSName(dev);
|
||||
if(!name) return -1;
|
||||
if(!instance)
|
||||
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;
|
||||
else if (strncasecmp(name, "FAT", 3) == 0)
|
||||
else if(strncmp(FSName, "FAT", 3) == 0)
|
||||
return PART_FS_FAT;
|
||||
else if (strncasecmp(name, "NTFS", 4) == 0)
|
||||
else if(strncmp(FSName, "NTFS", 4) == 0)
|
||||
return PART_FS_NTFS;
|
||||
else if (strncasecmp(name, "LINUX", 5) == 0)
|
||||
else if(strncmp(FSName, "LINUX", 4) == 0)
|
||||
return PART_FS_EXT;
|
||||
|
||||
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)
|
||||
{
|
||||
if(dev == SD && DeviceHandler::instance->sd)
|
||||
return DeviceHandler::instance->sd->GetWbfsHandle(0);
|
||||
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb)
|
||||
return DeviceHandler::instance->usb->GetWbfsHandle(dev-USB1);
|
||||
else if(dev == GCSDA && DeviceHandler::instance->gca)
|
||||
return DeviceHandler::instance->gca->GetWbfsHandle(0);
|
||||
else if(dev == GCSDB && DeviceHandler::instance->gcb)
|
||||
return DeviceHandler::instance->gcb->GetWbfsHandle(0);
|
||||
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb0)
|
||||
return DeviceHandler::instance->usb0->GetWbfsHandle(dev-USB1);
|
||||
else if(dev >= USB1 && dev <= USB8 && DeviceHandler::instance->usb1)
|
||||
return DeviceHandler::instance->usb1->GetWbfsHandle(dev-USB1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -331,13 +351,48 @@ s32 DeviceHandler::Open_WBFS(int dev)
|
||||
else if(dev >= USB1 && dev <= USB8 && IsInserted(dev))
|
||||
{
|
||||
part_idx = dev;
|
||||
part_lba = Instance()->usb->GetLBAStart(dev - USB1);
|
||||
part_lba = Instance()->usb0->GetLBAStart(dev - USB1);
|
||||
}
|
||||
else if(dev == GCSDA && IsInserted(dev))
|
||||
part_lba = Instance()->gca->GetLBAStart(dev);
|
||||
else if(dev == GCSDB && IsInserted(dev))
|
||||
part_lba = Instance()->gcb->GetLBAStart(dev);
|
||||
else return -1;
|
||||
else
|
||||
return -1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -27,95 +27,96 @@
|
||||
#define DEVICE_HANDLER_HPP_
|
||||
|
||||
#include "PartitionHandle.h"
|
||||
#include "usbstorage.h"
|
||||
#include "libwbfs/libwbfs.h"
|
||||
|
||||
/**
|
||||
* libogc device names.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SD = 0,
|
||||
USB1,
|
||||
USB2,
|
||||
USB3,
|
||||
USB4,
|
||||
USB5,
|
||||
USB6,
|
||||
USB7,
|
||||
USB8,
|
||||
GCSDA,
|
||||
GCSDB,
|
||||
MAXDEVICES
|
||||
SD = 0,
|
||||
USB1,
|
||||
USB2,
|
||||
USB3,
|
||||
USB4,
|
||||
USB5,
|
||||
USB6,
|
||||
USB7,
|
||||
USB8,
|
||||
MAXDEVICES
|
||||
};
|
||||
|
||||
const char DeviceName[MAXDEVICES][6] =
|
||||
/**
|
||||
* libogc device names.
|
||||
*/
|
||||
const char DeviceName[MAXDEVICES][8] =
|
||||
{
|
||||
"sd",
|
||||
"usb1",
|
||||
"usb2",
|
||||
"usb3",
|
||||
"usb4",
|
||||
"usb5",
|
||||
"usb6",
|
||||
"usb7",
|
||||
"usb8",
|
||||
"gca",
|
||||
"gcb",
|
||||
"sd",
|
||||
"usb1",
|
||||
"usb2",
|
||||
"usb3",
|
||||
"usb4",
|
||||
"usb5",
|
||||
"usb6",
|
||||
"usb7",
|
||||
"usb8",
|
||||
};
|
||||
|
||||
class DeviceHandler
|
||||
{
|
||||
public:
|
||||
public:
|
||||
static DeviceHandler * Instance();
|
||||
static void DestroyInstance();
|
||||
|
||||
bool MountAll();
|
||||
void UnMountAll();
|
||||
bool Mount(int dev);
|
||||
bool IsInserted(int dev);
|
||||
void UnMount(int dev);
|
||||
bool MountAll();
|
||||
void UnMountAll();
|
||||
bool Mount(int dev);
|
||||
bool IsInserted(int dev);
|
||||
void UnMount(int dev);
|
||||
|
||||
//! Individual Mounts/UnMounts...
|
||||
//! Individual Mounts/UnMounts...
|
||||
bool MountSD();
|
||||
bool MountUSB(int part);
|
||||
bool MountAllUSB();
|
||||
bool MountGCA();
|
||||
bool MountGCB();
|
||||
bool MountUSBPort1();
|
||||
|
||||
bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; };
|
||||
bool USB_Inserted() { if(usb) return usb->IsInserted(); return false; };
|
||||
bool GCA_Inserted() { if(gca) return gca->IsInserted(); return false; };
|
||||
bool GCB_Inserted() { if(gcb) return gcb->IsInserted(); return false; };
|
||||
bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; }
|
||||
bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; }
|
||||
bool USB1_Inserted() { if(usb1) return usb1->IsInserted(); return false; }
|
||||
|
||||
void UnMountSD() { if(sd) delete sd; sd = NULL; };
|
||||
void UnMountSD() { if(sd) delete sd; sd = NULL; }
|
||||
void UnMountUSB(int pos);
|
||||
void UnMountAllUSB();
|
||||
void UnMountGCA() { if(gca) delete gca; gca = NULL; };
|
||||
void UnMountGCB() { if(gcb) delete gcb; gcb = NULL; };
|
||||
|
||||
const PartitionHandle * GetSDHandle() { return sd; };
|
||||
const PartitionHandle * GetUSBHandle() { return usb; };
|
||||
const PartitionHandle * GetGCAHandle() { return gca; };
|
||||
const PartitionHandle * GetGCBHandle() { return gcb; };
|
||||
PartitionHandle * GetSDHandle() const { return sd; }
|
||||
PartitionHandle * GetUSB0Handle() const { return usb0; }
|
||||
PartitionHandle * GetUSB1Handle() const { return usb1; }
|
||||
|
||||
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 const char * GetFSName(int dev);
|
||||
static const char * GetFSName(int dev);
|
||||
static int GetFSType(int dev);
|
||||
s16 GetMountedCount(int dev);
|
||||
static const char * PathToFSName(const char * path) { return GetFSName(PathToDriveType(path)); };
|
||||
static wbfs_t * GetWbfsHandle(int dev);
|
||||
//static u32 GetLBAStart(int dev);
|
||||
static u16 GetUSBPartitionCount();
|
||||
static const char * PathToFSName(const char * path) { return GetFSName(PathToDriveType(path)); }
|
||||
static wbfs_t *GetWbfsHandle(int dev);
|
||||
s32 Open_WBFS(int dev);
|
||||
static int PartitionToUSBPort(int part);
|
||||
static int PartitionToPortPartition(int part);
|
||||
private:
|
||||
DeviceHandler() : sd(0), gca(0), gcb(0), usb0(0), usb1(0) { }
|
||||
~DeviceHandler();
|
||||
bool MountUSB(int part);
|
||||
|
||||
private:
|
||||
DeviceHandler() : sd(0), usb(0), gca(0), gcb(0) { };
|
||||
~DeviceHandler();
|
||||
static bool InternalSetWatchdog(unsigned int timeout);
|
||||
static DeviceHandler *instance;
|
||||
|
||||
static DeviceHandler * instance;
|
||||
static unsigned int watchdog_timeout;
|
||||
|
||||
PartitionHandle * sd;
|
||||
PartitionHandle * usb;
|
||||
PartitionHandle * gca;
|
||||
PartitionHandle * gcb;
|
||||
PartitionHandle * sd;
|
||||
PartitionHandle * gca;
|
||||
PartitionHandle * gcb;
|
||||
PartitionHandle * usb0;
|
||||
PartitionHandle * usb1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,6 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
* modified for Debugging, GPT, WBFS, and EXT by Miigotu
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* 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
|
||||
* distribution.
|
||||
*
|
||||
* By Dimok for WiiXplorer 2010
|
||||
* By Miigotu for WiiFlow 2010
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#include <gccore.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_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 SECTORS 64
|
||||
|
||||
extern u32 sector_size;
|
||||
|
||||
static inline const char * PartFromType(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0x00: return "Unused"; //Or WBFS
|
||||
case 0x00: return "Unused";
|
||||
case 0x01: return "FAT12";
|
||||
case 0x04: return "FAT16";
|
||||
case 0x05: return "Extended";
|
||||
@ -74,29 +75,32 @@ static inline const char * PartFromType(int type)
|
||||
case 0xa8: return "OSX";
|
||||
case 0xab: return "OSXBT";
|
||||
case 0xaf: return "OSXHF";
|
||||
case 0xbf: return "WBFS";
|
||||
case 0xe8: return "LUKS";
|
||||
case 0xee: return "GPT";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
PartitionHandle::PartitionHandle(const DISC_INTERFACE *discio)
|
||||
: interface(discio)
|
||||
{
|
||||
interface = discio;
|
||||
|
||||
// Sanity check
|
||||
if(!interface) return;
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
// Start the device and check that it is inserted
|
||||
if(!interface->startup()) return;
|
||||
if(!interface->isInserted()) return;
|
||||
if (!interface->startup())
|
||||
return;
|
||||
|
||||
if (!interface->isInserted())
|
||||
return;
|
||||
|
||||
FindPartitions();
|
||||
}
|
||||
|
||||
PartitionHandle::~PartitionHandle()
|
||||
{
|
||||
UnMountAll();
|
||||
UnMountAll();
|
||||
|
||||
//shutdown device
|
||||
if(!neek2o())
|
||||
@ -114,42 +118,71 @@ bool PartitionHandle::IsMounted(int pos)
|
||||
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(!name) return false;
|
||||
if(!valid(pos))
|
||||
return false;
|
||||
|
||||
if(!name)
|
||||
return false;
|
||||
|
||||
UnMount(pos);
|
||||
|
||||
if(pos >= (int) MountNameList.size())
|
||||
MountNameList.resize(GetPartitionCount());
|
||||
MountNameList.resize(pos+1);
|
||||
|
||||
MountNameList[pos] = name;
|
||||
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, GetLBAStart(pos), CACHE, SECTORS))
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if(strncmp(GetFSName(pos), "NTFS", 4) == 0)
|
||||
|
||||
if(strncmp(GetFSName(pos), "FAT", 3) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0)
|
||||
{
|
||||
if(ntfsMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, NTFS_SU | NTFS_RECOVER))
|
||||
if (fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS))
|
||||
{
|
||||
if(strcmp(GetFSName(pos), "GUID-Entry") == 0)
|
||||
PartitionList[pos].FSName = "FAT";
|
||||
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))
|
||||
{
|
||||
PartitionList[pos].FSName = "LINUX";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(strncmp(GetFSName(pos), "WBFS", 4) == 0)
|
||||
{
|
||||
if(interface == &__io_usbstorage)
|
||||
SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadUSB, __WBFS_WriteUSB, NULL, sector_size, GetSecCount(pos), GetLBAStart(pos), 0));
|
||||
if(interface == &__io_usbstorage2_port0 || interface == &__io_usbstorage2_port1)
|
||||
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))
|
||||
SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadSDHC, __WBFS_WriteSDHC, NULL, sector_size, GetSecCount(pos), GetLBAStart(pos), 0));
|
||||
|
||||
if(GetWbfsHandle(pos)) return true;
|
||||
SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadSDHC, __WBFS_WriteSDHC, NULL, 512, GetSecCount(pos), GetLBAStart(pos), 0));
|
||||
if(GetWbfsHandle(pos))
|
||||
return true;
|
||||
}
|
||||
|
||||
MountNameList[pos].clear();
|
||||
@ -159,282 +192,234 @@ bool PartitionHandle::Mount(int pos, const char * name)
|
||||
|
||||
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];
|
||||
snprintf(DeviceName, sizeof(DeviceName), "%s:", MountNameList[pos].c_str());
|
||||
char DeviceSyn[20];
|
||||
snprintf(DeviceSyn, sizeof(DeviceSyn), "%s:", MountNameList[pos].c_str());
|
||||
|
||||
wbfs_t* wbfshandle = GetWbfsHandle(pos);
|
||||
if(wbfshandle) wbfs_close(wbfshandle);
|
||||
SetWbfsHandle(pos, NULL);
|
||||
WBFS_Close();
|
||||
|
||||
fatUnmount(DeviceName);
|
||||
ntfsUnmount(DeviceName, true);
|
||||
ext2Unmount(DeviceName);
|
||||
|
||||
//Remove mount name from the list
|
||||
//closing all open Files write back the cache
|
||||
fatUnmount(DeviceSyn);
|
||||
//closing all open Files write back the cache
|
||||
ntfsUnmount(DeviceSyn, true);
|
||||
//closing all open Files write back the cache
|
||||
ext2Unmount(DeviceSyn);
|
||||
//Remove name from list
|
||||
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()
|
||||
{
|
||||
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR);
|
||||
if(mbr == NULL)
|
||||
return -1;
|
||||
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
|
||||
if(!mbr) return -1;
|
||||
|
||||
// Read the first sector on the device
|
||||
if(!interface->readSectors(0, 1, mbr))
|
||||
if (!interface->readSectors(0, 1, mbr))
|
||||
{
|
||||
MEM2_free(mbr);
|
||||
return 0;
|
||||
free(mbr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if it's a RAW disc, without a partition table
|
||||
if(CheckRAW((VOLUME_BOOT_RECORD *)mbr))
|
||||
// If this is the devices master boot record
|
||||
if (mbr->signature != MBR_SIGNATURE)
|
||||
{
|
||||
MEM2_free(mbr);
|
||||
return 1;
|
||||
}
|
||||
// Verify this is the device's master boot record
|
||||
if(mbr->signature != MBR_SIGNATURE)
|
||||
{
|
||||
MEM2_free(mbr);
|
||||
return 0;
|
||||
free(mbr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
PARTITION_RECORD * partition = (PARTITION_RECORD *)&mbr->partitions[i];
|
||||
VOLUME_BOOT_RECORD *vbr = (VOLUME_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR);
|
||||
if(!vbr)
|
||||
PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i];
|
||||
|
||||
if(partition->type == PARTITION_TYPE_GPT)
|
||||
{
|
||||
MEM2_free(mbr);
|
||||
return -1;
|
||||
int ret = CheckGPT(i);
|
||||
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(!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))
|
||||
if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED)
|
||||
{
|
||||
CheckEBR(i, le32(partition->lba_start));
|
||||
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)
|
||||
{
|
||||
EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *)MEM2_alloc(MAX_BYTES_PER_SECTOR);
|
||||
if(ebr == NULL)
|
||||
return;
|
||||
EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
|
||||
if(!ebr) return;
|
||||
sec_t next_erb_lba = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Check if the partition is WBFS
|
||||
bool isWBFS = memcmp((u8 *)ebr, WBFS_SIGNATURE, sizeof(WBFS_SIGNATURE)) == 0;
|
||||
|
||||
if(!isWBFS && ebr->signature != EBR_SIGNATURE)
|
||||
if (ebr->signature != EBR_SIGNATURE)
|
||||
{
|
||||
MEM2_free(ebr);
|
||||
free(ebr);
|
||||
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};
|
||||
PartitionEntry.FSName = isWBFS ? "WBFS" : PartFromType(ebr->partition.type);
|
||||
PartitionEntry.LBA_Start = ebr_lba + next_erb_lba + le32(ebr->partition.lba_start);
|
||||
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);
|
||||
AddPartition(PartFromType(ebr->partition.type), ebr_lba + next_erb_lba + le32(ebr->partition.lba_start),
|
||||
le32(ebr->partition.block_count), (ebr->partition.status == PARTITION_BOOTABLE),
|
||||
ebr->partition.type, PartNum);
|
||||
}
|
||||
// Get the start sector of the current partition
|
||||
// and the next extended boot record in the chain
|
||||
next_erb_lba = le32(ebr->next_ebr.lba_start);
|
||||
}
|
||||
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 };
|
||||
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 };
|
||||
|
||||
int PartitionHandle::CheckGPT(u8 PartNum)
|
||||
{
|
||||
GPT_PARTITION_TABLE *gpt = (GPT_PARTITION_TABLE *)MEM2_alloc(MAX_BYTES_PER_SECTOR);
|
||||
if(gpt == NULL)
|
||||
return false;
|
||||
bool success = false; // To return false unless at least 1 partition is verified
|
||||
GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_BYTES_PER_SECTOR);
|
||||
if(!gpt_header) return -1;
|
||||
|
||||
if(!interface->readSectors(1, 33, gpt))
|
||||
// Read and validate the extended boot record
|
||||
if (!interface->readSectors(1, 1, gpt_header))
|
||||
{
|
||||
MEM2_free(gpt);
|
||||
return false; // To read all 128 possible partitions
|
||||
free(gpt_header);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Verify this is the Primary GPT entry
|
||||
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))
|
||||
if(strncmp(gpt_header->magic, "EFI PART", 8) != 0)
|
||||
{
|
||||
MEM2_free(gpt);
|
||||
return false;
|
||||
free(gpt_header);
|
||||
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];
|
||||
VOLUME_BOOT_RECORD *vbr = (VOLUME_BOOT_RECORD*)MEM2_alloc(MAX_BYTES_PER_SECTOR);
|
||||
if(vbr == NULL)
|
||||
if (!interface->readSectors(next_lba, 1, sector_buf))
|
||||
break;
|
||||
|
||||
for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header->part_entry_size; ++n, ++i)
|
||||
{
|
||||
MEM2_free(gpt);
|
||||
return false;
|
||||
GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n);
|
||||
|
||||
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);
|
||||
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')
|
||||
{
|
||||
PartitionEntry.LBA_Start = Start;
|
||||
PartitionEntry.PartitionNum = i;
|
||||
|
||||
success = true;
|
||||
PartitionList.push_back(PartitionEntry);
|
||||
}
|
||||
MEM2_free(vbr);
|
||||
next_lba++;
|
||||
}
|
||||
MEM2_free(gpt);
|
||||
|
||||
return success;
|
||||
delete [] sector_buf;
|
||||
free(gpt_header);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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};
|
||||
if(memcmp((u8 *)vbr + BPB_NTFS_ADDR, NTFS_SIGNATURE, sizeof(NTFS_SIGNATURE)) == 0)
|
||||
char *buffer = (char *) malloc(MAX_BYTES_PER_SECTOR);
|
||||
|
||||
if (!interface->readSectors(lba_start, 1, buffer))
|
||||
{
|
||||
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;
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if(PartitionEntry.FSName[0] != '0')
|
||||
wbfs_head_t *head = (wbfs_head_t *) buffer;
|
||||
|
||||
if (head->magic == wbfs_htonl(WBFS_MAGIC))
|
||||
{
|
||||
PartitionList.push_back(PartitionEntry);
|
||||
return true;
|
||||
name = "WBFS";
|
||||
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);
|
||||
}
|
||||
|
@ -28,194 +28,149 @@
|
||||
|
||||
#include <gccore.h>
|
||||
#include "libwbfs/libwbfs.h"
|
||||
#include "usbstorage.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_PARTITIONS 32 /* Maximum number of partitions that can be found */
|
||||
#define MAX_MOUNTS 10 /* Maximum number of mounts available at one time */
|
||||
#define MAX_SYMLINK_DEPTH 10 /* Maximum search depth when resolving symbolic links */
|
||||
#define MAX_PARTITIONS 32 /* Maximum number of partitions that can be found */
|
||||
#define MAX_MOUNTS 10 /* Maximum number of mounts available at one time */
|
||||
#define MAX_SYMLINK_DEPTH 10 /* Maximum search depth when resolving symbolic links */
|
||||
|
||||
#define MBR_SIGNATURE 0x55AA
|
||||
#define EBR_SIGNATURE MBR_SIGNATURE
|
||||
#define VBR_SIGNATURE MBR_SIGNATURE
|
||||
#define GPT_SIGNATURE "EFI PART"
|
||||
#define MBR_SIGNATURE 0x55AA
|
||||
#define EBR_SIGNATURE MBR_SIGNATURE
|
||||
|
||||
#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */
|
||||
#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */
|
||||
#define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */
|
||||
#define PARTITION_TYPE_GPT 0xEE /* Indicates that a GPT header is available */
|
||||
|
||||
#define BYTES_PER_SECTOR 512 /* Default in libogc */
|
||||
#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 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 {
|
||||
u8 status; /* Partition status; see above */
|
||||
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
|
||||
u8 type; /* Partition type; see above */
|
||||
u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */
|
||||
u32 lba_start; /* Local block address to first sector of partition */
|
||||
u32 block_count; /* Number of blocks in partition */
|
||||
u8 status; /* Partition status; see above */
|
||||
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
|
||||
u8 type; /* Partition type; see above */
|
||||
u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */
|
||||
u32 lba_start; /* Local block address to first sector of partition */
|
||||
u32 block_count; /* Number of blocks in partition */
|
||||
} __attribute__((__packed__)) PARTITION_RECORD;
|
||||
|
||||
|
||||
typedef struct _MASTER_BOOT_RECORD {
|
||||
u8 code_area[440]; /* Code area; normally empty */
|
||||
u8 disk_guid[4]; /* Disk signature (optional) */
|
||||
u8 reserved[2]; /* Usually zeroed */
|
||||
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
|
||||
u16 signature; /* MBR signature; 0xAA55 */
|
||||
u8 code_area[446]; /* Code area; normally empty */
|
||||
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
|
||||
u16 signature; /* MBR signature; 0xAA55 */
|
||||
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
|
||||
|
||||
typedef struct _EXTENDED_BOOT_RECORD {
|
||||
u8 code_area[446]; /* Code area; normally empty */
|
||||
PARTITION_RECORD partition; /* Primary partition */
|
||||
PARTITION_RECORD next_ebr; /* Next extended boot record in the chain */
|
||||
u8 reserved[32]; /* Normally empty */
|
||||
u16 signature; /* EBR signature; 0xAA55 */
|
||||
u8 code_area[446]; /* Code area; normally empty */
|
||||
PARTITION_RECORD partition; /* Primary partition */
|
||||
PARTITION_RECORD next_ebr; /* Next extended boot record in the chain */
|
||||
u8 reserved[32]; /* Normally empty */
|
||||
u16 signature; /* EBR signature; 0xAA55 */
|
||||
} __attribute__((__packed__)) EXTENDED_BOOT_RECORD;
|
||||
|
||||
typedef struct _GUID_PARTITION_ENTRY
|
||||
typedef struct _GUID_PART_ENTRY
|
||||
{
|
||||
u8 Type_GUID[16]; /* Partition type GUID */
|
||||
u8 Unique_GUID[16]; /* Unique partition GUID */
|
||||
u64 First_LBA; /* First LBA (little-endian) */
|
||||
u64 Last_LBA; /* Last LBA (inclusive, usually odd) */
|
||||
u64 Attributes; /* GUID Attribute flags (e.g. bit 60 denotes read-only) */
|
||||
char Name[72]; /* Partition name (36 UTF-16LE code units) */
|
||||
} __attribute__((__packed__)) GUID_PARTITION_ENTRY;
|
||||
u8 part_type_guid[16]; /* Partition type GUID */
|
||||
u8 uniq_part_guid[16]; /* Unique partition GUID */
|
||||
u64 part_first_lba; /* First LBA (little-endian) */
|
||||
u64 part_last_lba; /* Last LBA (inclusive, usually odd) */
|
||||
u64 attribute_flags; /* GUID Attribute flags (e.g. bit 60 denotes read-only) */
|
||||
char partition_name[72]; /* Partition name (36 UTF-16LE code units) */
|
||||
} __attribute__((__packed__)) GUID_PART_ENTRY;
|
||||
|
||||
typedef struct _GPT_PARTITION_TABLE {
|
||||
char magic[8]; /* "EFI PART" */
|
||||
u32 Revision;
|
||||
u32 Header_Size; /* Size of this header */
|
||||
u32 CheckSum;
|
||||
u32 Reserved; /* Must be 0 */
|
||||
u64 Header_LBA; /* Location of this header, always 1 in primary copy */
|
||||
u64 Backup_Header_LBA; /* Location of backup header, always max lba - 1 */
|
||||
u64 First_Usable_LBA; /* Primary GPT partition table's last LBA + 1 */
|
||||
u64 Last_Usable_LBA; /* Secondary GPT partition table's first LBA - 1 */
|
||||
u8 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 */
|
||||
u32 Num_Entries; /* Number of entries in the partition info array */
|
||||
u32 Entry_Size; /* Size of each array entry, usually 128 */
|
||||
u32 Entries_CheckSum; /* CRC32 of partition array */
|
||||
u8 Zeroes[420]; /* Pad to a total 512 byte LBA or sizeof 1 LBA */
|
||||
GUID_PARTITION_ENTRY partitions[128]; /* Max 128 Partition Entries */
|
||||
} __attribute__((__packed__)) GPT_PARTITION_TABLE;
|
||||
typedef struct _GPT_HEADER
|
||||
{
|
||||
char magic[8]; /* "EFI PART" */
|
||||
u32 revision; /* For version 1.0 */
|
||||
u32 header_size; /* Header size in bytes */
|
||||
u32 checksum; /* CRC32 of header (0 to header size), with this field zeroed during calculation */
|
||||
u32 reserved; /* must be 0 */
|
||||
u64 header_lba; /* Current LBA (location of this header copy) */
|
||||
u64 backup_lba; /* Backup LBA (location of the other header copy) */
|
||||
u64 first_part_lba; /* First usable LBA for partitions (primary partition table last LBA + 1) */
|
||||
u64 last_part_lba; /* Last usable LBA (secondary partition table first LBA - 1) */
|
||||
u8 disk_guid[16]; /* Disk GUID (also referred as UUID on UNIXes) */
|
||||
u64 part_table_lba; /* Partition entries starting LBA (always 2 in primary copy) */
|
||||
u32 part_entries; /* Number of partition entries */
|
||||
u32 part_entry_size; /* Size of a partition entry (usually 128) */
|
||||
u32 part_entry_checksum; /* CRC32 of partition array */
|
||||
u8 zeros[420];
|
||||
} __attribute__((__packed__)) GPT_HEADER;
|
||||
|
||||
typedef struct _PartitionFS {
|
||||
const char * FSName;
|
||||
u32 LBA_Start;
|
||||
u32 SecCount;
|
||||
bool Bootable;
|
||||
u8 PartitionType;
|
||||
u8 PartitionNum;
|
||||
u32 EBR_Sector;
|
||||
const char * FSName;
|
||||
u64 LBA_Start;
|
||||
u64 SecCount;
|
||||
bool Bootable;
|
||||
u8 PartitionType;
|
||||
u8 PartitionNum;
|
||||
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
|
||||
{
|
||||
public:
|
||||
//! Constructor reads the MBR and all EBRs and lists up the Partitions
|
||||
PartitionHandle(const DISC_INTERFACE *discio);
|
||||
//! Destructor unmounts drives
|
||||
~PartitionHandle();
|
||||
//! Is Drive inserted
|
||||
bool IsInserted() { if(!interface) return false; else return interface->isInserted(); };
|
||||
//! Is the partition Mounted
|
||||
bool IsMounted(int pos);
|
||||
//! Mount a specific Partition
|
||||
bool Mount(int pos, const char * name);
|
||||
//! UnMount a specific Partition
|
||||
void UnMount(int pos);
|
||||
//! UnMount all Partition
|
||||
void UnMountAll() { for(u32 i = 0; i < PartitionList.size(); ++i) UnMount(i); };
|
||||
//! Get the Mountname
|
||||
const char * MountName(int pos) { if(pos < 0 || pos >= (int) MountNameList.size() || !MountNameList[pos].size()) return ""; else return MountNameList[pos].c_str(); };
|
||||
//! Get the Name of the FileSystem e.g. "FAT32"
|
||||
const char * GetFSName(int pos) { if(valid(pos)) return PartitionList[pos].FSName; else return ""; };
|
||||
//! Get the LBA where the partition is located
|
||||
u32 GetLBAStart(int pos) { if(valid(pos)) return PartitionList[pos].LBA_Start; else return 0; };
|
||||
//! Get the partition size in sectors of this partition
|
||||
u32 GetSecCount(int pos) { if(valid(pos)) return PartitionList[pos].SecCount; else return 0; };
|
||||
//! Check if the partition is Active or NonBootable
|
||||
bool IsActive(int pos) { if(valid(pos)) return PartitionList[pos].Bootable; else return false; };
|
||||
//! Get the partition type
|
||||
int GetPartitionType(int pos) { if(valid(pos)) return PartitionList[pos].PartitionType; else return -1; };
|
||||
//! Get the entrie number in MBR of this partition
|
||||
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
|
||||
int GetPartitionCount() { return PartitionList.size(); };
|
||||
//! Get the partition size in bytes
|
||||
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
|
||||
PartitionFS * GetPartitionRecord(int pos) { if(valid(pos)) return &PartitionList[pos]; else return NULL; };
|
||||
//! Get the disc interface of this handle
|
||||
const DISC_INTERFACE * GetDiscInterface() { return interface; };
|
||||
protected:
|
||||
bool valid(int pos) { return (pos >= 0 && pos < (int) PartitionList.size()); }
|
||||
bool CheckRAW(VOLUME_BOOT_RECORD * vbr);
|
||||
int FindPartitions();
|
||||
void CheckEBR(u8 PartNum, sec_t ebr_lba);
|
||||
bool CheckGPT(void);
|
||||
public:
|
||||
//! Constructor reads the MBR and all EBRs and lists up the Partitions
|
||||
PartitionHandle(const DISC_INTERFACE *discio);
|
||||
//! Destructor unmounts drives
|
||||
~PartitionHandle();
|
||||
//! Is Drive inserted
|
||||
bool IsInserted() { if(!interface) return false; else return interface->isInserted(); };
|
||||
//! Is the partition Mounted
|
||||
bool IsMounted(int pos);
|
||||
//! Mount a specific Partition
|
||||
bool Mount(int pos, const char * name, bool forceFAT = false);
|
||||
//! UnMount a specific Partition
|
||||
void UnMount(int pos);
|
||||
//! UnMount all Partition
|
||||
void UnMountAll() { for(u32 i = 0; i < PartitionList.size(); ++i) UnMount(i); };
|
||||
//! Get the Mountname
|
||||
const char * MountName(int pos) { if(pos < 0 || pos >= (int) MountNameList.size() || !MountNameList[pos].size()) return ""; else return MountNameList[pos].c_str(); };
|
||||
//! Get the Name of the FileSystem e.g. "FAT32"
|
||||
const char * GetFSName(int pos) { if(valid(pos)) return PartitionList[pos].FSName; else return ""; };
|
||||
//! Get the LBA where the partition is located
|
||||
u32 GetLBAStart(int pos) { if(valid(pos)) return PartitionList[pos].LBA_Start; else return 0; };
|
||||
//! Get the partition size in sectors of this partition
|
||||
u32 GetSecCount(int pos) { if(valid(pos)) return PartitionList[pos].SecCount; else return 0; };
|
||||
//! Check if the partition is Active or NonBootable
|
||||
bool IsActive(int pos) { if(valid(pos)) return PartitionList[pos].Bootable; else return false; };
|
||||
//! Get the partition type
|
||||
int GetPartitionType(int pos) { if(valid(pos)) return PartitionList[pos].PartitionType; else return -1; };
|
||||
//! Get the entrie number in MBR of this partition
|
||||
int GetPartitionNum(int pos) { if(valid(pos)) return PartitionList[pos].PartitionNum; else return -1; };
|
||||
//! Get the count of found partitions
|
||||
int GetPartitionCount() const { return PartitionList.size(); };
|
||||
//! Get the partition size in bytes
|
||||
u64 GetSize(int pos) { if(valid(pos)) return (u64) PartitionList[pos].SecCount*BYTES_PER_SECTOR; else return 0; };
|
||||
//! Get the whole partition record struct
|
||||
PartitionFS * GetPartitionRecord(int pos) { if(valid(pos)) return &PartitionList[pos]; else return NULL; };
|
||||
//! Get the disc interface of this handle
|
||||
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:
|
||||
bool valid(int pos) { return (pos >= 0 && pos < (int) PartitionList.size()); }
|
||||
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();
|
||||
void CheckEBR(u8 PartNum, sec_t ebr_lba);
|
||||
int CheckGPT(u8 PartNum);
|
||||
|
||||
const DISC_INTERFACE *interface;
|
||||
vector<PartitionFS> PartitionList;
|
||||
vector<std::string> MountNameList;
|
||||
const DISC_INTERFACE *interface;
|
||||
vector<PartitionFS> PartitionList;
|
||||
vector<string> MountNameList;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,299 +1,336 @@
|
||||
/*-------------------------------------------------------------
|
||||
|
||||
usbstorage_starlet.c -- USB mass storage support, inside starlet
|
||||
Copyright (C) 2009 Kwiirk
|
||||
usbstorage_starlet.c -- USB mass storage support, inside starlet
|
||||
Copyright (C) 2011 Dimok
|
||||
Copyright (C) 2011 Rodries
|
||||
Copyright (C) 2009 Kwiirk
|
||||
|
||||
If this driver is linked before libogc, this will replace the original
|
||||
usbstorage driver by svpe from libogc
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
If this driver is linked before libogc, this will replace the original
|
||||
usbstorage driver by svpe from libogc
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
-------------------------------------------------------------*/
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usbstorage.h"
|
||||
#include "memory/mem2.hpp"
|
||||
#include "gecko.h"
|
||||
|
||||
|
||||
/* IOCTL commands */
|
||||
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||
#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 USB_IOCTL_UMS_TESTMODE (UMS_BASE+0x81)
|
||||
#define USB_IOCTL_SET_PORT (UMS_BASE+0x83)
|
||||
|
||||
#define UMS_HEAPSIZE 0x8000
|
||||
#define USB_MEM2_SIZE 0x10000
|
||||
#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 */
|
||||
static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2";
|
||||
static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb123";
|
||||
static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
|
||||
|
||||
static u8 * mem2_ptr = NULL;
|
||||
static s32 hid = -1, fd = -1;
|
||||
u32 sector_size;
|
||||
static void *usb_buf2;
|
||||
static u32 usb2_port = -1; //current USB port
|
||||
bool hddInUse[2] = { false, false };
|
||||
u32 hdd_sector_size[2] = { 512, 512 };
|
||||
|
||||
extern void* SYS_AllocArena2MemLo(u32 size,u32 align);
|
||||
|
||||
inline s32 __USBStorage_isMEM2Buffer(const void *buffer)
|
||||
s32 USBStorage2_Init(u32 port)
|
||||
{
|
||||
u32 high_addr = ((u32)buffer) >> 24;
|
||||
|
||||
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", §or_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;
|
||||
}
|
||||
|
||||
s32 USBStorage_OpenDev()
|
||||
{
|
||||
/* Already open */
|
||||
if (fd >= 0) return fd;
|
||||
if(hddInUse[port])
|
||||
return 0;
|
||||
|
||||
/* Create heap */
|
||||
if (hid < 0)
|
||||
{
|
||||
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 */
|
||||
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(fs3, 0);
|
||||
return fd;
|
||||
}
|
||||
|
||||
s32 USBStorage_SetWatchdog(u32 seconds)
|
||||
{
|
||||
if (fd < 0) return fd;
|
||||
|
||||
static ioctlv vector[1] ATTRIBUTE_ALIGN(32);
|
||||
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;
|
||||
USBStorage2_SetPort(port);
|
||||
|
||||
/* Initialize USB storage */
|
||||
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
|
||||
IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
|
||||
|
||||
/* Get device capacity */
|
||||
ret = USBStorage_GetCapacity(NULL);
|
||||
if (!ret) goto err;
|
||||
if (USBStorage2_GetCapacity(port, &hdd_sector_size[port]) == 0)
|
||||
return IPC_ENOENT;
|
||||
|
||||
return 0;
|
||||
hddInUse[port] = true;
|
||||
|
||||
err:
|
||||
/* Close USB device */
|
||||
if (fd >= 0)
|
||||
{
|
||||
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;
|
||||
return 0; // 0->HDD, 1->DVD
|
||||
}
|
||||
|
||||
void USBStorage_Deinit(void)
|
||||
void USBStorage2_Deinit()
|
||||
{
|
||||
/* Close USB device */
|
||||
if (fd >= 0)
|
||||
{
|
||||
IOS_Close(fd);
|
||||
IOS_Close(fd); // not sure to close the fd is needed
|
||||
fd = -1;
|
||||
}
|
||||
/* if (hid > 0) {
|
||||
iosDestroyHeap(hid);
|
||||
hid = -1;
|
||||
} */
|
||||
USB_Deinitialize();
|
||||
}
|
||||
|
||||
s32 USBStorage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
|
||||
s32 USBStorage2_SetPort(u32 port)
|
||||
{
|
||||
void *buf = (void *)buffer;
|
||||
u32 len = (sector_size * numSectors);
|
||||
s32 ret;
|
||||
//! Port = 2 is handle in the loader, no need to handle it in cIOS
|
||||
if(port > 1)
|
||||
return -1;
|
||||
|
||||
/* Device not opened */
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
if(port == usb2_port)
|
||||
return 0;
|
||||
|
||||
/* MEM1 buffer */
|
||||
if (!__USBStorage_isMEM2Buffer(buffer))
|
||||
{
|
||||
/* Allocate memory */
|
||||
//buf = iosAlloc(hid, len);
|
||||
buf = usb_buf2;
|
||||
if (!buf) return IPC_ENOMEM;
|
||||
}
|
||||
s32 ret = -1;
|
||||
usb2_port = port;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
gprintf("Changing USB port to port %i....\n", port);
|
||||
//must be called before USBStorage2_Init (default port 0)
|
||||
if (fd >= 0)
|
||||
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_SET_PORT, "i:", usb2_port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
|
||||
s32 USBStorage2_GetPort()
|
||||
{
|
||||
void *buf = (void *)buffer;
|
||||
u32 len = (sector_size * numSectors);
|
||||
s32 ret;
|
||||
return usb2_port;
|
||||
}
|
||||
|
||||
s32 USBStorage2_GetCapacity(u32 port, u32 *_sector_size)
|
||||
{
|
||||
if (fd >= 0)
|
||||
{
|
||||
s32 ret;
|
||||
u32 sector_size = 0;
|
||||
USBStorage2_SetPort(port);
|
||||
|
||||
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", §or_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 */
|
||||
if (fd < 0) return fd;
|
||||
|
||||
/* MEM1 buffer */
|
||||
if (!__USBStorage_isMEM2Buffer(buffer))
|
||||
if (!mem2_ptr)
|
||||
mem2_ptr = (u8 *) MEM2_alloc(MAX_SECTOR_SIZE * MAX_BUFFER_SECTORS);
|
||||
|
||||
USBStorage2_SetPort(port);
|
||||
|
||||
s32 read_secs, read_size;
|
||||
|
||||
while(numSectors > 0)
|
||||
{
|
||||
/* Allocate memory */
|
||||
//buf = iosAlloc(hid, len);
|
||||
buf = usb_buf2;
|
||||
if (!buf) return IPC_ENOMEM;
|
||||
read_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
|
||||
read_size = read_secs*hdd_sector_size[port];
|
||||
|
||||
/* Copy data */
|
||||
memcpy(buf, buffer, len);
|
||||
// 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;
|
||||
}
|
||||
|
||||
sector += read_secs;
|
||||
numSectors -= read_secs;
|
||||
buf += read_size;
|
||||
}
|
||||
|
||||
/* Write data */
|
||||
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buf, len);
|
||||
|
||||
/* Free memory */
|
||||
//if (buf != buffer)
|
||||
// iosFree(hid, buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// DISC_INTERFACE methods
|
||||
|
||||
static bool __io_usb_IsInserted(void)
|
||||
s32 USBStorage2_WriteSectors(u32 port, u32 sector, u32 numSectors, const void *buffer)
|
||||
{
|
||||
s32 ret;
|
||||
u32 sec_size;
|
||||
if (fd < 0)
|
||||
return false;
|
||||
u8 *buf = (u8 *) buffer;
|
||||
s32 ret = -1;
|
||||
|
||||
ret = USBStorage_GetCapacity(&sec_size);
|
||||
if (ret == 0)
|
||||
return false;
|
||||
return true;
|
||||
/* Device not opened */
|
||||
if (fd < 0) return fd;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
sector += write_secs;
|
||||
numSectors -= write_secs;
|
||||
buf += write_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool __io_usb_Startup(void)
|
||||
s32 USBStorage2_GetSectorSize()
|
||||
{
|
||||
if (USBStorage_Init() < 0) return false;
|
||||
return __io_usb_IsInserted();
|
||||
return hdd_sector_size[usb2_port];
|
||||
}
|
||||
|
||||
bool __io_usb_ReadSectors(u32 sector, u32 count, void *buffer)
|
||||
static bool __usbstorage_Startup(void)
|
||||
{
|
||||
return USBStorage_ReadSectors(sector, count, buffer) >= 0;
|
||||
return USBStorage2_Init(0) >= 0;
|
||||
}
|
||||
|
||||
bool __io_usb_WriteSectors(u32 sector, u32 count, void *buffer)
|
||||
static bool __usbstorage_IsInserted(void)
|
||||
{
|
||||
return USBStorage_WriteSectors(sector, count, buffer) >= 0;
|
||||
return (USBStorage2_GetCapacity(0, NULL) != 0);
|
||||
}
|
||||
|
||||
static bool __io_usb_ClearStatus(void)
|
||||
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;
|
||||
}
|
||||
|
||||
static bool __io_usb_Shutdown(void)
|
||||
static bool __usbstorage_Shutdown(void)
|
||||
{
|
||||
// do nothing
|
||||
hddInUse[0] = false;
|
||||
hdd_sector_size[0] = 512;
|
||||
return true;
|
||||
}
|
||||
|
||||
DISC_INTERFACE __io_usbstorage = {
|
||||
DEVICE_TYPE_WII_USB,
|
||||
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
|
||||
(FN_MEDIUM_STARTUP) &__io_usb_Startup,
|
||||
(FN_MEDIUM_ISINSERTED) &__io_usb_IsInserted,
|
||||
(FN_MEDIUM_READSECTORS) &__io_usb_ReadSectors,
|
||||
(FN_MEDIUM_WRITESECTORS) &__io_usb_WriteSectors,
|
||||
(FN_MEDIUM_CLEARSTATUS) &__io_usb_ClearStatus,
|
||||
(FN_MEDIUM_SHUTDOWN) &__io_usb_Shutdown
|
||||
const DISC_INTERFACE __io_usbstorage2_port0 = {
|
||||
DEVICE_TYPE_WII_UMS, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
|
||||
(FN_MEDIUM_STARTUP) &__usbstorage_Startup,
|
||||
(FN_MEDIUM_ISINSERTED) &__usbstorage_IsInserted,
|
||||
(FN_MEDIUM_READSECTORS) &__usbstorage_ReadSectors,
|
||||
(FN_MEDIUM_WRITESECTORS) &__usbstorage_WriteSectors,
|
||||
(FN_MEDIUM_CLEARSTATUS) &__usbstorage_ClearStatus,
|
||||
(FN_MEDIUM_SHUTDOWN) &__usbstorage_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
|
||||
};
|
@ -1,22 +1,32 @@
|
||||
#ifndef _USBSTORAGE_H_
|
||||
#define _USBSTORAGE_H_
|
||||
#ifndef _USBSTORAGE2_H_
|
||||
#define _USBSTORAGE2_H_
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include "ogc/disc_io.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Prototypes */
|
||||
s32 USBStorage_GetCapacity(u32 *);
|
||||
s32 USBStorage_SetWatchdog(u32);
|
||||
s32 USBStorage_Init(void);
|
||||
void USBStorage_Deinit(void);
|
||||
s32 USBStorage_ReadSectors(u32, u32, void *);
|
||||
s32 USBStorage_WriteSectors(u32, u32, void *);
|
||||
/* Prototypes */
|
||||
s32 USBStorage2_Init(u32 port);
|
||||
void USBStorage2_Deinit();
|
||||
s32 USBStorage2_GetCapacity(u32 port, u32 *size);
|
||||
|
||||
s32 USBStorage2_ReadSectors(u32 port, u32 sector, u32 numSectors, void *buffer);
|
||||
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
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -87,7 +87,7 @@ bool loadIOS(int ios, bool launch_game)
|
||||
DeviceHandler::Instance()->UnMountAll();
|
||||
|
||||
WDVD_Close();
|
||||
USBStorage_Deinit();
|
||||
USBStorage2_Deinit();
|
||||
mload_close();
|
||||
|
||||
bool iosOK = IOS_ReloadIOS(ios) == 0;
|
||||
|
@ -29,8 +29,6 @@
|
||||
/* WBFS device */
|
||||
s32 wbfsDev = WBFS_MIN_DEVICE;
|
||||
|
||||
extern u32 sector_size;
|
||||
|
||||
// partition
|
||||
int wbfs_part_fs = PART_FS_WBFS;
|
||||
u32 wbfs_part_idx = 0;
|
||||
@ -99,7 +97,7 @@ s32 __WBFS_ReadUSB(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
/* Do reads */
|
||||
while (cnt < count)
|
||||
{
|
||||
fp = ((u8 *)iobuf) + (cnt * sector_size);
|
||||
fp = ((u8 *)iobuf) + (cnt * USBStorage2_GetSectorSize());
|
||||
u32 sectors = (count - cnt);
|
||||
|
||||
/* Read sectors is too big */
|
||||
@ -107,7 +105,7 @@ s32 __WBFS_ReadUSB(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
sectors = MAX_NB_SECTORS;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Increment counter */
|
||||
@ -124,7 +122,7 @@ s32 __WBFS_WriteUSB(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
/* Do writes */
|
||||
while (cnt < count)
|
||||
{
|
||||
fp = ((u8 *)iobuf) + (cnt * sector_size);
|
||||
fp = ((u8 *)iobuf) + (cnt * USBStorage2_GetSectorSize());
|
||||
u32 sectors = (count - cnt);
|
||||
|
||||
/* Write sectors is too big */
|
||||
@ -132,7 +130,7 @@ s32 __WBFS_WriteUSB(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
sectors = MAX_NB_SECTORS;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Increment counter */
|
||||
@ -149,7 +147,7 @@ s32 __WBFS_ReadSDHC(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
/* Do reads */
|
||||
while (cnt < count)
|
||||
{
|
||||
fp = ((u8 *)iobuf) + (cnt * sector_size);
|
||||
fp = ((u8 *)iobuf) + (cnt * 512);
|
||||
u32 sectors = (count - cnt);
|
||||
|
||||
/* Read sectors is too big */
|
||||
@ -175,7 +173,7 @@ s32 __WBFS_WriteSDHC(void* fp, u32 lba, u32 count, void *iobuf)
|
||||
/* Do writes */
|
||||
while (cnt < count)
|
||||
{
|
||||
fp = ((u8 *)iobuf) + (cnt * sector_size);
|
||||
fp = ((u8 *)iobuf) + (cnt * 512);
|
||||
u32 sectors = (count - cnt);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
u32 sector_size = (currentPartition == 0) ? 512 : USBStorage2_GetSectorSize();
|
||||
u32 wbfs_sector_size = sector_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)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -26,8 +26,6 @@
|
||||
#define MAX_FAT_PATH 1024
|
||||
#define TITLE_LEN 64
|
||||
|
||||
extern u32 sector_size;
|
||||
|
||||
char wbfs_fs_drive[16];
|
||||
char wbfs_ext_dir[16] = "/wbfs";
|
||||
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)
|
||||
{
|
||||
bool sd = strstr(fname, "sd") != NULL;
|
||||
if (strcasecmp(strrchr(fname,'.'), ".iso") == 0)
|
||||
{
|
||||
// .iso file
|
||||
@ -58,7 +57,7 @@ wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname)
|
||||
return NULL;
|
||||
|
||||
// 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->header = (void*)fd;
|
||||
return iso_file;
|
||||
@ -116,12 +115,13 @@ s32 WBFS_Ext_DiskSpace(f32 *used, f32 *free)
|
||||
|
||||
wbfs_t* WBFS_Ext_OpenPart(char *fname)
|
||||
{
|
||||
bool sd = strstr(fname, "sd") != NULL;
|
||||
if(split_open(&split, fname) < 0)
|
||||
return NULL;
|
||||
|
||||
wbfs_set_force_mode(1);
|
||||
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);
|
||||
|
||||
if (!part)
|
||||
@ -223,17 +223,16 @@ s32 WBFS_Ext_AddGame(progress_callback_t spinner, void *spinner_data)
|
||||
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;
|
||||
u32 n_sector = size / 512;
|
||||
|
||||
// init a temporary dummy part
|
||||
// as a placeholder for wbfs_size_disc
|
||||
wbfs_t *part = wbfs_open_partition(
|
||||
0, 0,
|
||||
NULL, sector_size, n_sector, 0, 1);
|
||||
if (!part) return -1;
|
||||
wbfs_t *part = wbfs_open_partition(0, 0, NULL, sd ? 512 : USBStorage2_GetSectorSize(), n_sector, 0, 1);
|
||||
if (!part)
|
||||
return -1;
|
||||
|
||||
u32 comp_sec = 0, last_sec = 0;
|
||||
s32 ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION, &comp_sec, &last_sec);
|
||||
|
@ -16,7 +16,7 @@ void WBFS_Ext_CloseDisc(wbfs_disc_t* disc);
|
||||
s32 WBFS_Ext_DiskSpace(f32 *used, f32 *free);
|
||||
s32 WBFS_Ext_RemoveGame(u8 *discid, char *path);
|
||||
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);
|
||||
|
||||
char* strcopy(char *dest, const char *src, int size);
|
||||
|
@ -88,19 +88,18 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Open_Inputs(); //(re)init wiimote
|
||||
#ifndef DOLPHIN
|
||||
const DISC_INTERFACE *handle = DeviceHandler::GetUSB0Interface();
|
||||
bool deviceAvailable = false;
|
||||
u8 timeout = 0;
|
||||
DeviceHandler::Instance()->MountSD();
|
||||
while(!deviceAvailable && timeout++ != 20)
|
||||
{
|
||||
DeviceHandler::Instance()->MountAll();
|
||||
sleep(1);
|
||||
|
||||
for(u8 device = USB1; device <= USB8; device++)
|
||||
{
|
||||
if(DeviceHandler::Instance()->IsInserted(device))
|
||||
deviceAvailable = true;
|
||||
}
|
||||
deviceAvailable = (handle->startup() && handle->isInserted());
|
||||
if(deviceAvailable)
|
||||
break;
|
||||
usleep(50000);
|
||||
}
|
||||
DeviceHandler::Instance()->MountAllUSB();
|
||||
if(DeviceHandler::Instance()->IsInserted(SD))
|
||||
deviceAvailable = true;
|
||||
#else
|
||||
|
@ -309,7 +309,7 @@ void CMenu::init(void)
|
||||
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()));
|
||||
|
||||
DeviceHandler::SetWatchdog(m_cfg.getUInt("GENERAL", "watchdog_timeout", 10));
|
||||
//DeviceHandler::SetWatchdog(m_cfg.getUInt("GENERAL", "watchdog_timeout", 10));
|
||||
|
||||
const char *domain = _domainFromView();
|
||||
const char *checkDir = m_current_view == COVERFLOW_HOMEBREW ? HOMEBREW_DIR : GAMES_DIR;
|
||||
@ -491,7 +491,7 @@ void CMenu::cleanup()
|
||||
{
|
||||
if(cleaned_up)
|
||||
return;
|
||||
|
||||
gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize());
|
||||
m_cf.stopCoverLoader();
|
||||
_cleanupDefaultFont();
|
||||
m_cf.clear();
|
||||
@ -542,6 +542,7 @@ void CMenu::cleanup()
|
||||
|
||||
cleaned_up = true;
|
||||
gprintf(" \nMemory cleaned up\n");
|
||||
gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize());
|
||||
}
|
||||
|
||||
void CMenu::_reload_wifi_gecko(void)
|
||||
|
@ -61,7 +61,6 @@ extern const u8 blank_png[];
|
||||
extern const u8 gc_ogg[];
|
||||
extern const u32 gc_ogg_size;
|
||||
|
||||
extern u32 sector_size;
|
||||
extern u32 boot2version;
|
||||
extern int mainIOS;
|
||||
static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32);
|
||||
@ -871,7 +870,7 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
|
||||
cleanup();
|
||||
#ifndef DOLPHIN
|
||||
ISFS_Deinitialize();
|
||||
USBStorage_Deinit();
|
||||
USBStorage2_Deinit();
|
||||
SDHC_Init();
|
||||
#endif
|
||||
GC_SetVideoMode(videoMode, videoSetting);
|
||||
@ -910,7 +909,7 @@ void CMenu::_launchHomebrew(const char *filepath, vector<string> arguments)
|
||||
AddBootArgument(arguments[i].c_str());
|
||||
#ifndef DOLPHIN
|
||||
ISFS_Deinitialize();
|
||||
USBStorage_Deinit();
|
||||
USBStorage2_Deinit();
|
||||
#endif
|
||||
//MEM2_clear();
|
||||
BootHomebrew(title);
|
||||
@ -1285,8 +1284,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
Nand::Instance()->Do_Region_Change(id);
|
||||
}
|
||||
}
|
||||
|
||||
if(!dvd && get_frag_list((u8 *)id.c_str(), (char*)path.c_str(), currentPartition == 0 ? 0x200 : sector_size) < 0)
|
||||
if(!dvd && get_frag_list((u8 *)id.c_str(), (char*)path.c_str(), currentPartition == 0 ? 0x200 : USBStorage2_GetSectorSize()) < 0)
|
||||
return;
|
||||
|
||||
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
|
||||
ISFS_Deinitialize();
|
||||
USBStorage_Deinit();
|
||||
USBStorage2_Deinit();
|
||||
if(currentPartition == 0)
|
||||
SDHC_Init();
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "WavDecoder.hpp"
|
||||
#include "loader/sys.h"
|
||||
|
||||
#define MAX_SND_VOICES 16
|
||||
#define MAX_SND_VOICES 16
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -56,8 +56,7 @@ static inline int GetFirstUnusedVoice()
|
||||
extern "C" void SoundCallback(s32 voice)
|
||||
{
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
return;
|
||||
if(!decoder) return;
|
||||
|
||||
if(decoder->IsBufferReady())
|
||||
{
|
||||
@ -70,7 +69,7 @@ extern "C" void SoundCallback(s32 voice)
|
||||
else if(decoder->IsEOF())
|
||||
ASND_StopVoice(voice);
|
||||
else
|
||||
SoundHandler::Instance()->ThreadSignal();
|
||||
SoundHandler::Instance()->ThreadSignal();
|
||||
}
|
||||
|
||||
GuiSound::GuiSound()
|
||||
@ -99,13 +98,12 @@ GuiSound::GuiSound(GuiSound *g)
|
||||
voice = -1;
|
||||
|
||||
Init();
|
||||
if (g == NULL)
|
||||
return;
|
||||
if (g == NULL) return;
|
||||
|
||||
if (g->sound != NULL)
|
||||
{
|
||||
u8 *snd = (u8 *)MEM1_alloc(g->length);
|
||||
memcpy(snd, g->sound, length);
|
||||
u8 * snd = (u8 *) malloc(g->length);
|
||||
memcpy(snd, g->sound, g->length);
|
||||
Load(snd, g->length, true);
|
||||
}
|
||||
else
|
||||
@ -144,9 +142,11 @@ void GuiSound::FreeMemory()
|
||||
|
||||
if(allocated)
|
||||
{
|
||||
MEM1_free(sound);
|
||||
free(sound);
|
||||
allocated = false;
|
||||
}
|
||||
sound = NULL;
|
||||
length = 0;
|
||||
filepath = "";
|
||||
|
||||
SoundEffectLength = 0;
|
||||
@ -161,8 +161,7 @@ bool GuiSound::Load(const char * filepath)
|
||||
|
||||
FILE * f = fopen(filepath, "rb");
|
||||
if(!f)
|
||||
{
|
||||
gprintf("Failed to load file %s!!\n", filepath);
|
||||
{ gprintf("Failed to load file %s!!\n", filepath);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -174,14 +173,12 @@ bool GuiSound::Load(const char * filepath)
|
||||
gprintf("Loading %s using voice %d\n", filepath, voice);
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
{
|
||||
gprintf("No Decoder!!!\n");
|
||||
{ gprintf("No Decoder!!!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!decoder->IsBufferReady())
|
||||
{
|
||||
gprintf("Buffer not ready!!\n");
|
||||
{ gprintf("Buffer not ready!!n");
|
||||
SoundHandler::Instance()->RemoveDecoder(voice);
|
||||
return false;
|
||||
}
|
||||
@ -197,14 +194,15 @@ bool GuiSound::Load(const u8 * snd, u32 len, bool isallocated)
|
||||
FreeMemory();
|
||||
this->voice = voice;
|
||||
|
||||
if(!snd)
|
||||
return false;
|
||||
if(!snd) return false;
|
||||
|
||||
if(!isallocated && *((u32 *) snd) == 'RIFF')
|
||||
return LoadSoundEffect(snd, len);
|
||||
|
||||
if(*((u32 *) snd) == 'IMD5')
|
||||
{
|
||||
UncompressSoundbin(snd, len, isallocated);
|
||||
}
|
||||
else
|
||||
{
|
||||
sound = (u8 *) snd;
|
||||
@ -216,7 +214,9 @@ bool GuiSound::Load(const u8 * snd, u32 len, bool isallocated)
|
||||
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!decoder->IsBufferReady())
|
||||
{
|
||||
@ -237,15 +237,15 @@ bool GuiSound::LoadSoundEffect(const u8 * snd, u32 len)
|
||||
decoder.Rewind();
|
||||
|
||||
u32 done = 0;
|
||||
sound = (u8 *)MEM1_alloc(4096);
|
||||
sound = (u8 *)malloc(4096);
|
||||
memset(sound, 0, 4096);
|
||||
|
||||
while(1)
|
||||
{
|
||||
u8 * tmpsnd = (u8 *)MEM1_realloc(sound, done+4096);
|
||||
u8 * tmpsnd = (u8 *)realloc(sound, done+4096);
|
||||
if(!tmpsnd)
|
||||
{
|
||||
MEM1_free(sound);
|
||||
free(sound);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -253,12 +253,12 @@ bool GuiSound::LoadSoundEffect(const u8 * snd, u32 len)
|
||||
|
||||
int read = decoder.Read(sound+done, 4096, done);
|
||||
if(read <= 0)
|
||||
break;
|
||||
break;
|
||||
|
||||
done += read;
|
||||
}
|
||||
|
||||
sound = (u8 *)MEM1_realloc(sound, done);
|
||||
sound = (u8 *)realloc(sound, done);
|
||||
SoundEffectLength = done;
|
||||
allocated = true;
|
||||
|
||||
@ -274,15 +274,10 @@ void GuiSound::Play(int vol, bool restart)
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsPlaying() && !restart)
|
||||
return;
|
||||
|
||||
if(voice < 0 || voice >= 16)
|
||||
return;
|
||||
if((IsPlaying() && !restart) || voice < 0 || voice >= 16) return;
|
||||
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
return;
|
||||
if(!decoder) return;
|
||||
|
||||
ASND_StopVoice(voice);
|
||||
if(decoder->IsEOF())
|
||||
@ -307,16 +302,14 @@ void GuiSound::Play()
|
||||
|
||||
void GuiSound::Stop()
|
||||
{
|
||||
if (!IsPlaying()) return;
|
||||
|
||||
if(voice < 0 || voice >= 16)
|
||||
volume = 0;
|
||||
if (!IsPlaying() || voice < 0 || voice >= 16)
|
||||
return;
|
||||
|
||||
ASND_StopVoice(voice);
|
||||
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
return;
|
||||
if(!decoder) return;
|
||||
|
||||
decoder->ClearBuffer();
|
||||
Rewind();
|
||||
@ -357,10 +350,7 @@ int GuiSound::GetVolume()
|
||||
|
||||
void GuiSound::SetVolume(int vol)
|
||||
{
|
||||
if(voice < 0 || voice >= 16)
|
||||
return;
|
||||
|
||||
if(vol < 0)
|
||||
if(voice < 0 || voice >= 16 || vol < 0)
|
||||
return;
|
||||
|
||||
volume = vol;
|
||||
@ -372,8 +362,7 @@ void GuiSound::SetLoop(u8 l)
|
||||
loop = l;
|
||||
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
return;
|
||||
if(!decoder) return;
|
||||
|
||||
decoder->SetLoop(l == 1);
|
||||
}
|
||||
@ -381,16 +370,15 @@ void GuiSound::SetLoop(u8 l)
|
||||
void GuiSound::Rewind()
|
||||
{
|
||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||
if(!decoder)
|
||||
return;
|
||||
if(!decoder) return;
|
||||
|
||||
decoder->Rewind();
|
||||
}
|
||||
|
||||
struct _LZ77Info
|
||||
{
|
||||
u16 length : 4;
|
||||
u16 offset : 12;
|
||||
u16 length : 4;
|
||||
u16 offset : 12;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _LZ77Info LZ77Info;
|
||||
@ -407,10 +395,9 @@ u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size)
|
||||
const u8 *inBufEnd = inBuf + inLength;
|
||||
inBuf += 8;
|
||||
|
||||
buffer = (u8 *)MEM1_alloc(uncSize);
|
||||
buffer = (u8 *)malloc(uncSize);
|
||||
|
||||
if (!buffer)
|
||||
return buffer;
|
||||
if (!buffer) return buffer;
|
||||
|
||||
u8 *bufCur = buffer;
|
||||
u8 *bufEnd = buffer + uncSize;
|
||||
@ -428,7 +415,7 @@ u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size)
|
||||
inBuf += sizeof (LZ77Info);
|
||||
int length = info->length + 3;
|
||||
if (bufCur - info->offset - 1 < buffer || bufCur + length > bufEnd)
|
||||
return buffer;
|
||||
return buffer;
|
||||
memcpy(bufCur, bufCur - info->offset - 1, length);
|
||||
bufCur += length;
|
||||
}
|
||||
@ -452,8 +439,7 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
|
||||
const u8 * file = snd+32;
|
||||
|
||||
length = len-32;
|
||||
if (length <= 0)
|
||||
return;
|
||||
if (length <= 0) return;
|
||||
|
||||
if(*((u32 *) file) == 'LZ77')
|
||||
{
|
||||
@ -468,7 +454,7 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
|
||||
}
|
||||
else
|
||||
{
|
||||
sound = (u8 *)MEM1_alloc(length);
|
||||
sound = (u8 *)malloc(length);
|
||||
if (!sound)
|
||||
{
|
||||
length = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user