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