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; };