Some cleanup of CWII_IPC_HLE_Device_FileIO:

The real file was never kept open for longer than a single operation so there was no point in dealing with it in DoState.
Saving the real path in the savestate was also probably a bad idea. Savestates should be a bit more portable now.
This commit is contained in:
Jordan Woyak 2013-02-17 13:30:04 -06:00
parent 0cdd4434b9
commit fa9aafeed8
5 changed files with 63 additions and 90 deletions

View File

@ -42,6 +42,7 @@
#endif #endif
#include <fstream> #include <fstream>
#include <algorithm>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef S_ISDIR #ifndef S_ISDIR
@ -774,6 +775,24 @@ IOFile::~IOFile()
Close(); Close();
} }
IOFile::IOFile(IOFile&& other)
: m_file(NULL), m_good(true)
{
Swap(other);
}
IOFile& IOFile::operator=(IOFile other)
{
Swap(other);
return *this;
}
void IOFile::Swap(IOFile& other)
{
std::swap(m_file, other.m_file);
std::swap(m_good, other.m_good);
}
bool IOFile::Open(const std::string& filename, const char openmode[]) bool IOFile::Open(const std::string& filename, const char openmode[])
{ {
Close(); Close();

View File

@ -150,7 +150,7 @@ bool ReadFileToString(bool text_file, const char *filename, std::string &str);
// simple wrapper for cstdlib file functions to // simple wrapper for cstdlib file functions to
// hopefully will make error checking easier // hopefully will make error checking easier
// and make forgetting an fclose() harder // and make forgetting an fclose() harder
class IOFile : NonCopyable class IOFile
{ {
public: public:
IOFile(); IOFile();
@ -159,6 +159,11 @@ public:
~IOFile(); ~IOFile();
IOFile(IOFile&& other);
IOFile& operator=(IOFile other);
void Swap(IOFile& other);
bool Open(const std::string& filename, const char openmode[]); bool Open(const std::string& filename, const char openmode[]);
bool Close(); bool Close();
@ -212,6 +217,7 @@ public:
void Clear() { m_good = true; std::clearerr(m_file); } void Clear() { m_good = true; std::clearerr(m_file); }
private: private:
IOFile(const IOFile&) /*= delete*/;
IOFile& operator=(const IOFile&) /*= delete*/; IOFile& operator=(const IOFile&) /*= delete*/;
std::FILE* m_file; std::FILE* m_file;

View File

@ -29,16 +29,15 @@
static Common::replace_v replacements; static Common::replace_v replacements;
// 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(std::string path_wii, int _size)
{ {
std::string path_full = File::GetUserPath(D_WIIROOT_IDX); std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
std::string path_wii(_pFilename);
if ((path_wii.length() > 0) && (path_wii[1] == '0')) if ((path_wii.length() > 0) && (path_wii[1] == '0'))
path_full += std::string("/title"); // this looks and feel like a hack... 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 // Replaces chars that FAT32 can't support with strings defined in /sys/replace
for (Common::replace_v::const_iterator i = replacements.begin(); i != replacements.end(); ++i) for (auto i = replacements.begin(); i != replacements.end(); ++i)
{ {
for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j) for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j)
path_wii.replace(j, 1, i->second); path_wii.replace(j, 1, i->second);
@ -84,7 +83,6 @@ void HLE_IPC_CreateVirtualFATFilesystem()
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName) 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 : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
, m_pFileHandle(NULL)
, m_Mode(0) , m_Mode(0)
, m_SeekPos(0) , m_SeekPos(0)
{ {
@ -112,9 +110,6 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
m_Mode = _Mode; m_Mode = _Mode;
u32 ReturnValue = 0; u32 ReturnValue = 0;
// close the file handle if we get a reopen
//m_pFileHandle.Close();
static const char* const Modes[] = static const char* const Modes[] =
{ {
"Unk Mode", "Unk Mode",
@ -123,19 +118,17 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
"Read and Write" "Read and Write"
}; };
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
// The file must exist before we can open it // The file must exist before we can open it
// It should be created by ISFS_CreateFile, not here // It should be created by ISFS_CreateFile, not here
if (File::Exists(m_Filename)) auto const filename = HLE_IPC_BuildFilename(m_Name, 64);
if (File::Exists(filename))
{ {
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode); INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
ReturnValue = m_DeviceID; ReturnValue = m_DeviceID;
} }
else else
{ {
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], m_Filename.c_str()); WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], filename.c_str());
ReturnValue = FS_FILE_NOT_EXIST; ReturnValue = FS_FILE_NOT_EXIST;
} }
@ -145,39 +138,27 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
return true; return true;
} }
File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile()
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
{ {
const char* open_mode = "";
switch (m_Mode) switch (m_Mode)
{ {
case ISFS_OPEN_READ: case ISFS_OPEN_READ:
{ open_mode = "rb";
m_pFileHandle.Open(m_Filename, "rb");
break; break;
}
case ISFS_OPEN_WRITE: case ISFS_OPEN_WRITE:
{
m_pFileHandle.Open(m_Filename, "r+b");
break;
}
case ISFS_OPEN_RW: case ISFS_OPEN_RW:
{ open_mode = "r+b";
m_pFileHandle.Open(m_Filename, "r+b");
break; break;
}
default: default:
{
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
break; break;
} }
}
return m_pFileHandle.IsOpen();
}
void CWII_IPC_HLE_Device_FileIO::CloseFile() return File::IOFile(HLE_IPC_BuildFilename(m_Name, 64), open_mode);
{
m_pFileHandle.Close();
} }
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
@ -186,14 +167,14 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
const u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); const u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10); const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
if (auto file = OpenFile())
if (OpenFile())
{ {
ReturnValue = FS_RESULT_FATAL; ReturnValue = FS_RESULT_FATAL;
const u64 fileSize = m_pFileHandle.GetSize(); 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)", SeekPosition, Mode, m_Name.c_str(), fileSize);
switch (Mode){ switch (Mode)
{
case 0: case 0:
{ {
if (SeekPosition <= fileSize) if (SeekPosition <= fileSize)
@ -230,7 +211,6 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
break; break;
} }
} }
CloseFile();
} }
else else
{ {
@ -248,7 +228,7 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if (OpenFile()) if (auto file = OpenFile())
{ {
if (m_Mode == ISFS_OPEN_WRITE) if (m_Mode == ISFS_OPEN_WRITE)
{ {
@ -257,9 +237,9 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
else else
{ {
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str()); INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
m_pFileHandle.Seek(m_SeekPos, SEEK_SET); file.Seek(m_SeekPos, SEEK_SET);
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle.GetHandle()); ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle());
if (ReturnValue != Size && ferror(m_pFileHandle.GetHandle())) if (ReturnValue != Size && ferror(file.GetHandle()))
{ {
ReturnValue = FS_EACCESS; ReturnValue = FS_EACCESS;
} }
@ -269,7 +249,6 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
} }
} }
CloseFile();
} }
else else
{ {
@ -288,7 +267,7 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
if (OpenFile()) if (auto file = OpenFile())
{ {
if (m_Mode == ISFS_OPEN_READ) if (m_Mode == ISFS_OPEN_READ)
{ {
@ -297,14 +276,13 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
else else
{ {
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());
m_pFileHandle.Seek(m_SeekPos, SEEK_SET); file.Seek(m_SeekPos, SEEK_SET);
if (m_pFileHandle.WriteBytes(Memory::GetPointer(Address), Size)) if (file.WriteBytes(Memory::GetPointer(Address), Size))
{ {
ReturnValue = Size; ReturnValue = Size;
m_SeekPos += Size; m_SeekPos += Size;
} }
} }
CloseFile();
} }
else else
{ {
@ -329,9 +307,9 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
{ {
case ISFS_IOCTL_GETFILESTATS: case ISFS_IOCTL_GETFILESTATS:
{ {
if (OpenFile()) if (auto file = OpenFile())
{ {
u32 m_FileLength = (u32)m_pFileHandle.GetSize(); u32 m_FileLength = (u32)file.GetSize();
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS"); INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
@ -339,7 +317,6 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
Memory::Write_U32(m_FileLength, BufferOut); Memory::Write_U32(m_FileLength, BufferOut);
Memory::Write_U32(m_SeekPos, BufferOut+4); Memory::Write_U32(m_SeekPos, BufferOut+4);
CloseFile();
} }
else else
{ {
@ -365,30 +342,6 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
{ {
DoStateShared(p); DoStateShared(p);
bool have_file_handle = (m_pFileHandle != 0);
s32 seek = (have_file_handle) ? (s32)m_pFileHandle.Tell() : 0;
p.Do(have_file_handle);
p.Do(m_Mode); p.Do(m_Mode);
p.Do(seek);
p.Do(m_SeekPos); p.Do(m_SeekPos);
p.Do(m_Filename);
if (p.GetMode() == PointerWrap::MODE_READ)
{
int mode = m_Mode;
bool active = m_Active;
if (have_file_handle)
{
Open(0, m_Mode);
_dbg_assert_msg_(WII_IPC_HLE, m_pFileHandle, "bad filehandle");
}
else
Close(0, true);
m_Mode = mode;
m_Active = active;
}
if (have_file_handle)
m_pFileHandle.Seek(seek, SEEK_SET);
} }

View File

@ -21,7 +21,7 @@
#include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_Device.h"
#include "FileUtil.h" #include "FileUtil.h"
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size); std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size);
void HLE_IPC_CreateVirtualFATFilesystem(); void HLE_IPC_CreateVirtualFATFilesystem();
class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
@ -39,8 +39,7 @@ public:
bool IOCtl(u32 _CommandAddress); bool IOCtl(u32 _CommandAddress);
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
bool OpenFile(); File::IOFile OpenFile();
void CloseFile();
private: private:
enum enum
@ -76,12 +75,8 @@ private:
ISFS_IOCTL_SHUTDOWN ISFS_IOCTL_SHUTDOWN
}; };
File::IOFile m_pFileHandle;
u32 m_Mode; u32 m_Mode;
u32 m_SeekPos; u32 m_SeekPos;
std::string m_Filename;
}; };
#endif #endif

View File

@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread; static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system // Don't forget to increase this after doing changes on the savestate system
static const u32 STATE_VERSION = 12; static const u32 STATE_VERSION = 13;
struct StateHeader struct StateHeader
{ {