Fixes issue 2917 and possibly others like 5232
This commit is contained in:
parent
e8e2c241d7
commit
53d2d9718f
|
@ -87,6 +87,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std:
|
|||
, m_pFileHandle(NULL)
|
||||
, m_FileLength(0)
|
||||
, m_Mode(0)
|
||||
, m_SeekPos(0)
|
||||
{
|
||||
Common::ReadReplacements(replacements);
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ 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);
|
||||
|
||||
m_pFileHandle.Close();
|
||||
//m_pFileHandle.Close();
|
||||
|
||||
m_FileLength = 0;
|
||||
m_Mode = 0;
|
||||
|
@ -117,7 +118,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
u32 ReturnValue = 0;
|
||||
|
||||
// close the file handle if we get a reopen
|
||||
m_pFileHandle.Close();
|
||||
//m_pFileHandle.Close();
|
||||
|
||||
static const char* const Modes[] =
|
||||
{
|
||||
|
@ -129,30 +130,13 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
|
||||
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
|
||||
|
||||
|
||||
// The file must exist before we can open it
|
||||
// It should be created by ISFS_CreateFile, not here
|
||||
if(File::Exists(m_Filename))
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s)", m_Name.c_str(), Modes[_Mode]);
|
||||
switch(_Mode)
|
||||
{
|
||||
case ISFS_OPEN_READ:
|
||||
m_pFileHandle.Open(m_Filename, "rb");
|
||||
break;
|
||||
|
||||
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
|
||||
case ISFS_OPEN_WRITE:
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
|
||||
case ISFS_OPEN_RW:
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlertT("FileIO: Unknown open mode : 0x%02x", _Mode);
|
||||
break;
|
||||
}
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
|
||||
ReturnValue = m_DeviceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -160,70 +144,99 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (m_pFileHandle != NULL)
|
||||
{
|
||||
m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||
ReturnValue = m_DeviceID;
|
||||
}
|
||||
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_RESULT_FATAL;
|
||||
}
|
||||
|
||||
if (_CommandAddress)
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
||||
m_Active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
{
|
||||
switch(m_Mode)
|
||||
{
|
||||
case ISFS_OPEN_READ:
|
||||
m_pFileHandle.Open(m_Filename, "rb");
|
||||
break;
|
||||
|
||||
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
|
||||
case ISFS_OPEN_WRITE:
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
|
||||
case ISFS_OPEN_RW:
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
|
||||
break;
|
||||
}
|
||||
return m_pFileHandle.IsOpen();
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_FileIO::CloseFile()
|
||||
{
|
||||
m_pFileHandle.Close();
|
||||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
{
|
||||
u32 ReturnValue = FS_RESULT_FATAL;
|
||||
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
if (m_pFileHandle == NULL)
|
||||
{
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FILEIO: Seek failed because of null file handle - %s", m_Name.c_str());
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
else if (Mode >= 0 && Mode <= 2)
|
||||
|
||||
if(OpenFile())
|
||||
{
|
||||
ReturnValue = FS_RESULT_FATAL;
|
||||
|
||||
const u64 fileSize = m_pFileHandle.GetSize();
|
||||
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||
|
||||
// Set seek mode
|
||||
int seek_mode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
|
||||
// POSIX allows seek past EOF, the Wii does not.
|
||||
// TODO: Can we check this without tell'ing/seek'ing twice?
|
||||
const u64 curPos = m_pFileHandle.Tell();
|
||||
if (m_pFileHandle.Seek(SeekPosition, seek_mode[Mode]))
|
||||
{
|
||||
const u64 newPos = m_pFileHandle.Tell();
|
||||
if (newPos > fileSize)
|
||||
switch(Mode){
|
||||
case 0:
|
||||
{
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FILEIO: Seek past EOF - %s", m_Name.c_str());
|
||||
m_pFileHandle.Seek(curPos, SEEK_SET);
|
||||
if(SeekPosition >=0 && SeekPosition <= fileSize)
|
||||
{
|
||||
m_SeekPos = SeekPosition;
|
||||
ReturnValue = m_SeekPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
s32 wantedPos = SeekPosition+m_SeekPos;
|
||||
if(wantedPos >=0 && wantedPos <= fileSize)
|
||||
{
|
||||
m_SeekPos = wantedPos;
|
||||
ReturnValue = m_SeekPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
s32 wantedPos = fileSize+m_SeekPos;
|
||||
if(wantedPos >=0 && 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;
|
||||
}
|
||||
else
|
||||
ReturnValue = (u32)newPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must clear the failbits, since subsequent seeks don't care about
|
||||
// past failure on Wii
|
||||
m_pFileHandle.Clear();
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FILEIO: Seek failed - %s", m_Name.c_str());
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode);
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
||||
return true;
|
||||
|
@ -235,7 +248,8 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address
|
||||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
if (m_pFileHandle != NULL)
|
||||
|
||||
if(OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
{
|
||||
|
@ -244,15 +258,24 @@ 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());
|
||||
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle.GetHandle());
|
||||
if (ReturnValue != Size && ferror(m_pFileHandle.GetHandle()))
|
||||
{
|
||||
ReturnValue = FS_EACCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SeekPos += Size;
|
||||
}
|
||||
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", m_Name.c_str(), Address, Size);
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could not be opened or does not exist", m_Name.c_str(), Address, Size);
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
@ -265,9 +288,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);
|
||||
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
||||
|
||||
if (m_pFileHandle)
|
||||
if(OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
{
|
||||
|
@ -275,9 +297,20 @@ 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());
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
if (m_pFileHandle.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
{
|
||||
ReturnValue = Size;
|
||||
m_SeekPos += Size;
|
||||
}
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could not be opened or does not exist", m_Name.c_str(), Address, Size);
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
@ -297,19 +330,29 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
||||
|
||||
// Return Value
|
||||
u32 ReturnValue = 0; // no error
|
||||
|
||||
switch(Parameter)
|
||||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||
const u32 Position = (u32)m_pFileHandle.Tell();
|
||||
if(OpenFile())
|
||||
{
|
||||
m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, Position);
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, m_SeekPos);
|
||||
|
||||
Memory::Write_U32(m_FileLength, BufferOut);
|
||||
Memory::Write_U32(Position, BufferOut+4);
|
||||
Memory::Write_U32(m_FileLength, BufferOut);
|
||||
Memory::Write_U32(m_SeekPos, BufferOut+4);
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -321,8 +364,6 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
|
||||
}
|
||||
|
||||
// Return Value
|
||||
const u32 ReturnValue = 0; // no error
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -39,6 +39,9 @@ public:
|
|||
bool IOCtl(u32 _CommandAddress);
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
bool OpenFile();
|
||||
void CloseFile();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
|
@ -77,6 +80,8 @@ private:
|
|||
u32 m_FileLength;
|
||||
u32 m_Mode;
|
||||
|
||||
u32 m_SeekPos;
|
||||
|
||||
std::string m_Filename;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue