From 0efe6c2124ab5e59a43a41b0e665787f2acf7f43 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 15:13:44 -0600 Subject: [PATCH 1/5] GET_ATTR should not be returning the real filepath that we built. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 38100e5d7a..5424542a73 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 @@ -377,7 +377,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 Addr = _BufferOut; Memory::Write_U32(OwnerID, Addr); Addr += 4; Memory::Write_U16(GroupID, Addr); Addr += 2; - memcpy(Memory::GetPointer(Addr), Filename.c_str(), Filename.size()); Addr += 64; + memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64); Addr += 64; Memory::Write_U8(OwnerPerm, Addr); Addr += 1; Memory::Write_U8(GroupPerm, Addr); Addr += 1; Memory::Write_U8(OtherPerm, Addr); Addr += 1; From 04a33b177a8784dc1d2a4fe8cae8b558d28a1a34 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 15:15:04 -0600 Subject: [PATCH 2/5] Make seek mode 2 (offset from end of file) make sense. I doubt any games use this. --- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 63 ++++++++----------- 1 file changed, 26 insertions(+), 37 deletions(-) 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 711d360874..4ac9cb0eaa 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 @@ -165,7 +165,7 @@ File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile() bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) { u32 ReturnValue = FS_RESULT_FATAL; - const u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); + const u32 SeekOffset = Memory::Read_U32(_CommandAddress + 0xC); const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10); if (auto file = OpenFile()) @@ -173,48 +173,37 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) ReturnValue = FS_RESULT_FATAL; const u64 fileSize = file.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)", SeekOffset, Mode, m_Name.c_str(), fileSize); + u64 wantedPos = 0; switch (Mode) { - case 0: - { - if (SeekPosition <= fileSize) - { - m_SeekPos = SeekPosition; - ReturnValue = m_SeekPos; - } - break; - } - case 1: - { - u32 wantedPos = SeekPosition+m_SeekPos; - if (wantedPos <= fileSize) - { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; - } - break; - } - case 2: - { - u64 wantedPos = fileSize+m_SeekPos; - if (wantedPos <= fileSize) - { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; - } - break; - } - default: - { - PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); - ReturnValue = FS_RESULT_FATAL; - break; - } + case 0: + wantedPos = SeekOffset; + break; + + case 1: + wantedPos = m_SeekPos + SeekOffset; + break; + + case 2: + wantedPos = fileSize + (s32)SeekOffset; + break; + + default: + PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); + ReturnValue = FS_RESULT_FATAL; + break; + } + + if (wantedPos <= fileSize) + { + m_SeekPos = wantedPos; + ReturnValue = m_SeekPos; } } else { + // TODO: This can't be right. ReturnValue = FS_FILE_NOT_EXIST; } Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); From efcb2abe9bf60978d2e5e776268179671bfef87a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:01:23 -0600 Subject: [PATCH 3/5] Don't open/close file for every file operation. --- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 76 +++++++++++-------- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 5 +- 2 files changed, 46 insertions(+), 35 deletions(-) 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 4ac9cb0eaa..5655e9b46d 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 @@ -139,27 +139,36 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) return true; } -File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile() +// Opens file if needed. +// Clears any error state. +// Seeks to proper position position. +void CWII_IPC_HLE_Device_FileIO::PrepareFile() { - const char* open_mode = ""; - - switch (m_Mode) + if (!m_file.IsOpen()) { - case ISFS_OPEN_READ: - open_mode = "rb"; - break; - - case ISFS_OPEN_WRITE: - case ISFS_OPEN_RW: - open_mode = "r+b"; - break; - - default: - PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); - break; + const char* open_mode = ""; + + switch (m_Mode) + { + case ISFS_OPEN_READ: + open_mode = "rb"; + break; + + case ISFS_OPEN_WRITE: + case ISFS_OPEN_RW: + open_mode = "r+b"; + break; + + default: + PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); + break; + } + + m_file.Open(m_filepath, open_mode); } - return File::IOFile(m_filepath, open_mode); + m_file.Clear(); + m_file.Seek(m_SeekPos, SEEK_SET); } bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) @@ -168,11 +177,12 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) const u32 SeekOffset = Memory::Read_U32(_CommandAddress + 0xC); const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10); - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { ReturnValue = FS_RESULT_FATAL; - const u64 fileSize = file.GetSize(); + const u64 fileSize = m_file.GetSize(); INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekOffset, Mode, m_Name.c_str(), fileSize); u64 wantedPos = 0; switch (Mode) @@ -182,7 +192,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) break; case 1: - wantedPos = m_SeekPos + SeekOffset; + wantedPos = m_SeekPos + (s32)SeekOffset; break; case 2: @@ -216,9 +226,9 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) u32 ReturnValue = FS_EACCESS; const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - - - if (auto file = OpenFile()) + + PrepareFile(); + if (m_file) { if (m_Mode == ISFS_OPEN_WRITE) { @@ -227,9 +237,8 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) else { INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str()); - file.Seek(m_SeekPos, SEEK_SET); - ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle()); - if (ReturnValue != Size && ferror(file.GetHandle())) + ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file.GetHandle()); + if (ReturnValue != Size && ferror(m_file.GetHandle())) { ReturnValue = FS_EACCESS; } @@ -256,8 +265,8 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { if (m_Mode == ISFS_OPEN_READ) { @@ -266,8 +275,7 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) else { INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str()); - file.Seek(m_SeekPos, SEEK_SET); - if (file.WriteBytes(Memory::GetPointer(Address), Size)) + if (m_file.WriteBytes(Memory::GetPointer(Address), Size)) { ReturnValue = Size; m_SeekPos += Size; @@ -297,9 +305,10 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) { case ISFS_IOCTL_GETFILESTATS: { - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { - u32 m_FileLength = (u32)file.GetSize(); + u32 m_FileLength = (u32)m_file.GetSize(); const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS"); @@ -334,6 +343,7 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) p.Do(m_Mode); p.Do(m_SeekPos); - + + m_file.Close(); m_filepath = HLE_IPC_BuildFilename(m_Name, 64); } 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 3698d05c9f..f5a0e9008a 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 @@ -39,9 +39,9 @@ public: bool IOCtl(u32 _CommandAddress); void DoState(PointerWrap &p); - File::IOFile OpenFile(); - private: + void PrepareFile(); + enum { ISFS_OPEN_READ = 1, @@ -77,6 +77,7 @@ private: u32 m_Mode; u32 m_SeekPos; + File::IOFile m_file; std::string m_filepath; }; From 6d50bd127da8b34bb02327c0a375a19ff881ec34 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:22:11 -0600 Subject: [PATCH 4/5] Remove hack that seems to be no longer needed. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 3 --- 1 file changed, 3 deletions(-) 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 5655e9b46d..1aad48592c 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 @@ -33,9 +33,6 @@ std::string HLE_IPC_BuildFilename(std::string path_wii, int _size) { std::string path_full = File::GetUserPath(D_WIIROOT_IDX); - if ((path_wii.length() > 0) && (path_wii[1] == '0')) - path_full += std::string("/title"); // this looks and feel like a hack... - // Replaces chars that FAT32 can't support with strings defined in /sys/replace for (auto i = replacements.begin(); i != replacements.end(); ++i) { From 5d47fd1dde3ccdc286e2248db9967c278d694f5a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:38:35 -0600 Subject: [PATCH 5/5] Remove HLE_IPC_CreateVirtualFATFilesystem as it no longer takes 3 minutes to LLE like the comment says. --- Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp | 4 +-- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 33 ------------------- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 1 - 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp index d3fa172621..a86c38286d 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp @@ -90,9 +90,7 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename) u64 titleID = ContentLoader.GetTitleID(); // create data directory File::CreateFullPath(Common::GetTitleDataPath(titleID)); - - if (titleID == TITLEID_SYSMENU) - HLE_IPC_CreateVirtualFATFilesystem(); + // setup wii mem if (!SetupWiiMemory(ContentLoader.GetCountry())) return false; 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 1aad48592c..acf5c921e9 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 @@ -45,39 +45,6 @@ std::string HLE_IPC_BuildFilename(std::string path_wii, int _size) return path_full; } -void HLE_IPC_CreateVirtualFATFilesystem() -{ - const int cdbSize = 0x01400000; - const std::string cdbPath = Common::GetTitleDataPath(TITLEID_SYSMENU) + "cdb.vff"; - if ((int)File::GetSize(cdbPath) < cdbSize) - { - // cdb.vff is a virtual Fat filesystem created on first launch of sysmenu - // we create it here as it is faster ~3 minutes for me when sysmenu does it ~1 second created here - const u8 cdbHDR[0x20] = {'V', 'F', 'F', 0x20, 0xfe, 0xff, 1, 0, 1, 0x40, 0, 0, 0, 0x20}; - const u8 cdbFAT[4] = {0xf0, 0xff, 0xff, 0xff}; - - File::IOFile cdbFile(cdbPath, "wb"); - if (cdbFile) - { - cdbFile.WriteBytes(cdbHDR, 0x20); - cdbFile.WriteBytes(cdbFAT, 0x4); - cdbFile.Seek(0x14020, SEEK_SET); - cdbFile.WriteBytes(cdbFAT, 0x4); - // 20 MiB file - cdbFile.Seek(cdbSize - 1, SEEK_SET); - // write the final 0 to 0 file from the second FAT to 20 MiB - cdbFile.WriteBytes(cdbHDR + 14, 1); - if (!cdbFile.IsGood()) - { - cdbFile.Close(); - File::Delete(cdbPath); - } - cdbFile.Flush(); - cdbFile.Close(); - } - } -} - CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware , m_Mode(0) 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 f5a0e9008a..fd33d7d69c 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 @@ -22,7 +22,6 @@ #include "FileUtil.h" std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size); -void HLE_IPC_CreateVirtualFATFilesystem(); class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device {