2012-01-21 21:57:41 +01:00
|
|
|
/****************************************************************************
|
2012-09-22 15:47:52 +02:00
|
|
|
* Copyright (C) 2010 by Dimok
|
|
|
|
* (C) 2012 by FIX94
|
2012-01-21 21:57:41 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
***************************************************************************/
|
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>
|
|
|
|
#include "DeviceHandler.hpp"
|
2012-09-20 18:09:32 +02:00
|
|
|
#include "fat.h"
|
2012-09-11 19:09:14 +02:00
|
|
|
#include "usbthread.h"
|
2013-01-19 19:32:46 +01:00
|
|
|
#include "sdhc.h"
|
|
|
|
#include "wiisd_libogc.h"
|
2012-08-05 15:48:15 +02:00
|
|
|
#include "usbstorage.h"
|
2012-09-02 15:34:41 +02:00
|
|
|
#include "usbstorage_libogc.h"
|
2012-08-05 15:48:15 +02:00
|
|
|
#include "loader/cios.h"
|
2012-09-20 18:09:32 +02:00
|
|
|
#include "loader/sys.h"
|
2012-08-05 15:48:15 +02:00
|
|
|
#include "loader/wbfs.h"
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-09-22 15:47:52 +02:00
|
|
|
DeviceHandler DeviceHandle;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
2012-09-22 15:47:52 +02:00
|
|
|
void DeviceHandler::Init()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-10-15 21:16:14 +02:00
|
|
|
sd.Init();
|
2013-02-14 22:30:48 +01:00
|
|
|
usb.Init();
|
2012-10-15 21:16:14 +02:00
|
|
|
OGC_Device.Init();
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
2012-08-24 00:29:15 +02:00
|
|
|
void DeviceHandler::MountAll()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-08-24 00:29:15 +02:00
|
|
|
MountSD();
|
2012-10-01 11:51:19 +02:00
|
|
|
if(!Sys_DolphinMode())
|
|
|
|
MountAllUSB();
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:52:32 +02:00
|
|
|
void DeviceHandler::UnMountAll()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-09-11 19:09:14 +02:00
|
|
|
/* Kill possible USB thread */
|
|
|
|
KillUSBKeepAliveThread();
|
|
|
|
|
2012-07-18 16:09:28 +02:00
|
|
|
for(u32 i = SD; i < MAXDEVICES; i++)
|
|
|
|
UnMount(i);
|
2012-09-02 13:51:26 +02:00
|
|
|
USBStorage2_Deinit();
|
2012-09-05 17:52:32 +02:00
|
|
|
USB_Deinitialize();
|
2012-09-02 13:51:26 +02:00
|
|
|
SDHC_Close();
|
2012-10-15 21:16:14 +02:00
|
|
|
|
|
|
|
sd.Cleanup();
|
2013-02-14 22:30:48 +01:00
|
|
|
usb.Cleanup();
|
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-10-15 21:16:14 +02:00
|
|
|
return SD_Inserted() && sd.IsMounted(0);
|
2012-01-21 21:57:41 +01:00
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
2013-02-14 22:30:48 +01:00
|
|
|
return usb.IsMounted(dev-USB1);
|
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);
|
|
|
|
}
|
|
|
|
|
2012-08-24 15:50:17 +02:00
|
|
|
void DeviceHandler::SetModes()
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-10-01 11:51:19 +02:00
|
|
|
sdhc_mode_sd = 1;
|
|
|
|
usb_libogc_mode = 1;
|
|
|
|
if(CustomIOS(CurrentIOS.Type))
|
|
|
|
{ /* For USB you can use every cIOS */
|
2012-09-28 19:24:04 +02:00
|
|
|
usb_libogc_mode = 0;
|
2012-10-01 11:51:19 +02:00
|
|
|
/* But not for SD */
|
|
|
|
if(CurrentIOS.Type != IOS_TYPE_NEEK2O)
|
|
|
|
sdhc_mode_sd = 0;
|
2012-09-28 19:24:04 +02:00
|
|
|
}
|
2012-08-24 15:50:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountSD()
|
|
|
|
{
|
2012-10-15 21:16:14 +02:00
|
|
|
if(!sd.IsInserted() || !sd.IsMounted(0))
|
2012-07-20 22:12:25 +02:00
|
|
|
{
|
2012-09-28 19:24:04 +02:00
|
|
|
if(CurrentIOS.Type == IOS_TYPE_HERMES)
|
|
|
|
{ /* Slowass Hermes SDHC Module */
|
|
|
|
for(int i = 0; i < 50; i++)
|
|
|
|
{
|
|
|
|
if(SDHC_Init())
|
|
|
|
break;
|
|
|
|
usleep(1000);
|
|
|
|
}
|
|
|
|
}
|
2012-10-15 21:16:14 +02:00
|
|
|
sd.SetDevice(&__io_sdhc);
|
|
|
|
//! Mount only one SD Partition
|
|
|
|
return sd.Mount(0, DeviceName[SD], true); /* Force FAT */
|
2012-07-20 22:12:25 +02:00
|
|
|
}
|
2012-10-15 21:16:14 +02:00
|
|
|
return true;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountUSB(int pos)
|
|
|
|
{
|
2012-07-18 16:09:28 +02:00
|
|
|
if(pos >= GetUSBPartitionCount())
|
|
|
|
return false;
|
2013-02-14 22:30:48 +01:00
|
|
|
return usb.Mount(pos, DeviceName[USB1+pos]);
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceHandler::MountAllUSB()
|
|
|
|
{
|
2012-09-11 19:09:14 +02:00
|
|
|
/* Kill possible USB thread */
|
|
|
|
KillUSBKeepAliveThread();
|
2012-09-02 15:34:41 +02:00
|
|
|
/* Wait for our slowass HDD */
|
2013-02-14 22:30:48 +01:00
|
|
|
WaitForDevice(GetUSBInterface());
|
2012-09-02 15:34:41 +02:00
|
|
|
/* Get Partitions and Mount them */
|
2013-02-14 22:30:48 +01:00
|
|
|
if(!usb.IsInserted() || !usb.IsMounted(0))
|
|
|
|
usb.SetDevice(GetUSBInterface());
|
2012-07-18 16:09:28 +02:00
|
|
|
bool result = false;
|
|
|
|
int partCount = GetUSBPartitionCount();
|
|
|
|
for(int i = 0; i < partCount; i++)
|
|
|
|
{
|
|
|
|
if(MountUSB(i))
|
|
|
|
result = true;
|
|
|
|
}
|
2012-09-28 19:24:04 +02:00
|
|
|
if(!result)
|
2013-02-14 22:30:48 +01:00
|
|
|
result = usb.Mount(0, DeviceName[USB1], true); /* Force FAT */
|
2012-09-11 19:09:14 +02:00
|
|
|
if(result && usb_libogc_mode)
|
|
|
|
CreateUSBKeepAliveThread();
|
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;
|
2013-02-14 22:30:48 +01:00
|
|
|
return usb.UnMount(pos);
|
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-09-22 15:47:52 +02:00
|
|
|
int DeviceHandler::PathToDriveType(const char *path)
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
2012-09-22 15:47:52 +02:00
|
|
|
const char *DeviceHandler::GetFSName(int dev)
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
2012-10-15 21:16:14 +02:00
|
|
|
if(dev == SD)
|
|
|
|
return sd.GetFSName(0);
|
2012-07-18 16:09:28 +02:00
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
|
|
|
{
|
2013-02-14 22:30:48 +01:00
|
|
|
if(dev-USB1 < usb.GetPartitionCount())
|
|
|
|
return usb.GetFSName(dev-USB1);
|
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
|
|
|
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
|
|
|
{
|
2013-02-14 22:30:48 +01:00
|
|
|
return usb.GetPartitionCount();
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wbfs_t * DeviceHandler::GetWbfsHandle(int dev)
|
|
|
|
{
|
2012-10-15 21:16:14 +02:00
|
|
|
if(dev == SD)
|
|
|
|
return sd.GetWbfsHandle(0);
|
|
|
|
else if(dev >= USB1 && dev <= USB8)
|
2013-02-14 22:30:48 +01:00
|
|
|
return usb.GetWbfsHandle(dev-USB1);
|
2012-09-22 15:47:52 +02:00
|
|
|
return NULL;
|
2012-01-21 21:57:41 +01:00
|
|
|
}
|
|
|
|
|
2012-09-22 15:47:52 +02:00
|
|
|
s32 DeviceHandler::OpenWBFS(int dev)
|
2012-01-21 21:57:41 +01:00
|
|
|
{
|
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);
|
2012-11-14 17:58:14 +01:00
|
|
|
const char *partition = DeviceName[dev];
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
if(dev == SD && IsInserted(dev))
|
2012-10-15 21:16:14 +02:00
|
|
|
part_lba = sd.GetLBAStart(dev);
|
2012-01-21 21:57:41 +01:00
|
|
|
else if(dev >= USB1 && dev <= USB8 && IsInserted(dev))
|
2012-07-16 16:05:57 +02:00
|
|
|
{
|
|
|
|
part_idx = dev;
|
2013-02-14 22:30:48 +01:00
|
|
|
part_lba = usb.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-11-14 17:58:14 +01:00
|
|
|
return WBFS_Init(GetWbfsHandle(dev), part_fs, part_idx, part_lba, partition);
|
2012-07-18 16:09:28 +02:00
|
|
|
}
|
|
|
|
|
2012-09-02 15:34:41 +02:00
|
|
|
void DeviceHandler::WaitForDevice(const DISC_INTERFACE *Handle)
|
|
|
|
{
|
|
|
|
if(Handle == NULL)
|
|
|
|
return;
|
|
|
|
time_t timeout = time(NULL);
|
|
|
|
while(time(NULL) - timeout < 20)
|
|
|
|
{
|
|
|
|
if(Handle->startup() && Handle->isInserted())
|
|
|
|
break;
|
|
|
|
usleep(50000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-17 18:30:24 +01:00
|
|
|
bool DeviceHandler::MountDevolution()
|
2012-09-02 15:34:41 +02:00
|
|
|
{
|
2012-11-17 18:30:24 +01:00
|
|
|
int NewPartition = (currentPartition == SD ? currentPartition : currentPartition - 1);
|
2013-01-19 19:32:46 +01:00
|
|
|
const DISC_INTERFACE *handle = (currentPartition == SD) ? &__io_wiisd_ogc : &__io_usbstorage_ogc;
|
2012-09-02 15:34:41 +02:00
|
|
|
/* We need to wait for the device to get ready for a remount */
|
|
|
|
WaitForDevice(handle);
|
|
|
|
/* Only mount the partition we need */
|
2012-10-15 21:16:14 +02:00
|
|
|
OGC_Device.SetDevice(handle);
|
2012-11-17 18:30:24 +01:00
|
|
|
return OGC_Device.Mount(NewPartition, DeviceName[currentPartition], true);
|
2012-09-02 15:34:41 +02:00
|
|
|
}
|
|
|
|
|
2012-11-17 18:30:24 +01:00
|
|
|
void DeviceHandler::UnMountDevolution()
|
2012-09-02 15:34:41 +02:00
|
|
|
{
|
2012-11-17 18:30:24 +01:00
|
|
|
int NewPartition = (currentPartition == SD ? currentPartition : currentPartition - 1);
|
2012-10-15 21:16:14 +02:00
|
|
|
OGC_Device.UnMount(NewPartition);
|
|
|
|
OGC_Device.Cleanup();
|
2012-09-02 15:34:41 +02:00
|
|
|
}
|
2012-09-05 17:52:32 +02:00
|
|
|
|
|
|
|
bool DeviceHandler::UsablePartitionMounted()
|
|
|
|
{
|
|
|
|
for(u8 i = SD; i < MAXDEVICES; i++)
|
|
|
|
{
|
|
|
|
if(IsInserted(i) && !GetWbfsHandle(i)) //Everything besides WBFS for configuration
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2012-09-10 00:38:42 +02:00
|
|
|
|
|
|
|
bool DeviceHandler::PartitionUsableForNandEmu(int Partition)
|
|
|
|
{
|
|
|
|
if(IsInserted(Partition) && GetFSType(Partition) == PART_FS_FAT)
|
|
|
|
return true;
|
2012-09-20 18:09:32 +02:00
|
|
|
|
2012-09-10 00:38:42 +02:00
|
|
|
return false;
|
|
|
|
}
|
2013-02-14 22:30:48 +01:00
|
|
|
|
|
|
|
const DISC_INTERFACE *DeviceHandler::GetUSBInterface()
|
|
|
|
{
|
|
|
|
if(((CurrentIOS.Type == IOS_TYPE_HERMES && CurrentIOS.Version > 4) ||
|
|
|
|
(CurrentIOS.Type == IOS_TYPE_D2X && CurrentIOS.Version > 8) ||
|
|
|
|
(CurrentIOS.Type == IOS_TYPE_NORMAL_IOS && CurrentIOS.Revision == 58))
|
|
|
|
&& currentPort == 1)
|
|
|
|
return &__io_usbstorage2_port1;
|
|
|
|
return &__io_usbstorage2_port0;
|
|
|
|
}
|