Fixed Pokepark 2! Maybe... :D Don't trust save states, although I think they are correct. File fd's were too large. Let me know if file related loading stops working in some games. fds are many to 1, not 1 to 1. ES has two instances available at a time. Sadly a clean up requires changing IWII_IPC_HLE_Device Constructor, as a deviceID doesn't make much sense per device. I won't do this until we have less branches :|

This commit is contained in:
Matthew Parlane 2012-03-18 21:00:23 +13:00
parent 0ed8af2287
commit 6fe495e1aa
5 changed files with 268 additions and 172 deletions

View File

@ -68,8 +68,13 @@ TDeviceMap g_DeviceMap;
// STATE_TO_SAVE // STATE_TO_SAVE
typedef std::map<u32, std::string> TFileNameMap; typedef std::map<u32, std::string> TFileNameMap;
TFileNameMap g_FileNameMap;
u32 g_LastDeviceID; #define IPC_MAX_FDS 0x18
#define ES_MAX_COUNT 2
IWII_IPC_HLE_Device* g_FdMap[IPC_MAX_FDS];
bool es_inuse[ES_MAX_COUNT];
IWII_IPC_HLE_Device* es_handles[ES_MAX_COUNT];
typedef std::deque<u32> ipc_msg_queue; typedef std::deque<u32> ipc_msg_queue;
static ipc_msg_queue request_queue; // ppc -> arm static ipc_msg_queue request_queue; // ppc -> arm
@ -78,14 +83,27 @@ static ipc_msg_queue reply_queue; // arm -> ppc
void Init() void Init()
{ {
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init"); _dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
u32 i;
for(i=0; i<IPC_MAX_FDS; i++){
g_FdMap[i] = NULL;
}
u32 i = IPC_FIRST_HARDWARE_ID; i = 0;
// Build hardware devices // Build hardware devices
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_oh1_57e_305(i, std::string("/dev/usb/oh1/57e/305")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_oh1_57e_305(i, std::string("/dev/usb/oh1/57e/305")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_immediate(i, std::string("/dev/stm/immediate")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_immediate(i, std::string("/dev/stm/immediate")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_eventhook(i, std::string("/dev/stm/eventhook")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_eventhook(i, std::string("/dev/stm/eventhook")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_fs(i, std::string("/dev/fs")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_fs(i, std::string("/dev/fs")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_es(i, std::string("/dev/es")); i++;
// IOS allows two ES devices at a time<
u32 j;
for (j=0; j<ES_MAX_COUNT; j++)
{
g_DeviceMap[i] = es_handles[j] = new CWII_IPC_HLE_Device_es(i, std::string("/dev/es")); i++;
es_inuse[j] = false;
}
g_DeviceMap[i] = new CWII_IPC_HLE_Device_di(i, std::string("/dev/di")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_di(i, std::string("/dev/di")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_request(i, std::string("/dev/net/kd/request")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_request(i, std::string("/dev/net/kd/request")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_time(i, std::string("/dev/net/kd/time")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_time(i, std::string("/dev/net/kd/time")); i++;
@ -96,13 +114,23 @@ void Init()
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
} }
void Reset(bool _bHard) void Reset(bool _bHard)
{ {
u32 i;
for (i=0; i<IPC_MAX_FDS; i++){
if (g_FdMap[i] != NULL && !g_FdMap[i]->IsHardware())
{
// close all files and delete their resources
g_FdMap[i]->Close(0, true);
delete g_FdMap[i];
}
g_FdMap[i] = NULL;
}
TDeviceMap::iterator itr = g_DeviceMap.begin(); TDeviceMap::iterator itr = g_DeviceMap.begin();
while (itr != g_DeviceMap.end()) while (itr != g_DeviceMap.end())
{ {
@ -111,21 +139,17 @@ void Reset(bool _bHard)
// Force close // Force close
itr->second->Close(0, true); itr->second->Close(0, true);
// Hardware should not be deleted unless it is a hard reset // Hardware should not be deleted unless it is a hard reset
if (_bHard || !itr->second->IsHardware()) if (_bHard)
delete itr->second; delete itr->second;
} }
++itr; ++itr;
} }
// Skip hardware devices if not a hard reset if (_bHard)
itr = (_bHard) ? g_DeviceMap.begin() : g_DeviceMap.lower_bound(IPC_FIRST_FILEIO_ID); {
// Erase devices g_DeviceMap.erase(g_DeviceMap.begin(), g_DeviceMap.end());
g_DeviceMap.erase(itr, g_DeviceMap.end()); }
g_FileNameMap.clear();
request_queue.clear(); request_queue.clear();
reply_queue.clear(); reply_queue.clear();
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
} }
void Shutdown() void Shutdown()
@ -135,41 +159,52 @@ void Shutdown()
void SetDefaultContentFile(const std::string& _rFilename) void SetDefaultContentFile(const std::string& _rFilename)
{ {
CWII_IPC_HLE_Device_es* pDevice = TDeviceMap::const_iterator itr = g_DeviceMap.begin();
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es"))); while(itr != g_DeviceMap.end())
if (pDevice) {
pDevice->LoadWAD(_rFilename); if (itr->second && itr->second->GetDeviceName().find(std::string("/dev/es")) == 0)
{
((CWII_IPC_HLE_Device_es*)itr->second)->LoadWAD(_rFilename);
}
++itr;
}
} }
void ES_DIVerify(u8 *_pTMD, u32 _sz) void ES_DIVerify(u8 *_pTMD, u32 _sz)
{ {
CWII_IPC_HLE_Device_es* pDevice = CWII_IPC_HLE_Device_es::ES_DIVerify(_pTMD, _sz);
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
if (pDevice)
pDevice->ES_DIVerify(_pTMD, _sz);
else
ERROR_LOG(WII_IPC_ES, "DIVerify called but /dev/es is not available");
} }
void SDIO_EventNotify() void SDIO_EventNotify()
{ {
CWII_IPC_HLE_Device_sdio_slot0 *pDevice = CWII_IPC_HLE_Device_sdio_slot0 *pDevice =
(CWII_IPC_HLE_Device_sdio_slot0*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/sdio/slot0"))); (CWII_IPC_HLE_Device_sdio_slot0*)GetDeviceByName(std::string("/dev/sdio/slot0"));
if (pDevice) if (pDevice)
pDevice->EventNotify(); pDevice->EventNotify();
} }
int getFreeDeviceId()
{
u32 i;
for(i=0; i<IPC_MAX_FDS; i++){
if (g_FdMap[i] == NULL)
{
return i;
}
}
return -1;
}
int GetDeviceIDByName(const std::string& _rDeviceName) IWII_IPC_HLE_Device* GetDeviceByName(const std::string& _rDeviceName)
{ {
TDeviceMap::const_iterator itr = g_DeviceMap.begin(); TDeviceMap::const_iterator itr = g_DeviceMap.begin();
while(itr != g_DeviceMap.end()) while (itr != g_DeviceMap.end())
{ {
if (itr->second->GetDeviceName() == _rDeviceName) if (itr->second && itr->second->GetDeviceName() == _rDeviceName)
return itr->first; return itr->second;
++itr; ++itr;
} }
return -1; return NULL;
} }
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID) IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
@ -177,17 +212,7 @@ IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
if (g_DeviceMap.find(_ID) != g_DeviceMap.end()) if (g_DeviceMap.find(_ID) != g_DeviceMap.end())
return g_DeviceMap[_ID]; return g_DeviceMap[_ID];
return NULL; return NULL;
}
void DeleteDeviceByID(u32 ID)
{
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(ID);
if (pDevice)
delete pDevice;
g_DeviceMap.erase(ID);
g_FileNameMap.erase(ID);
} }
// This is called from ExecuteCommand() COMMAND_OPEN_DEVICE // This is called from ExecuteCommand() COMMAND_OPEN_DEVICE
@ -205,60 +230,82 @@ IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName
void DoState(PointerWrap &p) void DoState(PointerWrap &p)
{ {
p.Do(g_LastDeviceID); p.Do(request_queue);
p.Do(reply_queue);
if (p.GetMode() == PointerWrap::MODE_READ) TDeviceMap::const_iterator itr;
{
TFileNameMap::const_iterator itr; itr = g_DeviceMap.begin();
// Delete file Handles while (itr != g_DeviceMap.end())
itr = g_FileNameMap.begin(); {
while (itr != g_FileNameMap.end()) if (itr->second->IsHardware())
{
TDeviceMap::const_iterator devitr = g_DeviceMap.find(itr->first);
if (devitr != g_DeviceMap.end())
{ {
if (devitr->second) itr->second->DoState(p);
delete devitr->second;
g_DeviceMap.erase(itr->first);
} }
++itr; ++itr;
}
if (p.GetMode() == PointerWrap::MODE_READ)
{
u32 i;
for (i=0; i<IPC_MAX_FDS; i++){
u32 exists;
p.Do(exists);
if (exists){
u32 isHw;
p.Do(isHw);
if (isHw)
{
u32 hwId;
p.Do(hwId);
g_FdMap[i] = AccessDeviceByID(hwId);
}
else
{
g_FdMap[i] = new CWII_IPC_HLE_Device_FileIO(i, "");
g_FdMap[i]->DoState(p);
}
}
else
{
g_FdMap[i] = NULL;
}
} }
// Load file names for (i=0; i<ES_MAX_COUNT; i++)
p.Do(g_FileNameMap);
// Rebuild file handles
itr = g_FileNameMap.begin();
while (itr != g_FileNameMap.end())
{ {
g_DeviceMap[itr->first] = new CWII_IPC_HLE_Device_FileIO(itr->first, itr->second); p.Do(es_inuse[i]);
++itr; u32 handleID = es_handles[i]->GetDeviceID();
p.Do(handleID);
es_handles[i] = AccessDeviceByID(handleID);
} }
} }
else else
{ {
p.Do(g_FileNameMap); u32 i;
} for (i=0; i<IPC_MAX_FDS; i++){
u32 exists = g_FdMap[i] ? 1 : 0;
p.Do(request_queue); p.Do(exists);
p.Do(reply_queue); if (exists){
u32 isHw = g_FdMap[i]->IsHardware() ? 1 : 0;
p.Do(isHw);
TDeviceMap::const_iterator itr; if (isHw)
//first, all the real devices {
//(because we need fs to be deserialized first) u32 hwId = g_FdMap[i]->GetDeviceID();
itr = g_DeviceMap.begin(); p.Do(hwId);
while (itr != g_DeviceMap.end()) }
{ else
if (itr->second->IsHardware()) {
itr->second->DoState(p); g_FdMap[i]->DoState(p);
++itr; }
} }
//then all the files }
itr = g_DeviceMap.begin(); for (i=0; i<ES_MAX_COUNT; i++)
while (itr != g_DeviceMap.end()) {
{ p.Do(es_inuse[i]);
if (!itr->second->IsHardware()) u32 handleID = es_handles[i]->GetDeviceID();
itr->second->DoState(p); p.Do(handleID);
++itr; }
} }
} }
@ -267,67 +314,106 @@ void ExecuteCommand(u32 _Address)
bool CmdSuccess = false; bool CmdSuccess = false;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address)); ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
int DeviceID = Memory::Read_U32(_Address + 8); volatile int DeviceID = Memory::Read_U32(_Address + 8);
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) ", _Address, Command, DeviceID); IWII_IPC_HLE_Device* pDevice = (DeviceID >= 0 && DeviceID < IPC_MAX_FDS) ? g_FdMap[DeviceID] : NULL;
INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) %p", _Address, Command, DeviceID, pDevice);
switch (Command) switch (Command)
{ {
case COMMAND_OPEN_DEVICE: case COMMAND_OPEN_DEVICE:
{ {
// Create a new HLE device. The Mode and DeviceName is given to us but we u32 Mode = Memory::Read_U32(_Address + 0x10);
// generate a DeviceID to be used for access to this device until it is Closed. DeviceID = getFreeDeviceId();
std::string DeviceName;
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC)); std::string DeviceName;
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
u32 Mode = Memory::Read_U32(_Address + 0x10);
DeviceID = GetDeviceIDByName(DeviceName); WARN_LOG(WII_IPC_HLE, "Tried to open %s as %d", DeviceName.c_str(), DeviceID);
if (DeviceID >= 0)
// check if a device with this name has been created already {
if (DeviceName.find("/dev/") == std::string::npos || DeviceID == -1) if (DeviceName.find("/dev/es") == 0)
{ {
if (DeviceName.find("/dev/") == 0) u32 j;
for (j=0; j<ES_MAX_COUNT; j++)
{ {
WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str()); if (!es_inuse[j])
{
es_inuse[j] = true;
g_FdMap[DeviceID] = es_handles[j];
CmdSuccess = es_handles[j]->Open(_Address, Mode);
Memory::Write_U32(DeviceID, _Address+4);
break;
}
}
if(j == ES_MAX_COUNT)
{
Memory::Write_U32(FS_EESEXHAUSTED, _Address + 4);
CmdSuccess = true;
}
pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("_Unimplemented_Device_"))); }
else if (DeviceName.find("/dev/") == 0)
{
pDevice = GetDeviceByName(DeviceName);
if (pDevice)
{
g_FdMap[DeviceID] = pDevice;
CmdSuccess = pDevice->Open(_Address, Mode); CmdSuccess = pDevice->Open(_Address, Mode);
INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), DeviceID, Mode);
Memory::Write_U32(DeviceID, _Address+4);
} }
else else
{ {
// create new file handle WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str());
u32 CurrentDeviceID = g_LastDeviceID; pDevice = GetDeviceByName(std::string("_Unimplemented_Device_"));
pDevice = CreateFileIO(CurrentDeviceID, DeviceName);
g_DeviceMap[CurrentDeviceID] = pDevice;
g_FileNameMap[CurrentDeviceID] = DeviceName;
g_LastDeviceID++;
CmdSuccess = pDevice->Open(_Address, Mode); CmdSuccess = pDevice->Open(_Address, Mode);
g_FdMap[DeviceID] = pDevice;
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)", Memory::Write_U32(DeviceID, _Address+4);
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
} }
} }
else else
{ {
// F|RES: prolly the re-open is just a mode change IWII_IPC_HLE_Device* pDevice = CreateFileIO(DeviceID, DeviceName);
pDevice = AccessDeviceByID(DeviceID);
CmdSuccess = pDevice->Open(_Address, Mode); CmdSuccess = pDevice->Open(_Address, Mode);
INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)", INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), DeviceID, Mode); pDevice->GetDeviceName().c_str(), DeviceID, Mode);
} if(Memory::Read_U32(_Address + 4) == DeviceID)
} g_FdMap[DeviceID] = pDevice;
break; }
}
else
{
Memory::Write_U32(FS_EFDEXHAUSTED, _Address + 4);
CmdSuccess = true;
}
break;
}
case COMMAND_CLOSE_DEVICE: case COMMAND_CLOSE_DEVICE:
if (pDevice) {
if (pDevice)
{ {
CmdSuccess = pDevice->Close(_Address); CmdSuccess = pDevice->Close(_Address);
u32 j;
for (j=0; j<ES_MAX_COUNT; j++)
{
if (es_handles[j] == g_FdMap[DeviceID])
{
es_inuse[j] = false;
}
}
g_FdMap[DeviceID] = NULL;
// Don't delete hardware // Don't delete hardware
if (!pDevice->IsHardware()) if (!pDevice->IsHardware())
DeleteDeviceByID(DeviceID); delete pDevice;
} }
else else
{ {
@ -335,50 +421,67 @@ void ExecuteCommand(u32 _Address)
CmdSuccess = true; CmdSuccess = true;
} }
break; break;
}
case COMMAND_READ: case COMMAND_READ:
{
if (pDevice) if (pDevice)
{
CmdSuccess = pDevice->Read(_Address); CmdSuccess = pDevice->Read(_Address);
}
else else
{ {
Memory::Write_U32(FS_EINVAL, _Address + 4); Memory::Write_U32(FS_EINVAL, _Address + 4);
CmdSuccess = true; CmdSuccess = true;
} }
break; break;
}
case COMMAND_WRITE: case COMMAND_WRITE:
{
if (pDevice) if (pDevice)
{
CmdSuccess = pDevice->Write(_Address); CmdSuccess = pDevice->Write(_Address);
}
else else
{ {
Memory::Write_U32(FS_EINVAL, _Address + 4); Memory::Write_U32(FS_EINVAL, _Address + 4);
CmdSuccess = true; CmdSuccess = true;
} }
break; break;
}
case COMMAND_SEEK: case COMMAND_SEEK:
{
if (pDevice) if (pDevice)
{
CmdSuccess = pDevice->Seek(_Address); CmdSuccess = pDevice->Seek(_Address);
}
else else
{ {
Memory::Write_U32(FS_EINVAL, _Address + 4); Memory::Write_U32(FS_EINVAL, _Address + 4);
CmdSuccess = true; CmdSuccess = true;
} }
break; break;
}
case COMMAND_IOCTL: case COMMAND_IOCTL:
{
if (pDevice) if (pDevice)
{
CmdSuccess = pDevice->IOCtl(_Address); CmdSuccess = pDevice->IOCtl(_Address);
}
break; break;
}
case COMMAND_IOCTLV: case COMMAND_IOCTLV:
{
if (pDevice) if (pDevice)
{
CmdSuccess = pDevice->IOCtlV(_Address); CmdSuccess = pDevice->IOCtlV(_Address);
}
break; break;
}
default: default:
{
_dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address); _dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address);
break; break;
}
} }
// It seems that the original hardware overwrites the command after it has been // It seems that the original hardware overwrites the command after it has been
@ -450,8 +553,7 @@ void Update()
void UpdateDevices() void UpdateDevices()
{ {
// Check if a hardware device must be updated // Check if a hardware device must be updated
TDeviceMap::const_iterator itrEnd = g_DeviceMap.lower_bound(IPC_FIRST_FILEIO_ID); for (TDeviceMap::const_iterator itr = g_DeviceMap.begin(); itr != g_DeviceMap.end(); ++itr) {
for (TDeviceMap::const_iterator itr = g_DeviceMap.begin(); itr != itrEnd; ++itr) {
if (itr->second->IsOpened() && itr->second->Update()) { if (itr->second->IsOpened() && itr->second->Update()) {
break; break;
} }

View File

@ -25,9 +25,9 @@ class IWII_IPC_HLE_Device;
namespace WII_IPC_HLE_Interface namespace WII_IPC_HLE_Interface
{ {
#define IPC_FIRST_HARDWARE_ID 0 // first IPC device ID #define IPC_FIRST_ID 0x00 // first IPC device ID
#define IPC_FIRST_FILEIO_ID 33 // first IPC file ID #define IPC_MAX_FILES 0x10 // first IPC file ID
// Init // Init
void Init(); void Init();
@ -46,14 +46,13 @@ void ES_DIVerify(u8 *_pTMD, u32 _sz);
void SDIO_EventNotify(); void SDIO_EventNotify();
int GetDeviceIDByName(const std::string& _rDeviceName);
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
void DeleteDeviceByID(u32 _ID);
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName); IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName);
IWII_IPC_HLE_Device* GetDeviceByName(const std::string& _rDeviceName);
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
int getFreeDeviceId();
// Update // Update
void Update(); void Update();

View File

@ -39,7 +39,7 @@ class PointerWrap;
#define FS_ENOENT2 (u32)-106 // File not found #define FS_ENOENT2 (u32)-106 // File not found
#define FS_ENFILE (u32)-107 // Too many fds open #define FS_ENFILE (u32)-107 // Too many fds open
#define FS_EFBIG (u32)-108 // max block count reached? #define FS_EFBIG (u32)-108 // max block count reached?
#define FS_ENFILE2 (u32)-109 // Too many fds open #define FS_EFDEXHAUSTED (u32)-109 // Too many fds open
#define FS_ENAMELEN (u32)-110 // pathname is too long #define FS_ENAMELEN (u32)-110 // pathname is too long
#define FS_EFDOPEN (u32)-111 // FD is already open #define FS_EFDOPEN (u32)-111 // FD is already open
#define FS_EIO2 (u32)-114 // returned on ECC error #define FS_EIO2 (u32)-114 // returned on ECC error
@ -47,6 +47,7 @@ class PointerWrap;
#define FS_EDIRDEPTH (u32)-116 // max directory depth exceeded #define FS_EDIRDEPTH (u32)-116 // max directory depth exceeded
#define FS_EBUSY2 (u32)-118 // Resource busy #define FS_EBUSY2 (u32)-118 // Resource busy
//#define FS_EFATAL (u32)-119 // fatal error not used by IOS as fatal ERROR //#define FS_EFATAL (u32)-119 // fatal error not used by IOS as fatal ERROR
#define FS_EESEXHAUSTED (u32)-1016 // Max of 2 ES handles at a time
class IWII_IPC_HLE_Device class IWII_IPC_HLE_Device
{ {

View File

@ -28,7 +28,7 @@
static Common::replace_v replacements; static Common::replace_v replacements;
// This is used by several of the FileIO and /dev/fs/ functions // This is used by several of the FileIO and /dev/fs functions
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size) std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
{ {
std::string path_full = File::GetUserPath(D_WIIROOT_IDX); std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
@ -128,7 +128,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
// The file must exist before we can open it // The file must exist before we can open it
// It should be created by ISFS_CreateFile, not here // It should be created by ISFS_CreateFile, not here
if(File::Exists(m_Filename)) if (File::Exists(m_Filename))
{ {
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode); INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
ReturnValue = m_DeviceID; ReturnValue = m_DeviceID;
@ -149,21 +149,22 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_FileIO::OpenFile() bool CWII_IPC_HLE_Device_FileIO::OpenFile()
{ {
switch(m_Mode) switch (m_Mode)
{ {
case ISFS_OPEN_READ: case ISFS_OPEN_READ:
{
m_pFileHandle.Open(m_Filename, "rb"); m_pFileHandle.Open(m_Filename, "rb");
break; break;
}
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
case ISFS_OPEN_WRITE: case ISFS_OPEN_WRITE:
m_pFileHandle.Open(m_Filename, "r+b"); m_pFileHandle.Open(m_Filename, "r+b");
break; break;
case ISFS_OPEN_RW: case ISFS_OPEN_RW:
{
m_pFileHandle.Open(m_Filename, "r+b"); m_pFileHandle.Open(m_Filename, "r+b");
break; break;
}
default: default:
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
break; break;
@ -178,21 +179,21 @@ void CWII_IPC_HLE_Device_FileIO::CloseFile()
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
{ {
u32 ReturnValue = FS_RESULT_FATAL; u32 ReturnValue = FS_RESULT_FATAL;
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10); const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
if(OpenFile()) if (OpenFile())
{ {
ReturnValue = FS_RESULT_FATAL; ReturnValue = FS_RESULT_FATAL;
const u64 fileSize = m_pFileHandle.GetSize(); const u64 fileSize = m_pFileHandle.GetSize();
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize); INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
switch(Mode){ switch (Mode){
case 0: case 0:
{ {
if(SeekPosition >=0 && SeekPosition <= fileSize) if (SeekPosition >=0 && SeekPosition <= fileSize)
{ {
m_SeekPos = SeekPosition; m_SeekPos = SeekPosition;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;
@ -202,7 +203,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
case 1: case 1:
{ {
s32 wantedPos = SeekPosition+m_SeekPos; s32 wantedPos = SeekPosition+m_SeekPos;
if(wantedPos >=0 && wantedPos <= fileSize) if (wantedPos >=0 && wantedPos <= fileSize)
{ {
m_SeekPos = wantedPos; m_SeekPos = wantedPos;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;
@ -212,7 +213,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
case 2: case 2:
{ {
s32 wantedPos = fileSize+m_SeekPos; s32 wantedPos = fileSize+m_SeekPos;
if(wantedPos >=0 && wantedPos <= fileSize) if (wantedPos >=0 && wantedPos <= fileSize)
{ {
m_SeekPos = wantedPos; m_SeekPos = wantedPos;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;
@ -244,7 +245,7 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if(OpenFile()) if (OpenFile())
{ {
if (m_Mode == ISFS_OPEN_WRITE) if (m_Mode == ISFS_OPEN_WRITE)
{ {
@ -284,7 +285,7 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if(OpenFile()) if (OpenFile())
{ {
if (m_Mode == ISFS_OPEN_READ) if (m_Mode == ISFS_OPEN_READ)
{ {
@ -318,21 +319,14 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
DumpCommands(_CommandAddress); DumpCommands(_CommandAddress);
#endif #endif
const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
u32 ReturnValue = 0;
//u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); switch (Parameter)
//u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
// Return Value
u32 ReturnValue = 0; // no error
switch(Parameter)
{ {
case ISFS_IOCTL_GETFILESTATS: case ISFS_IOCTL_GETFILESTATS:
{ {
if(OpenFile()) if (OpenFile())
{ {
u32 m_FileLength = (u32)m_pFileHandle.GetSize(); u32 m_FileLength = (u32)m_pFileHandle.GetSize();

View File

@ -37,7 +37,7 @@ public:
virtual bool Close(u32 _CommandAddress, bool _bForce); virtual bool Close(u32 _CommandAddress, bool _bForce);
virtual bool IOCtlV(u32 _CommandAddress); virtual bool IOCtlV(u32 _CommandAddress);
u32 ES_DIVerify(u8 *_pTMD, u32 _sz); static u32 ES_DIVerify(u8 *_pTMD, u32 _sz);
private: private:
enum enum