usbloadergx/source/Controls/DeviceHandler.cpp
dimok321 72d8c9dc2e *Created an automatic resource list generation script which is executed when files are added/removed
*Created an own class for the homebrew prompt
*Created scrollbar class which is now used on every browser
*Created a checkbox browser list class
*Changed the category prompts to the new list mode
*Improved B-Button scrolling
*Fixed horizontal text scrolling
*Fixed possible crash on long text display
*Many internal gui changes and navigation changes
*Fixed booting games by argument (headless id) (Issue 1930)
*Fixed SD Reload button to really reload the SD after it was ejected (Issue 1923)
*Added booting with arguements from meta.xml for homebrews (Issue 1926)
*Added some arguments acception from meta.xml to our app. "-ios=xxx" and "-usbport=x" or "--ios=xxx" and "--usbport=x" can be used. -usbport is for Hermes cIOS to decide which usb port to use on startup. The ios is the boot IOS on startup, it always overrides the compiled boot IOS into the application.
2011-06-14 17:53:19 +00:00

324 lines
6.6 KiB
C++

/****************************************************************************
* 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
***************************************************************************/
#include <malloc.h>
#include <unistd.h>
#include <string.h>
#include <ogc/mutex.h>
#include <ogc/system.h>
#include <sdcard/wiisd_io.h>
#include <sdcard/gcsd.h>
#include "settings/CSettings.h"
#include "usbloader/usbstorage2.h"
#include "DeviceHandler.hpp"
#include "usbloader/wbfs.h"
#include "system/IosLoader.h"
DeviceHandler * DeviceHandler::instance = NULL;
DeviceHandler::~DeviceHandler()
{
UnMountAll();
}
DeviceHandler * DeviceHandler::Instance()
{
if (instance == NULL)
{
instance = new DeviceHandler();
}
return instance;
}
void DeviceHandler::DestroyInstance()
{
if(instance)
{
delete instance;
}
instance = NULL;
}
bool DeviceHandler::MountAll()
{
bool result = false;
for(u32 i = SD; i < MAXDEVICES; i++)
{
if(Mount(i))
result = true;
}
return result;
}
void DeviceHandler::UnMountAll()
{
for(u32 i = SD; i < MAXDEVICES; i++)
UnMount(i);
if(sd)
delete sd;
if(usb)
delete usb;
sd = NULL;
usb = NULL;
}
bool DeviceHandler::Mount(int dev)
{
if(dev == SD)
return MountSD();
else if(dev >= USB1 && dev <= USB8)
return MountUSB(dev-USB1);
return false;
}
bool DeviceHandler::IsInserted(int dev)
{
if(dev == SD)
return SD_Inserted() && sd->IsMounted(0);
else if(dev >= USB1 && dev <= USB8)
return USB_Inserted() && usb->IsMounted(dev-USB1);
return false;
}
void DeviceHandler::UnMount(int dev)
{
if(dev == SD)
UnMountSD();
else if(dev >= USB1 && dev <= USB8)
UnMountUSB(dev-USB1);
}
bool DeviceHandler::MountSD()
{
if(!sd)
sd = new PartitionHandle(&__io_wiisd);
if(sd->GetPartitionCount() < 1)
{
delete sd;
sd = NULL;
return false;
}
//! Mount only one SD Partition
return sd->Mount(0, DeviceName[SD], true);
}
const DISC_INTERFACE * DeviceHandler::GetUSBInterface()
{
if(IOS_GetVersion() < 200)
return &__io_usbstorage;
return &__io_usbstorage2;
}
static inline bool USBSpinUp()
{
bool started = false;
int retries = 400;
const DISC_INTERFACE * handle = DeviceHandler::GetUSBInterface();
// wait 20 sec for the USB to spin up...stupid slow ass HDD
do
{
started = (handle->startup() && handle->isInserted());
if(started) break;
usleep(50000);
}
while(--retries > 0);
return started;
}
bool DeviceHandler::SetUSBPort(int port, bool spinup)
{
int ret = USBStorage2_SetPort(port);
if(spinup)
USBSpinUp();
return ret >= 0;
}
void DeviceHandler::SetUSBPortFromPartition(int part)
{
if(Settings.USBPort != 2)
return;
PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandle();
if(!usbHandle)
return;
if(part < usbHandle->GetPartitionCount())
SetUSBPort(0);
else
SetUSBPort(1);
}
bool DeviceHandler::MountUSB(int pos, bool spinup)
{
if(spinup && !USBSpinUp())
return false;
if(!usb)
{
if(Settings.USBPort == 2) SetUSBPort(0);
usb = new PartitionHandle(GetUSBInterface());
if(Settings.USBPort == 2 && IosLoader::IsHermesIOS())
{
SetUSBPort(1);
usb->GetPort1Partitions();
}
}
if(usb->GetPartitionTotalCount() < 1)
{
delete usb;
usb = NULL;
return false;
}
if(pos >= usb->GetPartitionTotalCount())
return false;
SetUSBPortFromPartition(pos);
return usb->Mount(pos, DeviceName[USB1+pos]);
}
bool DeviceHandler::MountAllUSB(bool spinup)
{
if(spinup && !USBSpinUp())
return false;
if(!usb)
{
if(Settings.USBPort == 2) SetUSBPort(0);
usb = new PartitionHandle(GetUSBInterface());
if(Settings.USBPort == 2 && IosLoader::IsHermesIOS())
{
SetUSBPort(1);
usb->GetPort1Partitions();
}
}
bool result = false;
for(int i = 0; i < usb->GetPartitionTotalCount(); i++)
{
if(MountUSB(i, false))
result = true;
}
if(Settings.USBPort == 2)
SetUSBPort(0);
return result;
}
void DeviceHandler::UnMountUSB(int pos)
{
if(!usb)
return;
if(pos >= usb->GetPartitionTotalCount())
return;
SetUSBPortFromPartition(pos);
usb->UnMount(pos);
}
void DeviceHandler::UnMountAllUSB()
{
if(!usb)
return;
for(int i = 0; i < usb->GetPartitionTotalCount(); i++)
UnMountUSB(i);
delete usb;
usb = NULL;
}
int DeviceHandler::PathToDriveType(const char * path)
{
if(!path)
return -1;
for(int i = SD; i < MAXDEVICES; i++)
{
if(strncmp(path, DeviceName[i], strlen(DeviceName[i])) == 0)
return i;
}
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);
}
return NULL;
}
int DeviceHandler::GetUSBFilesystemType(int partition)
{
if(!instance)
return -1;
PartitionHandle * usbHandle = instance->GetUSBHandle();
const char * FSName = usbHandle->GetFSName(partition);
if(!FSName) return -1;
if(strncmp(FSName, "WBFS", 4) == 0)
return PART_FS_WBFS;
else if(strncmp(FSName, "FAT", 3) == 0)
return PART_FS_FAT;
else if(strncmp(FSName, "NTFS", 4) == 0)
return PART_FS_NTFS;
else if(strncmp(FSName, "LINUX", 4) == 0)
return PART_FS_EXT;
return -1;
}