IOS HLE: Deduplicate request code in FileIO and FS
This commit is contained in:
parent
5a5985f674
commit
0e979ec75f
|
@ -2,6 +2,7 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
@ -70,11 +71,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 device_id,
|
|||
{
|
||||
}
|
||||
|
||||
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
|
||||
{
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
|
||||
void CWII_IPC_HLE_Device_FileIO::Close()
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_name.c_str(), m_device_id);
|
||||
m_Mode = 0;
|
||||
|
@ -84,12 +81,11 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bF
|
|||
m_file.reset();
|
||||
|
||||
m_is_active = false;
|
||||
return GetDefaultReply();
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode)
|
||||
IOSReturnCode CWII_IPC_HLE_Device_FileIO::Open(const IOSOpenRequest& request)
|
||||
{
|
||||
m_Mode = mode;
|
||||
m_Mode = request.flags;
|
||||
|
||||
static const char* const Modes[] = {"Unk Mode", "Read only", "Write only", "Read and Write"};
|
||||
|
||||
|
@ -97,21 +93,18 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode)
|
|||
|
||||
// The file must exist before we can open it
|
||||
// It should be created by ISFS_CreateFile, not here
|
||||
if (File::Exists(m_filepath) && !File::IsDirectory(m_filepath))
|
||||
if (!File::Exists(m_filepath) || File::IsDirectory(m_filepath))
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[mode], mode);
|
||||
OpenFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[mode],
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[m_Mode],
|
||||
m_filepath.c_str());
|
||||
if (command_address)
|
||||
Memory::Write_U32(FS_ENOENT, command_address + 4);
|
||||
return FS_ENOENT;
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[m_Mode], m_Mode);
|
||||
OpenFile();
|
||||
|
||||
m_is_active = true;
|
||||
return GetDefaultReply();
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
// This isn't theadsafe, but it's only called from the CPU thread.
|
||||
|
@ -158,98 +151,91 @@ void CWII_IPC_HLE_Device_FileIO::OpenFile()
|
|||
}
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(const IOSSeekRequest& request)
|
||||
{
|
||||
u32 ReturnValue = FS_EINVAL;
|
||||
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
u32 return_value = FS_EINVAL;
|
||||
|
||||
if (m_file->IsOpen())
|
||||
{
|
||||
ReturnValue = FS_EINVAL;
|
||||
|
||||
const s32 fileSize = (s32)m_file->GetSize();
|
||||
const u32 file_size = static_cast<u32>(m_file->GetSize());
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)",
|
||||
SeekPosition, Mode, m_name.c_str(), fileSize);
|
||||
request.offset, request.mode, m_name.c_str(), file_size);
|
||||
|
||||
switch (Mode)
|
||||
switch (request.mode)
|
||||
{
|
||||
case WII_SEEK_SET:
|
||||
case IOSSeekRequest::IOS_SEEK_SET:
|
||||
{
|
||||
if ((SeekPosition >= 0) && (SeekPosition <= fileSize))
|
||||
if (request.offset <= file_size)
|
||||
{
|
||||
m_SeekPos = SeekPosition;
|
||||
ReturnValue = m_SeekPos;
|
||||
m_SeekPos = request.offset;
|
||||
return_value = m_SeekPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WII_SEEK_CUR:
|
||||
case IOSSeekRequest::IOS_SEEK_CUR:
|
||||
{
|
||||
s32 wantedPos = SeekPosition + m_SeekPos;
|
||||
if (wantedPos >= 0 && wantedPos <= fileSize)
|
||||
const u32 wanted_pos = request.offset + m_SeekPos;
|
||||
if (wanted_pos <= file_size)
|
||||
{
|
||||
m_SeekPos = wantedPos;
|
||||
ReturnValue = m_SeekPos;
|
||||
m_SeekPos = wanted_pos;
|
||||
return_value = m_SeekPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WII_SEEK_END:
|
||||
case IOSSeekRequest::IOS_SEEK_END:
|
||||
{
|
||||
s32 wantedPos = SeekPosition + fileSize;
|
||||
if (wantedPos >= 0 && wantedPos <= fileSize)
|
||||
const u32 wanted_pos = request.offset + file_size;
|
||||
if (wanted_pos <= file_size)
|
||||
{
|
||||
m_SeekPos = wantedPos;
|
||||
ReturnValue = m_SeekPos;
|
||||
m_SeekPos = wanted_pos;
|
||||
return_value = m_SeekPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode);
|
||||
ReturnValue = FS_EINVAL;
|
||||
PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", request.mode);
|
||||
return_value = FS_EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReturnValue = FS_ENOENT;
|
||||
return_value = FS_ENOENT;
|
||||
}
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
||||
request.SetReturnValue(return_value);
|
||||
return GetDefaultReply();
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(const IOSReadWriteRequest& request)
|
||||
{
|
||||
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);
|
||||
|
||||
s32 return_value = FS_EACCESS;
|
||||
if (m_file->IsOpen())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
if (m_Mode == IOS_OPEN_WRITE)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO,
|
||||
"FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s", Size,
|
||||
Address, m_name.c_str());
|
||||
"FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s",
|
||||
request.size, request.buffer, m_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address,
|
||||
m_name.c_str());
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", request.size,
|
||||
request.buffer, m_name.c_str());
|
||||
m_file->Seek(m_SeekPos, SEEK_SET); // File might be opened twice, need to seek before we read
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file->GetHandle());
|
||||
if (ReturnValue != Size && ferror(m_file->GetHandle()))
|
||||
return_value = static_cast<u32>(
|
||||
fread(Memory::GetPointer(request.buffer), 1, request.size, m_file->GetHandle()));
|
||||
if (static_cast<u32>(return_value) != request.size && ferror(m_file->GetHandle()))
|
||||
{
|
||||
ReturnValue = FS_EACCESS;
|
||||
return_value = FS_EACCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SeekPos += Size;
|
||||
m_SeekPos += request.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,39 +243,35 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
{
|
||||
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_ENOENT;
|
||||
m_name.c_str(), request.buffer, request.size);
|
||||
return_value = FS_ENOENT;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
request.SetReturnValue(return_value);
|
||||
return GetDefaultReply();
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(const IOSReadWriteRequest& request)
|
||||
{
|
||||
u32 ReturnValue = FS_EACCESS;
|
||||
const u32 Address =
|
||||
Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
|
||||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
s32 return_value = FS_EACCESS;
|
||||
if (m_file->IsOpen())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
if (m_Mode == IOS_OPEN_READ)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO,
|
||||
"FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s", Size,
|
||||
Address, m_name.c_str());
|
||||
"FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s",
|
||||
request.size, request.buffer, m_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address,
|
||||
m_name.c_str());
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", request.size,
|
||||
request.buffer, m_name.c_str());
|
||||
m_file->Seek(m_SeekPos,
|
||||
SEEK_SET); // File might be opened twice, need to seek before we write
|
||||
if (m_file->WriteBytes(Memory::GetPointer(Address), Size))
|
||||
if (m_file->WriteBytes(Memory::GetPointer(request.buffer), request.size))
|
||||
{
|
||||
ReturnValue = Size;
|
||||
m_SeekPos += Size;
|
||||
return_value = request.size;
|
||||
m_SeekPos += request.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,51 +279,42 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
{
|
||||
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_ENOENT;
|
||||
m_name.c_str(), request.buffer, request.size);
|
||||
return_value = FS_ENOENT;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
request.SetReturnValue(return_value);
|
||||
return GetDefaultReply();
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(const IOSIOCtlRequest& request)
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_name.c_str());
|
||||
const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
u32 ReturnValue = 0;
|
||||
s32 return_value = IPC_SUCCESS;
|
||||
|
||||
switch (Parameter)
|
||||
switch (request.request)
|
||||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
if (m_file->IsOpen())
|
||||
{
|
||||
u32 m_FileLength = (u32)m_file->GetSize();
|
||||
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
DEBUG_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(m_SeekPos, BufferOut + 4);
|
||||
DEBUG_LOG(WII_IPC_FILEIO, "File: %s, Length: %" PRIu64 ", Pos: %i", m_name.c_str(),
|
||||
m_file->GetSize(), m_SeekPos);
|
||||
Memory::Write_U32(static_cast<u32>(m_file->GetSize()), request.buffer_out);
|
||||
Memory::Write_U32(m_SeekPos, request.buffer_out + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReturnValue = FS_ENOENT;
|
||||
return_value = FS_ENOENT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
|
||||
}
|
||||
break;
|
||||
request.Log(GetDeviceName(), LogTypes::WII_IPC_FILEIO, LogTypes::LERROR);
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
|
||||
request.SetReturnValue(return_value);
|
||||
return GetDefaultReply();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,34 +26,18 @@ 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();
|
||||
|
||||
IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override;
|
||||
IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override;
|
||||
IPCCommandResult Seek(u32 _CommandAddress) override;
|
||||
IPCCommandResult Read(u32 _CommandAddress) override;
|
||||
IPCCommandResult Write(u32 _CommandAddress) override;
|
||||
IPCCommandResult IOCtl(u32 _CommandAddress) override;
|
||||
void Close() override;
|
||||
IOSReturnCode Open(const IOSOpenRequest& request) override;
|
||||
IPCCommandResult Seek(const IOSSeekRequest& request) override;
|
||||
IPCCommandResult Read(const IOSReadWriteRequest& request) override;
|
||||
IPCCommandResult Write(const IOSReadWriteRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
|
||||
void PrepareForState(PointerWrap::Mode mode) override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
void OpenFile();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
ISFS_OPEN_READ = 1,
|
||||
ISFS_OPEN_WRITE = 2,
|
||||
ISFS_OPEN_RW = (ISFS_OPEN_READ | ISFS_OPEN_WRITE)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
WII_SEEK_SET = 0,
|
||||
WII_SEEK_CUR = 1,
|
||||
WII_SEEK_END = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ISFS_FUNCNULL = 0,
|
||||
|
|
|
@ -32,10 +32,6 @@ CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string&
|
|||
{
|
||||
}
|
||||
|
||||
CWII_IPC_HLE_Device_fs::~CWII_IPC_HLE_Device_fs()
|
||||
{
|
||||
}
|
||||
|
||||
// ~1/1000th of a second is too short and causes hangs in Wii Party
|
||||
// Play it safe at 1/500th
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const
|
||||
|
@ -43,7 +39,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const
|
|||
return {true, SystemTimers::GetTicksPerSecond() / 500};
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
|
||||
IOSReturnCode CWII_IPC_HLE_Device_fs::Open(const IOSOpenRequest& request)
|
||||
{
|
||||
// clear tmp folder
|
||||
{
|
||||
|
@ -53,7 +49,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
|
|||
}
|
||||
|
||||
m_is_active = true;
|
||||
return GetFSReply();
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
// Get total filesize of contents of a directory (recursive)
|
||||
|
@ -71,27 +67,20 @@ static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry)
|
|||
return sizeOfFiles;
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(const IOSIOCtlVRequest& request)
|
||||
{
|
||||
u32 ReturnValue = IPC_SUCCESS;
|
||||
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
||||
|
||||
// Prepare the out buffer(s) with zeros as a safety precaution
|
||||
// to avoid returning bad values
|
||||
for (const auto& buffer : CommandBuffer.PayloadBuffer)
|
||||
Memory::Memset(buffer.m_Address, 0, buffer.m_Size);
|
||||
|
||||
switch (CommandBuffer.Parameter)
|
||||
s32 return_value = IPC_SUCCESS;
|
||||
switch (request.request)
|
||||
{
|
||||
case IOCTLV_READ_DIR:
|
||||
{
|
||||
const std::string relative_path =
|
||||
Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size);
|
||||
Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
|
||||
if (!IsValidWiiPath(relative_path))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relative_path.c_str());
|
||||
ReturnValue = FS_EINVAL;
|
||||
return_value = FS_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -103,7 +92,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
if (!File::Exists(DirName))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str());
|
||||
ReturnValue = FS_ENOENT;
|
||||
return_value = FS_ENOENT;
|
||||
break;
|
||||
}
|
||||
else if (!File::IsDirectory(DirName))
|
||||
|
@ -112,19 +101,19 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
// Games don't usually seem to care WHICH error they get, as long as it's <
|
||||
// Well the system menu CARES!
|
||||
WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_EINVAL");
|
||||
ReturnValue = FS_EINVAL;
|
||||
return_value = FS_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
File::FSTEntry entry = File::ScanDirectoryTree(DirName, false);
|
||||
|
||||
// it is one
|
||||
if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1))
|
||||
if ((request.in_vectors.size() == 1) && (request.io_vectors.size() == 1))
|
||||
{
|
||||
size_t numFile = entry.children.size();
|
||||
INFO_LOG(WII_IPC_FILEIO, "\t%zu files found", numFile);
|
||||
|
||||
Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32((u32)numFile, request.io_vectors[0].address);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -140,13 +129,12 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
return one.virtualName < two.virtualName;
|
||||
});
|
||||
|
||||
u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address);
|
||||
u32 MaxEntries = Memory::Read_U32(request.in_vectors[0].address);
|
||||
|
||||
memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0,
|
||||
CommandBuffer.PayloadBuffer[0].m_Size);
|
||||
memset(Memory::GetPointer(request.io_vectors[0].address), 0, request.io_vectors[0].size);
|
||||
|
||||
size_t numFiles = 0;
|
||||
char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address));
|
||||
char* pFilename = (char*)Memory::GetPointer((u32)(request.io_vectors[0].address));
|
||||
|
||||
for (size_t i = 0; i < entry.children.size() && i < MaxEntries; i++)
|
||||
{
|
||||
|
@ -160,29 +148,29 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str());
|
||||
}
|
||||
|
||||
Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address);
|
||||
Memory::Write_U32((u32)numFiles, request.io_vectors[1].address);
|
||||
}
|
||||
|
||||
ReturnValue = IPC_SUCCESS;
|
||||
return_value = IPC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTLV_GETUSAGE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2);
|
||||
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4);
|
||||
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.io_vectors.size() == 2);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.io_vectors[0].size == 4);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.io_vectors[1].size == 4);
|
||||
|
||||
// this command sucks because it asks of the number of used
|
||||
// fsBlocks and inodes
|
||||
// It should be correct, but don't count on it...
|
||||
std::string relativepath =
|
||||
Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size);
|
||||
Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
|
||||
if (!IsValidWiiPath(relativepath))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relativepath.c_str());
|
||||
ReturnValue = FS_EINVAL;
|
||||
return_value = FS_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -214,7 +202,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
|
||||
fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb
|
||||
}
|
||||
ReturnValue = IPC_SUCCESS;
|
||||
return_value = IPC_SUCCESS;
|
||||
|
||||
INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes);
|
||||
}
|
||||
|
@ -222,54 +210,39 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
{
|
||||
fsBlocks = 0;
|
||||
iNodes = 0;
|
||||
ReturnValue = IPC_SUCCESS;
|
||||
return_value = IPC_SUCCESS;
|
||||
WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directory: %s", path.c_str());
|
||||
}
|
||||
|
||||
Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address);
|
||||
Memory::Write_U32(fsBlocks, request.io_vectors[0].address);
|
||||
Memory::Write_U32(iNodes, request.io_vectors[1].address);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
|
||||
request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO);
|
||||
break;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 4);
|
||||
|
||||
request.SetReturnValue(return_value);
|
||||
return GetFSReply();
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress)
|
||||
IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(const IOSIOCtlRequest& request)
|
||||
{
|
||||
// u32 DeviceID = Memory::Read_U32(_CommandAddress + 8);
|
||||
|
||||
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);
|
||||
|
||||
/* Prepare the out buffer(s) with zeroes as a safety precaution
|
||||
to avoid returning bad values. */
|
||||
// LOG(WII_IPC_FILEIO, "Cleared %u bytes of the out buffer", _BufferOutSize);
|
||||
Memory::Memset(BufferOut, 0, BufferOutSize);
|
||||
|
||||
u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 4);
|
||||
|
||||
Memory::Memset(request.buffer_out, 0, request.buffer_out_size);
|
||||
const s32 return_value = ExecuteCommand(request);
|
||||
request.SetReturnValue(return_value);
|
||||
return GetFSReply();
|
||||
}
|
||||
|
||||
s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize,
|
||||
u32 _BufferOut, u32 _BufferOutSize)
|
||||
s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(const IOSIOCtlRequest& request)
|
||||
{
|
||||
switch (_Parameter)
|
||||
switch (request.request)
|
||||
{
|
||||
case IOCTL_GET_STATS:
|
||||
{
|
||||
if (_BufferOutSize < 0x1c)
|
||||
if (request.buffer_out_size < 0x1c)
|
||||
return -1017;
|
||||
|
||||
WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now");
|
||||
|
@ -285,7 +258,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
fs.Free_INodes = 0x146B;
|
||||
fs.Used_Inodes = 0x0394;
|
||||
|
||||
std::memcpy(Memory::GetPointer(_BufferOut), &fs, sizeof(NANDStat));
|
||||
std::memcpy(Memory::GetPointer(request.buffer_out), &fs, sizeof(NANDStat));
|
||||
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
@ -293,8 +266,8 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_CREATE_DIR:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
u32 Addr = _BufferIn;
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0);
|
||||
u32 Addr = request.buffer_in;
|
||||
|
||||
u32 OwnerID = Memory::Read_U32(Addr);
|
||||
Addr += 4;
|
||||
|
@ -325,7 +298,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_SET_ATTR:
|
||||
{
|
||||
u32 Addr = _BufferIn;
|
||||
u32 Addr = request.buffer_in;
|
||||
|
||||
u32 OwnerID = Memory::Read_U32(Addr);
|
||||
Addr += 4;
|
||||
|
@ -362,14 +335,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_GET_ATTR:
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76,
|
||||
_dbg_assert_msg_(WII_IPC_FILEIO, request.buffer_out_size == 76,
|
||||
" GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large",
|
||||
_BufferOutSize);
|
||||
request.buffer_out_size);
|
||||
|
||||
u32 OwnerID = 0;
|
||||
u16 GroupID = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08
|
||||
// (0x3038) for MH3 etc
|
||||
const std::string wii_path = Memory::GetString(_BufferIn, 64);
|
||||
const std::string wii_path = Memory::GetString(request.buffer_in, 64);
|
||||
if (!IsValidWiiPath(wii_path))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str());
|
||||
|
@ -400,14 +373,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
}
|
||||
|
||||
// write answer to buffer
|
||||
if (_BufferOutSize == 76)
|
||||
if (request.buffer_out_size == 76)
|
||||
{
|
||||
u32 Addr = _BufferOut;
|
||||
u32 Addr = request.buffer_out;
|
||||
Memory::Write_U32(OwnerID, Addr);
|
||||
Addr += 4;
|
||||
Memory::Write_U16(GroupID, Addr);
|
||||
Addr += 2;
|
||||
memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64);
|
||||
memcpy(Memory::GetPointer(Addr), Memory::GetPointer(request.buffer_in), 64);
|
||||
Addr += 64;
|
||||
Memory::Write_U8(OwnerPerm, Addr);
|
||||
Addr += 1;
|
||||
|
@ -425,10 +398,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_DELETE_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0);
|
||||
int Offset = 0;
|
||||
|
||||
const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64);
|
||||
const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64);
|
||||
if (!IsValidWiiPath(wii_path))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str());
|
||||
|
@ -455,10 +428,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_RENAME_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0);
|
||||
int Offset = 0;
|
||||
|
||||
const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64);
|
||||
const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64);
|
||||
if (!IsValidWiiPath(wii_path))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str());
|
||||
|
@ -467,7 +440,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
std::string Filename = HLE_IPC_BuildFilename(wii_path);
|
||||
Offset += 64;
|
||||
|
||||
const std::string wii_path_rename = Memory::GetString(_BufferIn + Offset, 64);
|
||||
const std::string wii_path_rename = Memory::GetString(request.buffer_in + Offset, 64);
|
||||
if (!IsValidWiiPath(wii_path_rename))
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path_rename.c_str());
|
||||
|
@ -503,9 +476,9 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
|
||||
case IOCTL_CREATE_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
_dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0);
|
||||
|
||||
u32 Addr = _BufferIn;
|
||||
u32 Addr = request.buffer_in;
|
||||
u32 OwnerID = Memory::Read_U32(Addr);
|
||||
Addr += 4;
|
||||
u16 GroupID = Memory::Read_U16(Addr);
|
||||
|
@ -563,9 +536,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
}
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter);
|
||||
PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter);
|
||||
break;
|
||||
request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO);
|
||||
}
|
||||
|
||||
return FS_EINVAL;
|
||||
|
|
|
@ -27,14 +27,12 @@ class CWII_IPC_HLE_Device_fs : public IWII_IPC_HLE_Device
|
|||
{
|
||||
public:
|
||||
CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName);
|
||||
virtual ~CWII_IPC_HLE_Device_fs();
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override;
|
||||
|
||||
IPCCommandResult IOCtl(u32 _CommandAddress) override;
|
||||
IPCCommandResult IOCtlV(u32 _CommandAddress) override;
|
||||
IOSReturnCode Open(const IOSOpenRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
|
@ -52,6 +50,5 @@ private:
|
|||
};
|
||||
|
||||
IPCCommandResult GetFSReply() const;
|
||||
s32 ExecuteCommand(u32 Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut,
|
||||
u32 _BufferOutSize);
|
||||
s32 ExecuteCommand(const IOSIOCtlRequest& request);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue