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"
// ===================================================
/* 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)
{
char Buffer[128];
@ -33,7 +31,7 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
std::string Filename(FULL_WII_ROOT_DIR);
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;
@ -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
, m_pFileHandle(NULL)
, m_FileLength(0)
{}
{
}
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
{}
{
}
bool
CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
bool 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);
@ -67,8 +66,7 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{
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]);
switch(_Mode)
{
case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
case 0x02: // m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
case ISFS_OPEN_READ: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); 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
// 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;
}
}
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]);
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());
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());
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]);
ReturnValue = FS_INVALID_ARGUMENT;
@ -131,12 +131,11 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
{
u32 ReturnValue = 0;
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
u32 Mode = Memory::Read_U32(_CommandAddress +0x10);
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
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);
@ -183,12 +182,11 @@ CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
{
u32 ReturnValue = 0;
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Read to this memory address
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address
u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if (m_pFileHandle != NULL)
{
@ -206,12 +204,11 @@ CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
{
u32 ReturnValue = 0;
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Write data from this memory address
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
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());
@ -227,8 +224,7 @@ CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
{
INFO_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_Name.c_str());
#if defined(_DEBUG) || defined(DEBUGFAST)
@ -236,10 +232,10 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
#endif
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
// u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
// u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
// u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
// u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
//u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
//u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
switch(Parameter)
{
@ -274,8 +270,7 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
return true;
}
bool
CWII_IPC_HLE_Device_FileIO::ReturnFileHandle()
bool CWII_IPC_HLE_Device_FileIO::ReturnFileHandle()
{
if(m_pFileHandle == NULL)
return false;

View File

@ -23,7 +23,6 @@
class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
{
public:
CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_FileIO();
@ -37,35 +36,41 @@ public:
bool ReturnFileHandle();
private:
enum
{
ISFS_OPEN_READ = 1,
ISFS_OPEN_WRITE,
ISFS_OPEN_RW = (ISFS_OPEN_READ | ISFS_OPEN_WRITE)
};
enum
{
ISFS_FUNCNULL = 0,
ISFS_FUNCGETSTAT = 1,
ISFS_FUNCREADDIR = 2,
ISFS_FUNCGETATTR = 3,
ISFS_FUNCGETUSAGE = 4,
ISFS_FUNCGETSTAT,
ISFS_FUNCREADDIR,
ISFS_FUNCGETATTR,
ISFS_FUNCGETUSAGE
};
enum
{
ISFS_IOCTL_FORMAT = 1,
ISFS_IOCTL_GETSTATS = 2,
ISFS_IOCTL_CREATEDIR = 3,
ISFS_IOCTL_READDIR = 4,
ISFS_IOCTL_SETATTR = 5,
ISFS_IOCTL_GETATTR = 6,
ISFS_IOCTL_DELETE = 7,
ISFS_IOCTL_RENAME = 8,
ISFS_IOCTL_CREATEFILE = 9,
ISFS_IOCTL_SETFILEVERCTRL = 10,
ISFS_IOCTL_GETFILESTATS = 11,
ISFS_IOCTL_GETUSAGE = 12,
ISFS_IOCTL_SHUTDOWN = 13,
ISFS_IOCTL_GETSTATS,
ISFS_IOCTL_CREATEDIR,
ISFS_IOCTL_READDIR,
ISFS_IOCTL_SETATTR,
ISFS_IOCTL_GETATTR,
ISFS_IOCTL_DELETE,
ISFS_IOCTL_RENAME,
ISFS_IOCTL_CREATEFILE,
ISFS_IOCTL_SETFILEVERCTRL,
ISFS_IOCTL_GETFILESTATS,
ISFS_IOCTL_GETUSAGE,
ISFS_IOCTL_SHUTDOWN
};
FILE* m_pFileHandle;
u64 m_FileLength;
u32 m_FileLength;
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)
{
INFO_LOG(WII_IPC_NET, "/dev/fs: Close");
INFO_LOG(WII_IPC_FILEIO, "Close");
if (!_bForce)
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
@ -102,7 +102,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
u32 ReturnValue = FS_RESULT_OK;
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
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());
/* 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()))
{
WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", Filename.c_str());
ReturnValue = FS_DIRFILE_NOT_FOUND;
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?
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;
break;
}
@ -279,22 +266,23 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
{
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, " InBufferSize: %i OutBufferSize: %i", _BufferInSize, _BufferOutSize);
WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now");
// This happens in Tatsonuko vs Capcom., Transformers
// 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
u32 Addr = _BufferOut;
Memory::Write_U32(0x00004000, Addr); Addr += 4;
Memory::Write_U32(0x00005717, Addr); Addr += 4;
Memory::Write_U32(0x000024a9, Addr); Addr += 4;
Memory::Write_U32(0x00000000, Addr); Addr += 4;
Memory::Write_U32(0x00000300, Addr); Addr += 4;
Memory::Write_U32(0x0000163e, Addr); Addr += 4;
Memory::Write_U32(0x000001c1, Addr);
NANDStat fs;
//TODO: scrape the real amounts from somewhere...
fs.BlockSize = 0x4000;
fs.FreeBlocks = 0x5DEC;
fs.UsedBlocks = 0x1DD4;
fs.unk3 = 0x10;
fs.unk4 = 0x02F0;
fs.Free_INodes = 0x146B;
fs.unk5 = 0x0394;
*(NANDStat*)Memory::GetPointer(_BufferOut) = fs;
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
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()))
{
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;
}
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;
}
break;

View File

@ -19,6 +19,17 @@
#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 {
FS_RESULT_OK = 0,
FS_DIRFILE_NOT_FOUND = -6,