fs/fileIO: add enum for open mode, and struct for NANDStat.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4682 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-12-11 21:36:26 +00:00
parent cca6f75110
commit 57d2f39cb0
4 changed files with 87 additions and 88 deletions

View File

@ -23,9 +23,7 @@
#include "WII_IPC_HLE_Device_FileIO.h" #include "WII_IPC_HLE_Device_FileIO.h"
// =================================================== // 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)
{ {
char Buffer[128]; char Buffer[128];
@ -33,7 +31,7 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
std::string Filename(FULL_WII_ROOT_DIR); std::string Filename(FULL_WII_ROOT_DIR);
if (Buffer[1] == '0') if (Buffer[1] == '0')
Filename += std::string("/title"); // this looks and feel like an hack... Filename += std::string("/title"); // this looks and feel like a hack...
Filename += Buffer; Filename += Buffer;
@ -44,13 +42,14 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std:
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
, m_pFileHandle(NULL) , m_pFileHandle(NULL)
, m_FileLength(0) , m_FileLength(0)
{} {
}
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO() CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
{} {
}
bool bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
{ {
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_Name.c_str(), m_DeviceID); INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_Name.c_str(), m_DeviceID);
@ -67,8 +66,7 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{ {
u32 ReturnValue = 0; u32 ReturnValue = 0;
@ -95,21 +93,23 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s), File exists", m_Name.c_str(), Modes[_Mode]); INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s), File exists", m_Name.c_str(), Modes[_Mode]);
switch(_Mode) switch(_Mode)
{ {
case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break; case ISFS_OPEN_READ: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
case 0x02: // m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break; case ISFS_OPEN_WRITE: // m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
// MK Wii gets here corrupting its saves, however using rb+ mode works fine // MK Wii gets here corrupting its saves, however using rb+ mode works fine
// TODO : figure it properly... // TODO : figure it properly...
case 0x03: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break; case ISFS_OPEN_RW: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode : 0x%02x", _Mode); break; default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode : 0x%02x", _Mode); break;
} }
} }
else else
{ {
if (_Mode == 0x02) { if (_Mode == ISFS_OPEN_WRITE)
{
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open new %s (%s)", m_Name.c_str(), Modes[_Mode]); INFO_LOG(WII_IPC_FILEIO, "FileIO: Open new %s (%s)", m_Name.c_str(), Modes[_Mode]);
m_pFileHandle = fopen(m_Filename.c_str(), "wb"); m_pFileHandle = fopen(m_Filename.c_str(), "wb");
} }
else { else
{
ERROR_LOG(WII_IPC_FILEIO, " FileIO failed open for reading: %s - File doesn't exist", m_Filename.c_str()); ERROR_LOG(WII_IPC_FILEIO, " FileIO failed open for reading: %s - File doesn't exist", m_Filename.c_str());
ReturnValue = FS_FILE_NOT_EXIST; ReturnValue = FS_FILE_NOT_EXIST;
} }
@ -120,7 +120,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
m_FileLength = File::GetSize(m_Filename.c_str()); m_FileLength = File::GetSize(m_Filename.c_str());
ReturnValue = GetDeviceID(); ReturnValue = GetDeviceID();
} }
else if(ReturnValue == 0) else if (ReturnValue == 0)
{ {
ERROR_LOG(WII_IPC_FILEIO, " FileIO failed open: %s(%s) - I/O Error", m_Filename.c_str(), Modes[_Mode]); ERROR_LOG(WII_IPC_FILEIO, " FileIO failed open: %s(%s) - I/O Error", m_Filename.c_str(), Modes[_Mode]);
ReturnValue = FS_INVALID_ARGUMENT; ReturnValue = FS_INVALID_ARGUMENT;
@ -131,12 +131,11 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
{ {
u32 ReturnValue = 0; u32 ReturnValue = 0;
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
u32 Mode = Memory::Read_U32(_CommandAddress +0x10); u32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
INFO_LOG(WII_IPC_FILEIO, "FileIO: Old Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)", SeekPosition, Mode, m_Name.c_str(), m_FileLength); INFO_LOG(WII_IPC_FILEIO, "FileIO: Old Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)", SeekPosition, Mode, m_Name.c_str(), m_FileLength);
@ -183,12 +182,11 @@ CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
{ {
u32 ReturnValue = 0; u32 ReturnValue = 0;
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Read to this memory address u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address
u32 Size = Memory::Read_U32(_CommandAddress +0x10); u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if (m_pFileHandle != NULL) if (m_pFileHandle != NULL)
{ {
@ -206,12 +204,11 @@ CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
{ {
u32 ReturnValue = 0; u32 ReturnValue = 0;
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Write data from this memory address u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
u32 Size = Memory::Read_U32(_CommandAddress +0x10); u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str()); INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
@ -227,8 +224,7 @@ CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_Name.c_str()); INFO_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_Name.c_str());
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
@ -236,10 +232,10 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
#endif #endif
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
// u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); //u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
// u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); //u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
// u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); //u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
// u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); //u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
switch(Parameter) switch(Parameter)
{ {
@ -274,8 +270,7 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
return true; return true;
} }
bool bool CWII_IPC_HLE_Device_FileIO::ReturnFileHandle()
CWII_IPC_HLE_Device_FileIO::ReturnFileHandle()
{ {
if(m_pFileHandle == NULL) if(m_pFileHandle == NULL)
return false; return false;

View File

@ -23,7 +23,6 @@
class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
{ {
public: public:
CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName); CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_FileIO(); virtual ~CWII_IPC_HLE_Device_FileIO();
@ -37,35 +36,41 @@ public:
bool ReturnFileHandle(); bool ReturnFileHandle();
private: private:
enum
{
ISFS_OPEN_READ = 1,
ISFS_OPEN_WRITE,
ISFS_OPEN_RW = (ISFS_OPEN_READ | ISFS_OPEN_WRITE)
};
enum enum
{ {
ISFS_FUNCNULL = 0, ISFS_FUNCNULL = 0,
ISFS_FUNCGETSTAT = 1, ISFS_FUNCGETSTAT,
ISFS_FUNCREADDIR = 2, ISFS_FUNCREADDIR,
ISFS_FUNCGETATTR = 3, ISFS_FUNCGETATTR,
ISFS_FUNCGETUSAGE = 4, ISFS_FUNCGETUSAGE
}; };
enum enum
{ {
ISFS_IOCTL_FORMAT = 1, ISFS_IOCTL_FORMAT = 1,
ISFS_IOCTL_GETSTATS = 2, ISFS_IOCTL_GETSTATS,
ISFS_IOCTL_CREATEDIR = 3, ISFS_IOCTL_CREATEDIR,
ISFS_IOCTL_READDIR = 4, ISFS_IOCTL_READDIR,
ISFS_IOCTL_SETATTR = 5, ISFS_IOCTL_SETATTR,
ISFS_IOCTL_GETATTR = 6, ISFS_IOCTL_GETATTR,
ISFS_IOCTL_DELETE = 7, ISFS_IOCTL_DELETE,
ISFS_IOCTL_RENAME = 8, ISFS_IOCTL_RENAME,
ISFS_IOCTL_CREATEFILE = 9, ISFS_IOCTL_CREATEFILE,
ISFS_IOCTL_SETFILEVERCTRL = 10, ISFS_IOCTL_SETFILEVERCTRL,
ISFS_IOCTL_GETFILESTATS = 11, ISFS_IOCTL_GETFILESTATS,
ISFS_IOCTL_GETUSAGE = 12, ISFS_IOCTL_GETUSAGE,
ISFS_IOCTL_SHUTDOWN = 13, ISFS_IOCTL_SHUTDOWN
}; };
FILE* m_pFileHandle; FILE* m_pFileHandle;
u64 m_FileLength; u32 m_FileLength;
std::string m_Filename; std::string m_Filename;
}; };

View File

@ -73,7 +73,7 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_fs::Close(u32 _CommandAddress, bool _bForce) bool CWII_IPC_HLE_Device_fs::Close(u32 _CommandAddress, bool _bForce)
{ {
INFO_LOG(WII_IPC_NET, "/dev/fs: Close"); INFO_LOG(WII_IPC_FILEIO, "Close");
if (!_bForce) if (!_bForce)
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false; m_Active = false;
@ -102,7 +102,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
u32 ReturnValue = FS_RESULT_OK; u32 ReturnValue = FS_RESULT_OK;
SIOCtlVBuffer CommandBuffer(_CommandAddress); SIOCtlVBuffer CommandBuffer(_CommandAddress);
// Prepare the out buffer(s) with zeroes as a safety precaution // Prepare the out buffer(s) with zeros as a safety precaution
// to avoid returning bad values // to avoid returning bad values
for(u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++) for(u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++)
{ {
@ -120,32 +120,19 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", Filename.c_str()); INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", Filename.c_str());
/* Check if this is really a directory. Or a file, because it seems like Mario Kart
did a IOCTL_READ_DIR on the save file to check if it existed before deleting it,
and if I didn't returned a -something it never deleted the file presumably because
it thought it didn't exist. So this solution worked for Mario Kart.
F|RES: i dont have mkart but -6 is a wrong return value if you try to read from a
directory which doesnt exist
JP: Okay, but Mario Kart calls this for files and if I return 0 here it never
creates a new file in any event, it just calls a DELETE_FILE and never close
the handle, so perhaps this is better
*/
if (!File::Exists(Filename.c_str())) if (!File::Exists(Filename.c_str()))
{ {
WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", Filename.c_str()); WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", Filename.c_str());
ReturnValue = FS_DIRFILE_NOT_FOUND; ReturnValue = FS_DIRFILE_NOT_FOUND;
break; break;
} }
/* Okay, maybe it is a file but not a directory, then we should return -101?
I have not seen any example of this. */
// AyuanX: what if we return "found one successfully" if it is a file? // AyuanX: what if we return "found one successfully" if it is a file?
else if (!File::IsDirectory(Filename.c_str())) else if (!File::IsDirectory(Filename.c_str()))
{ {
WARN_LOG(WII_IPC_FILEIO, "FS: Cannot search on file yet", Filename.c_str()); // It's not a directory, so error.
// Games don't usually seem to care WHICH error they get, as long as it's <0
WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_INVALID_ARGUMENT");
ReturnValue = FS_INVALID_ARGUMENT; ReturnValue = FS_INVALID_ARGUMENT;
break; break;
} }
@ -279,22 +266,23 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
{ {
case IOCTL_GET_STATS: case IOCTL_GET_STATS:
{ {
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 28); if (_BufferOutSize < 0x1c)
return -1017;
WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - no idea what we have to return here, prolly the free memory etc:)"); WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now");
WARN_LOG(WII_IPC_FILEIO, " InBufferSize: %i OutBufferSize: %i", _BufferInSize, _BufferOutSize);
// This happens in Tatsonuko vs Capcom., Transformers NANDStat fs;
// The buffer out values are ripped form a real WII and i dont know the meaning
// of them. Prolly it is some kind of small statistic like number of iblocks, free iblocks etc //TODO: scrape the real amounts from somewhere...
u32 Addr = _BufferOut; fs.BlockSize = 0x4000;
Memory::Write_U32(0x00004000, Addr); Addr += 4; fs.FreeBlocks = 0x5DEC;
Memory::Write_U32(0x00005717, Addr); Addr += 4; fs.UsedBlocks = 0x1DD4;
Memory::Write_U32(0x000024a9, Addr); Addr += 4; fs.unk3 = 0x10;
Memory::Write_U32(0x00000000, Addr); Addr += 4; fs.unk4 = 0x02F0;
Memory::Write_U32(0x00000300, Addr); Addr += 4; fs.Free_INodes = 0x146B;
Memory::Write_U32(0x0000163e, Addr); Addr += 4; fs.unk5 = 0x0394;
Memory::Write_U32(0x000001c1, Addr);
*(NANDStat*)Memory::GetPointer(_BufferOut) = fs;
return FS_RESULT_OK; return FS_RESULT_OK;
} }
@ -431,7 +419,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
// try to make the basis directory // try to make the basis directory
File::CreateFullPath(FilenameRename.c_str()); File::CreateFullPath(FilenameRename.c_str());
// if there is already a filedelete it // if there is already a file, delete it
if (File::Exists(FilenameRename.c_str())) if (File::Exists(FilenameRename.c_str()))
{ {
File::Delete(FilenameRename.c_str()); File::Delete(FilenameRename.c_str());
@ -490,7 +478,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
return FS_RESULT_FATAL; return FS_RESULT_FATAL;
} }
INFO_LOG(WII_IPC_FILEIO, " result = FS_RESULT_OK", Filename.c_str()); INFO_LOG(WII_IPC_FILEIO, "\tresult = FS_RESULT_OK");
return FS_RESULT_OK; return FS_RESULT_OK;
} }
break; break;

View File

@ -19,6 +19,17 @@
#include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_Device.h"
struct NANDStat
{
u32 BlockSize;
u32 FreeBlocks;
u32 UsedBlocks;
u32 unk3;
u32 unk4;
u32 Free_INodes;
u32 unk5; // Used INodes?
};
enum { enum {
FS_RESULT_OK = 0, FS_RESULT_OK = 0,
FS_DIRFILE_NOT_FOUND = -6, FS_DIRFILE_NOT_FOUND = -6,