From 2d2a91b532f13a65a2fa6a59684f89737fb5f1f0 Mon Sep 17 00:00:00 2001 From: "fires.gc" Date: Fri, 31 Oct 2008 22:31:24 +0000 Subject: [PATCH] added support for IPC file system. i am sure it will break linux and osx builds and prolly we have to talk how we can do our file handling at all. perhaps we have to define an interface for file accesses. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1028 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Common.vcproj | 8 + .../{DolphinWX => Common}/Src/FileSearch.cpp | 2 +- .../{DolphinWX => Common}/Src/FileSearch.h | 0 Source/Core/Core/Core.vcproj | 6 +- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 37 +-- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device.h | 2 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 44 ++- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h | 2 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_Error.h | 2 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 87 ++++-- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 3 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h | 4 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 250 ++++++++++++++++++ .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h | 35 ++- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h | 6 +- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp | 2 +- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h | 2 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h | 4 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 2 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h | 2 +- 20 files changed, 401 insertions(+), 99 deletions(-) rename Source/Core/{DolphinWX => Common}/Src/FileSearch.cpp (94%) rename Source/Core/{DolphinWX => Common}/Src/FileSearch.h (100%) create mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj index e9eb4df63f..887faa963c 100644 --- a/Source/Core/Common/Common.vcproj +++ b/Source/Core/Common/Common.vcproj @@ -514,6 +514,14 @@ RelativePath=".\Src\ExtendedTrace.h" > + + + + diff --git a/Source/Core/DolphinWX/Src/FileSearch.cpp b/Source/Core/Common/Src/FileSearch.cpp similarity index 94% rename from Source/Core/DolphinWX/Src/FileSearch.cpp rename to Source/Core/Common/Src/FileSearch.cpp index 7ea9974235..6ada69d79b 100644 --- a/Source/Core/DolphinWX/Src/FileSearch.cpp +++ b/Source/Core/Common/Src/FileSearch.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "Globals.h" +#include "Common.h" #ifndef _WIN32 #include #include diff --git a/Source/Core/DolphinWX/Src/FileSearch.h b/Source/Core/Common/Src/FileSearch.h similarity index 100% rename from Source/Core/DolphinWX/Src/FileSearch.h rename to Source/Core/Common/Src/FileSearch.h diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index b651293371..71c21b6b1c 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -1,7 +1,7 @@ + + diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index d476d38aa3..4c08639f3c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "Common.h" #include "WII_IPC_HLE.h" @@ -164,22 +165,28 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName return pDevice; } -std::queue m_Ack; +std::list m_Ack; std::queue > m_ReplyQueue; void ExecuteCommand(u32 _Address); bool AckCommand(u32 _Address) { -/* static u32 Count = 0; - LOG(WII_IPC_HLE, "AckAdd: %i", Count); - if (Count == 63) - CCPU::Break(); - Count++; */ + Debugger::PrintCallstack(LogTypes::WII_IPC_HLE); + LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address); -// Debugger::PrintCallstack(LogTypes::WII_IPC_HLE); -// LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address); + std::list::iterator itr = m_Ack.begin(); + while (itr != m_Ack.end()) + { + if (*itr == _Address) + { + PanicAlert("execute a command two times"); + return false; + } - m_Ack.push(_Address); + itr++; + } + + m_Ack.push_back(_Address); return true; } @@ -214,10 +221,8 @@ void ExecuteCommand(u32 _Address) // HLE - Create a new HLE device std::string DeviceName; Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC)); -#ifdef LOGGING + u32 Mode = Memory::Read_U32(_Address+0x10); -#endif - u32 DeviceID = GetDeviceIDByName(DeviceName); if (DeviceID == 0) { @@ -229,7 +234,7 @@ void ExecuteCommand(u32 _Address) g_DeviceMap[CurrentDeviceID] = pDevice; g_LastDeviceID++; - GenerateReply = pDevice->Open(_Address); + GenerateReply = pDevice->Open(_Address, Mode); LOG(WII_IPC_HLE, "IOP: Open (Device=%s, Mode=%i)", pDevice->GetDeviceName().c_str(), Mode); } else @@ -327,7 +332,6 @@ void ExecuteCommand(u32 _Address) if (g_DeviceMap.find(DeviceID) != g_DeviceMap.end()) pDevice = g_DeviceMap[DeviceID]; - if (pDevice != NULL) m_ReplyQueue.push(std::pair(_Address, pDevice->GetDeviceName())); else @@ -335,7 +339,6 @@ void ExecuteCommand(u32 _Address) } } -// Update void Update() { if (WII_IPCInterface::IsReady()) @@ -361,12 +364,10 @@ void Update() return; } - - if (m_ReplyQueue.empty() && !m_Ack.empty()) { u32 _Address = m_Ack.front(); - m_Ack.pop(); + m_Ack.pop_front(); ExecuteCommand(_Address); LOG(WII_IPC_HLE, "-- Generate Ack (0x%08x)", _Address); WII_IPCInterface::GenerateAck(_Address); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h index 4bf83479e5..59cd542c97 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h @@ -37,7 +37,7 @@ public: const std::string& GetDeviceName() const { return m_Name; } u32 GetDeviceID() const { return m_DeviceID; } - virtual bool Open(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Open()", m_Name.c_str()); return true; } + virtual bool Open(u32 _CommandAddress, u32 _Mode) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Open()", m_Name.c_str()); return true; } virtual bool Close(u32 _CommandAddress) { /*_dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); */ return true; } virtual bool Seek(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Seek()", m_Name.c_str()); return true; } virtual bool Read(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Read()", m_Name.c_str()); return true; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index e7e67f1665..e832a2de3c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -28,9 +28,6 @@ #include "VolumeCreator.h" #include "Filesystem.h" -// Hack -u8 coverByte = 0; - CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName ) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) @@ -48,7 +45,7 @@ CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di() delete m_pVolume; } -bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress) +bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; @@ -60,10 +57,6 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtl"); LOG(WII_IPC_DVD, "*******************************"); - // DumpCommands(_CommandAddress); - - // u32 Cmd = Memory::Read_U32(_CommandAddress + 0xC); - // TODO: Use Cmd for something? u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); @@ -75,14 +68,6 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize); Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); -/* DumpCommands(_CommandAddress); - - LOG(WII_IPC_DVD, "InBuffer"); - DumpCommands(BufferIn, BufferInSize); - -// LOG(WII_IPC_DVD, "OutBuffer"); - // DumpCommands(BufferOut, BufferOutSize); */ - return true; } @@ -139,11 +124,7 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 } break; - // DVDLowRead - // TODO - find out if 80, 8d, or and d0 need to do something specific - case 0x80: - case 0x8d: - case 0xd0: + // DVDLowRead case 0x71: { u32 Size = Memory::Read_U32(_BufferIn + 0x04); @@ -186,7 +167,12 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 // DVDLowGetCoverReg - called by "Legend of Spyro" case 0x7a: { - // HACK - swiching the 4th byte between 0 and 1 gets through this check + LOG(WII_IPC_DVD, "%s executes DVDLowGetCoverReg (Buffer 0x%08x, 0x%x)", GetDeviceName().c_str(), _BufferOut, _BufferOutSize); + + // HACK - switching the 4th byte between 0 and 1 gets through this check + + static u8 coverByte = 0; + Memory::Memset(_BufferOut, 0, _BufferOutSize); u8* buffer = Memory::GetPointer(_BufferOut); @@ -227,12 +213,20 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 } break; + // DVDLowOpenPartition + case 0x8b: + PanicAlert("DVDLowOpenPartition", Command); + break; + + + // DVDLowUnencryptedRead + case 0x8d: + PanicAlert("DVDLowUnencryptedRead"); + break; // DVDLowSeek case 0xab: - { - // PanicAlert("DVDLowSeek"); - } + // PanicAlert("DVDLowSeek"); break; // DVDLowStopMotor diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h index 10b19b3415..48d81a89c6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h @@ -33,7 +33,7 @@ public: virtual ~CWII_IPC_HLE_Device_di(); - bool Open(u32 _CommandAddress); + bool Open(u32 _CommandAddress, u32 _Mode); bool IOCtl(u32 _CommandAddress); bool IOCtlV(u32 _CommandAddress); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h index 7def24e083..54793ca81c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h @@ -30,7 +30,7 @@ public: virtual ~CWII_IPC_HLE_Device_Error() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; 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 678315a824..587f8aaf13 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 @@ -19,14 +19,11 @@ #include "WII_IPC_HLE_Device_FileIO.h" -// smash bros writes to /shared2/sys/SYSCONF - CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName ) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) , m_pFileHandle(NULL) , m_FileLength(0) - , m_Seek(0) { } @@ -46,39 +43,73 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress) return true; } -bool -CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress) -{ - std::string Filename("WII"); - Filename += GetDeviceName(); +std::string HLE_IPC_BuildFilename(const char* _pFilename) +{ + std::string Filename("WII"); + if (_pFilename[1] == '0') + Filename += std::string("/title"); // this looks and feel like an hack... + Filename += std::string (_pFilename); - m_Filename = Filename; - m_pFileHandle = fopen(Filename.c_str(), "r+b"); + return Filename; +} + +bool +CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) +{ + u32 ReturnValue = 0; + + LOG(WII_IPC_FILEIO, "FileIO: Open (Device=%s)", GetDeviceName().c_str()); + + m_Filename = (HLE_IPC_BuildFilename(GetDeviceName().c_str())); + + switch(_Mode) + { + case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break; + case 0x02: m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break; + case 0x03: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break; + default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode"); break; + } if (m_pFileHandle != NULL) { fseek(m_pFileHandle, 0, SEEK_END); - m_FileLength = ftell(m_pFileHandle); + m_FileLength = (u32)ftell(m_pFileHandle); rewind(m_pFileHandle); + + ReturnValue = GetDeviceID(); } else { - //PanicAlert("CWII_IPC_HLE_Device_FileIO: cant open %s", Filename.c_str()); + ReturnValue = -106; } - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + Memory::Write_U32(ReturnValue, _CommandAddress+4); return true; } bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) { - LOG(WII_IPC_FILEIO, "FileIO: Seek (Device=%s)", GetDeviceName().c_str()); - DumpCommands(_CommandAddress); + u32 ReturnValue = 0; + u32 SeekPosition = Memory::Read_U32(_CommandAddress +0xC); + u32 Mode = Memory::Read_U32(_CommandAddress +0x10); - PanicAlert("CWII_IPC_HLE_Device_FileIO: Seek (%s)", m_Filename.c_str()); + LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: %i, Mode: %i(Device=%s)", SeekPosition, Mode, GetDeviceName().c_str()); + + switch(Mode) + { + case 0: + fseek(m_pFileHandle, SeekPosition, SEEK_SET); + ReturnValue = 0; + break; + + case 1: // cur + case 2: // end + default: + PanicAlert("CWII_IPC_HLE_Device_FileIO unsupported seek mode"); + break; + } - u32 ReturnValue = 1; Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); return true; @@ -110,12 +141,18 @@ CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) { - LOG(WII_IPC_FILEIO, "FileIO: Write (Device=%s)", GetDeviceName().c_str()); - DumpCommands(_CommandAddress); + u32 ReturnValue = 0; + u32 Address = Memory::Read_U32(_CommandAddress +0xC); + u32 Size = Memory::Read_U32(_CommandAddress +0x10); - // PanicAlert("CWII_IPC_HLE_Device_FileIO: Write (Device=%s)", GetDeviceName().c_str()); + LOG(WII_IPC_FILEIO, "FileIO: Write Addr: 0x%08x Size: %i (Device=%s)", Address, Size, GetDeviceName().c_str()); + + if (m_pFileHandle) + { + fwrite(Memory::GetPointer(Address), Size, 1, m_pFileHandle); + ReturnValue = Size; + } - u32 ReturnValue = 1; Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); return true; @@ -138,14 +175,14 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) { case ISFS_IOCTL_GETFILESTATS: { + u32 Position = ftell(m_pFileHandle); + u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS"); - LOG(WII_IPC_FILEIO, "Length: %i Seek: %i", m_FileLength, m_Seek); + LOG(WII_IPC_FILEIO, "Length: %i Seek: %i", m_FileLength, Position); Memory::Write_U32(m_FileLength, BufferOut); - Memory::Write_U32(m_Seek, BufferOut+4); - - PanicAlert("ISFS_IOCTL_GETFILESTATS: %s", m_Filename.c_str()); + Memory::Write_U32(Position, BufferOut+4); } break; 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 79d7552a69..80cf72257b 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 @@ -28,7 +28,7 @@ public: virtual ~CWII_IPC_HLE_Device_FileIO(); bool Close(u32 _CommandAddress); - bool Open(u32 _CommandAddress); + bool Open(u32 _CommandAddress, u32 _Mode); bool Seek(u32 _CommandAddress); bool Read(u32 _CommandAddress); bool Write(u32 _CommandAddress); @@ -64,7 +64,6 @@ private: FILE* m_pFileHandle; u32 m_FileLength; - u32 m_Seek; std::string m_Filename; }; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h index 0ff40facb8..82f575d660 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -64,7 +64,7 @@ public: virtual ~CWII_IPC_HLE_Device_es() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); @@ -87,7 +87,7 @@ public: char* pTitleID = (char*)&TitleID; char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - sprintf(Path, "/title/00010000/%02x%02x%02x%02x/data", (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]); + sprintf(Path, "/00010000/%02x%02x%02x%02x/data", (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]); LOG(WII_IPC_HLE, "CWII_IPC_HLE_Device_es command:" " IOCTL_ES_GETTITLEDIR: %s", Path); 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 new file mode 100644 index 0000000000..2d9a78e214 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -0,0 +1,250 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "StringUtil.h" +#include "FileSearch.h" + +#include "WII_IPC_HLE_Device_fs.h" + +#include + + + + +extern std::string HLE_IPC_BuildFilename(const char* _pFilename); + +#define FS_RESULT_OK (0) +#define FS_FILE_EXIST (-105) +#define FS_RESULT_FATAL (-128) + +CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName) + : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) +{} + +CWII_IPC_HLE_Device_fs::~CWII_IPC_HLE_Device_fs() +{} + +bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) +{ + CFileSearch::XStringVector Directories; + Directories.push_back("Wii/tmp"); + + CFileSearch::XStringVector Extensions; + Extensions.push_back("*.*"); + + CFileSearch FileSearch(Extensions, Directories); + const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); + for (u32 i = 0; i < rFilenames.size(); i++) + { + if (rFilenames[i].c_str()[0] != '.') + remove(rFilenames[i].c_str()); + } + + Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + return true; +} + +bool CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress) +{ + LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", GetDeviceName().c_str()); + + 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); + + u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); + Memory::Write_U32(ReturnValue, _CommandAddress+4); + + return true; +} + +bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) +{ + u32 ReturnValue = 0; + + SIOCtlVBuffer CommandBuffer(_CommandAddress); + + switch(CommandBuffer.Parameter) + { + case IOCTL_READ_DIR: + { + std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address))); + + if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1)) + { + LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s (dunno what i should return, number of FiLES?)", Filename.c_str()); + + Memory::Write_U32(0, CommandBuffer.PayloadBuffer[0].m_Address); + } + else + { + PanicAlert("IOCTL_READ_DIR with a lot of parameters"); + } + } + break; + + case IOCTL_GETUSAGE: + { + // this command sucks because it asks of the number of used + // fsBlocks and inodes + // we answer nothing is used, but if a program uses it to check + // how much memory has been used we are doomed... + std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address))); + + LOG(WII_IPC_FILEIO, "FS: IOCTL_GETUSAGE %s", Filename.c_str()); + + Memory::Write_U32(0, CommandBuffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(0, CommandBuffer.PayloadBuffer[1].m_Address); + } + break; + + + default: + PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter); + break; + } + + Memory::Write_U32(ReturnValue, _CommandAddress+4); + + return true; +} + + +s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) +{ + switch(_Parameter) + { + case DELETE_FILE: + { + int Offset = 0; + + std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset)); + Offset += 64; + if (remove(Filename.c_str()) == 0) + { + LOG(WII_IPC_FILEIO, "FS: DeleteFile %s", Filename.c_str()); + } + else + { + LOG(WII_IPC_FILEIO, "FS: DeleteFile %s - failed!!!", Filename.c_str()); + } + + return FS_RESULT_OK; + } + break; + + case RENAME_FILE: + { + int Offset = 0; + + std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset)); + Offset += 64; + + std::string FilenameRename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset)); + Offset += 64; + + if (rename(Filename.c_str(), FilenameRename.c_str()) == 0) + { + LOG(WII_IPC_FILEIO, "FS: Rename %s to %s", Filename.c_str(), FilenameRename.c_str()); + } + else + { + LOG(WII_IPC_FILEIO, "FS: Rename %s to %s - failed", Filename.c_str(), FilenameRename.c_str()); + PanicAlert("CWII_IPC_HLE_Device_fs: rename %s to %s failed", Filename.c_str(), FilenameRename.c_str()); + } + + return FS_RESULT_OK; + } + break; + + case CREATE_FILE: + { + u32 Addr = _BufferIn; + u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; + u16 GroupID = Memory::Read_U16(Addr); Addr += 2; + std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr))); + Addr += 64; + Addr += 9; // unk memory; + u8 Attribs = Memory::Read_U8(Addr); + + LOG(WII_IPC_FILEIO, "FS: CreateFile %s (attrib: 0x%02x)", Filename.c_str(), Attribs); + + FILE* pFileHandle = fopen(Filename.c_str(), "r+b"); + if (pFileHandle != NULL) + { + fclose(pFileHandle); + pFileHandle = NULL; + LOG(WII_IPC_FILEIO, " result = FS_RESULT_EXISTS", Filename.c_str(), Attribs); + + return FS_FILE_EXIST; + } + else + { + CreateDirectoryStruct(Filename); + + FILE* pFileHandle = fopen(Filename.c_str(), "w+b"); + if (!pFileHandle) + { + PanicAlert("CWII_IPC_HLE_Device_fs: couldn't create new file"); + return FS_RESULT_FATAL; + } + fclose(pFileHandle); + LOG(WII_IPC_FILEIO, " result = FS_RESULT_OK", Filename.c_str(), Attribs); + + return FS_RESULT_OK; + } + } + break; + + default: + PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); + break; + } + + return FS_RESULT_FATAL; +} + +void CWII_IPC_HLE_Device_fs::CreateDirectoryStruct(const std::string& _rFullPath) +{ + int PanicCounter = 10; + + size_t Position = 0; + while(true) + { + Position = _rFullPath.find('/', Position); + if (Position == std::string::npos) + break; + + Position++; + + std::string SubPath = _rFullPath.substr(0, Position); + if (!SubPath.empty()) + _mkdir(SubPath.c_str()); + + LOG(WII_IPC_FILEIO, " CreateSubDir %s", SubPath.c_str()); + + PanicCounter--; + if (PanicCounter <= 0) + { + PanicAlert("CreateDirectoryStruct creates way to much dirs..."); + break; + } + } +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h index 4b665e5bdd..5d9df6a576 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.h @@ -23,18 +23,10 @@ class CWII_IPC_HLE_Device_fs : public IWII_IPC_HLE_Device { public: - CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} + CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName); + virtual ~CWII_IPC_HLE_Device_fs(); - virtual ~CWII_IPC_HLE_Device_fs() - {} - - virtual bool Open(u32 _CommandAddress) - { - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); - return true; - } + virtual bool Open(u32 _CommandAddress, u32 _Mode); #if 0 virtual bool Close(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); return true; } @@ -42,8 +34,25 @@ public: virtual bool Read(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Read()", m_Name.c_str()); return true; } virtual bool Write(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Write()", m_Name.c_str()); return true; } #endif - virtual bool IOCtl(u32 _CommandAddress) { return true; } - virtual bool IOCtlV(u32 _CommandAddress) { return true; } + + virtual bool IOCtl(u32 _CommandAddress); + + virtual bool IOCtlV(u32 _CommandAddress); + +private: + + enum + { + IOCTL_READ_DIR = 0x04, + DELETE_FILE = 0x07, + RENAME_FILE = 0x08, + CREATE_FILE = 0x09, + IOCTL_GETUSAGE = 0x0C + }; + + s32 ExecuteCommand(u32 Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize); + + void CreateDirectoryStruct(const std::string& _rFullPath); }; #endif diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h index 6639a91ef2..16f99e638c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -30,7 +30,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_kd_request() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); @@ -49,7 +49,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_kd_time() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; @@ -90,7 +90,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_ip_top() { } - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index c96e310e1c..988951e04f 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -41,7 +41,7 @@ CWII_IPC_HLE_Device_sdio_slot0::~CWII_IPC_HLE_Device_sdio_slot0() // __________________________________________________________________________________________________ // bool -CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress) +CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress + 0x4); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h index 4d79ed95bc..f2e32dff86 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h @@ -36,7 +36,7 @@ public: virtual ~CWII_IPC_HLE_Device_sdio_slot0(); - bool Open(u32 _CommandAddress); + bool Open(u32 _CommandAddress, u32 _Mode); bool IOCtl(u32 _CommandAddress); bool IOCtlV(u32 _CommandAddress); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h index 8d1067ee37..8723fe9832 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -48,7 +48,7 @@ public: virtual ~CWII_IPC_HLE_Device_stm_immediate() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; @@ -111,7 +111,7 @@ public: virtual ~CWII_IPC_HLE_Device_stm_eventhook() {} - virtual bool Open(u32 _CommandAddress) + virtual bool Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index e5ccb4e876..6c552dbb08 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -59,7 +59,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De CWII_IPC_HLE_Device_usb_oh1_57e_305::~CWII_IPC_HLE_Device_usb_oh1_57e_305() {} -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress) +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode) { Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index aff1438654..662c680246 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -71,7 +71,7 @@ public: virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305(); - virtual bool Open(u32 _CommandAddress); + virtual bool Open(u32 _CommandAddress, u32 _Mode); virtual bool IOCtlV(u32 _CommandAddress); virtual bool IOCtl(u32 _CommandAddress);