2012-01-21 21:57:41 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Copyright (C) 2010
|
|
|
|
* by Dimok
|
|
|
|
*
|
|
|
|
* 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:
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 3. This notice may not be removed or altered from any source
|
|
|
|
* distribution.
|
|
|
|
*
|
|
|
|
* for WiiXplorer 2010
|
|
|
|
***************************************************************************/
|
2012-07-18 16:09:28 +02:00
|
|
|
#include <malloc.h>
|
2012-01-21 21:57:41 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ogc/mutex.h>
|
|
|
|
#include <ogc/system.h>
|
|
|
|
#include <sdcard/gcsd.h>
|
2012-07-14 20:32:52 +02:00
|
|
|
#include <sdcard/wiisd_io.h>
|
2012-07-16 16:05:57 +02:00
|
|
|
#include "cios.h"
|
2012-01-21 21:57:41 +01:00
|
|
|
#include "DeviceHandler.hpp"
|
|
|
|
#include "wbfs.h"
|
|
|
|
#include "usbstorage.h"
|
|
|
|
|
2012-07-14 18:19:41 +02:00
|
|
|
#ifdef DOLPHIN
|
|
|
|
const DISC_INTERFACE __io_sdhc = __io_wiisd;
|
|
|
|
#else
|
2012-01-21 21:57:41 +01:00
|
|
|
extern const DISC_INTERFACE __io_sdhc;
|
2012-07-14 18:19:41 +02:00
|
|
|
#endif
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
DeviceHandler * DeviceHandler::instance = NULL;
|
|
|
|
|
|
|
|
DeviceHandler::~DeviceHandler()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
UnMountAll();
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DeviceHandler * DeviceHandler::Instance()
|
|
|
|
{
|
|
|
|
if (instance == NULL)
|
2012-07-18 16:09:28 +02:00
|
|
|
{
|
2012-01-21 21:57:41 +01:00
|
|
|
instance = new DeviceHandler();
|
2012-07-18 16:09:28 +02:00
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceHandler::DestroyInstance()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(instance)
|
|
|
|
{
|
|
|
|
delete instance;
|
|
|
|
}
|
|
|
|
instance = NULL;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountAll()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
bool result = false;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(u32 i = SD; i < MAXDEVICES; i++)
|
|
|
|
{
|
|
|
|
if(Mount(i))
|
|
|
|
result = true;
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return result;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceHandler::UnMountAll()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
for(u32 i = SD; i < MAXDEVICES; i++)
|
|
|
|
UnMount(i);
|
|
|
|
|
|
|
|
if(sd)
|
|
|
|
delete sd;
|
|
|
|
if(usb0)
|
|
|
|
delete usb0;
|
|
|
|
if(usb1)
|
|
|
|
delete usb1;
|
|
|
|
|
|
|
|
sd = NULL;
|
|
|
|
usb0 = NULL;
|
|
|
|
usb1 = NULL;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::Mount(int dev)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(dev == SD)
|
2012-01-21 21:57:41 +01:00
|
|
|
return MountSD();
|
2012-07-18 16:09:28 +02:00
|
|
|
|
2012-01-21 21:57:41 +01:00
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
|
|
|
return MountUSB(dev-USB1);
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return false;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::IsInserted(int dev)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(dev == SD)
|
2012-01-21 21:57:41 +01:00
|
|
|
return SD_Inserted() && sd->IsMounted(0);
|
2012-07-18 16:09:28 +02:00
|
|
|
|
2012-01-21 21:57:41 +01:00
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
2012-07-18 16:09:28 +02:00
|
|
|
{
|
|
|
|
int portPart = PartitionToPortPartition(dev-USB1);
|
|
|
|
PartitionHandle *usb = instance->GetUSBHandleFromPartition(dev-USB1);
|
|
|
|
if(usb)
|
|
|
|
return usb->IsMounted(portPart);
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return false;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceHandler::UnMount(int dev)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(dev == SD)
|
2012-01-21 21:57:41 +01:00
|
|
|
UnMountSD();
|
2012-07-18 16:09:28 +02:00
|
|
|
|
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
2012-01-21 21:57:41 +01:00
|
|
|
UnMountUSB(dev-USB1);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountSD()
|
|
|
|
{
|
|
|
|
if(!sd)
|
|
|
|
{
|
2012-07-16 16:05:57 +02:00
|
|
|
if(neek2o())
|
2012-07-14 20:32:52 +02:00
|
|
|
sd = new PartitionHandle(&__io_wiisd);
|
|
|
|
else
|
|
|
|
sd = new PartitionHandle(&__io_sdhc);
|
2012-01-21 21:57:41 +01:00
|
|
|
if(sd->GetPartitionCount() < 1)
|
|
|
|
{
|
|
|
|
delete sd;
|
|
|
|
sd = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
//! Mount only one SD Partition
|
|
|
|
return sd->Mount(0, DeviceName[SD], true);
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
|
2012-01-21 21:57:41 +01:00
|
|
|
bool DeviceHandler::MountUSB(int pos)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(!usb0 && !usb1)
|
|
|
|
return false;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(pos >= GetUSBPartitionCount())
|
|
|
|
return false;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
int portPart = PartitionToPortPartition(pos);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(PartitionToUSBPort(pos) == 0 && usb0)
|
|
|
|
return usb0->Mount(portPart, DeviceName[USB1+pos]);
|
|
|
|
else if(usb1)
|
|
|
|
return usb1->Mount(portPart, DeviceName[USB1+pos]);
|
|
|
|
|
|
|
|
return false;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountAllUSB()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(!usb0)
|
|
|
|
usb0 = new PartitionHandle(GetUSB0Interface());
|
|
|
|
//if(!usb1 && (Settings.USBPort == 1 || Settings.USBPort == 2))
|
|
|
|
//usb1 = new PartitionHandle(GetUSB1Interface());
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(usb0 && usb0->GetPartitionCount() < 1)
|
|
|
|
{
|
|
|
|
delete usb0;
|
|
|
|
usb0 = NULL;
|
|
|
|
}
|
|
|
|
if(usb1 && usb1->GetPartitionCount() < 1)
|
|
|
|
{
|
|
|
|
delete usb1;
|
|
|
|
usb1 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
int partCount = GetUSBPartitionCount();
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(int i = 0; i < partCount; i++)
|
|
|
|
{
|
|
|
|
if(MountUSB(i))
|
|
|
|
result = true;
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return result;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
bool DeviceHandler::MountUSBPort1()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(!usb1)// && (Settings.USBPort == 1 || Settings.USBPort == 2))
|
|
|
|
usb1 = new PartitionHandle(GetUSB1Interface());
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(usb1 && usb1->GetPartitionCount() < 1)
|
|
|
|
{
|
|
|
|
delete usb1;
|
|
|
|
usb1 = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
bool result = false;
|
|
|
|
int partCount = GetUSBPartitionCount();
|
|
|
|
int partCount0 = 0;
|
|
|
|
if(usb0)
|
|
|
|
partCount0 = usb0->GetPartitionCount();
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(int i = partCount0; i < partCount; i++)
|
|
|
|
{
|
|
|
|
if(MountUSB(i))
|
|
|
|
result = true;
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return result;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceHandler::UnMountUSB(int pos)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(pos >= GetUSBPartitionCount())
|
|
|
|
return;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
int portPart = PartitionToPortPartition(pos);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(PartitionToUSBPort(pos) == 0 && usb0)
|
|
|
|
return usb0->UnMount(portPart);
|
|
|
|
else if(usb1)
|
|
|
|
return usb1->UnMount(portPart);
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceHandler::UnMountAllUSB()
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
int partCount = GetUSBPartitionCount();
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(int i = 0; i < partCount; i++)
|
|
|
|
UnMountUSB(i);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
delete usb0;
|
|
|
|
usb0 = NULL;
|
|
|
|
delete usb1;
|
|
|
|
usb1 = NULL;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int DeviceHandler::PathToDriveType(const char * path)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(!path)
|
|
|
|
return -1;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(int i = SD; i < MAXDEVICES; i++)
|
|
|
|
{
|
|
|
|
if(strncasecmp(path, DeviceName[i], strlen(DeviceName[i])) == 0)
|
|
|
|
return i;
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return -1;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const char * DeviceHandler::GetFSName(int dev)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
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();
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
return "";
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int DeviceHandler::GetFSType(int dev)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(!instance)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
const char *FSName = GetFSName(dev);
|
|
|
|
if(!FSName) return -1;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
if(strncmp(FSName, "WBFS", 4) == 0)
|
2012-01-21 21:57:41 +01:00
|
|
|
return PART_FS_WBFS;
|
2012-07-18 16:09:28 +02:00
|
|
|
else if(strncmp(FSName, "FAT", 3) == 0)
|
2012-01-21 21:57:41 +01:00
|
|
|
return PART_FS_FAT;
|
2012-07-18 16:09:28 +02:00
|
|
|
else if(strncmp(FSName, "NTFS", 4) == 0)
|
2012-01-21 21:57:41 +01:00
|
|
|
return PART_FS_NTFS;
|
2012-07-18 16:09:28 +02:00
|
|
|
else if(strncmp(FSName, "LINUX", 4) == 0)
|
2012-01-21 21:57:41 +01:00
|
|
|
return PART_FS_EXT;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
|
|
|
|
u16 DeviceHandler::GetUSBPartitionCount()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
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;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wbfs_t * DeviceHandler::GetWbfsHandle(int dev)
|
|
|
|
{
|
|
|
|
if(dev == SD && DeviceHandler::instance->sd)
|
|
|
|
return DeviceHandler::instance->sd->GetWbfsHandle(0);
|
2012-07-18 16:09:28 +02:00
|
|
|
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);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 DeviceHandler::Open_WBFS(int dev)
|
|
|
|
{
|
2012-07-16 16:05:57 +02:00
|
|
|
u32 part_lba, part_idx = 1;
|
2012-01-21 21:57:41 +01:00
|
|
|
u32 part_fs = GetFSType(dev);
|
|
|
|
char *partition = (char *)DeviceName[dev];
|
|
|
|
|
|
|
|
if(dev == SD && IsInserted(dev))
|
|
|
|
part_lba = Instance()->sd->GetLBAStart(dev);
|
|
|
|
else if(dev >= USB1 && dev <= USB8 && IsInserted(dev))
|
2012-07-16 16:05:57 +02:00
|
|
|
{
|
|
|
|
part_idx = dev;
|
2012-07-18 16:09:28 +02:00
|
|
|
part_lba = Instance()->usb0->GetLBAStart(dev - USB1);
|
2012-07-16 16:05:57 +02:00
|
|
|
}
|
2012-07-18 16:09:28 +02:00
|
|
|
else
|
|
|
|
return -1;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-07-16 16:05:57 +02:00
|
|
|
return WBFS_Init(GetWbfsHandle(dev), part_fs, part_idx, part_lba, partition, dev);
|
2012-07-18 16:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|