diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 5509f280bb..a7927a9c5d 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -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; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index cdd14a3ba3..ade2221ac8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -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; }; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index c068bf3436..601d331a93 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -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; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h index dfd8c2ffc9..164d864bfd 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h @@ -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,