diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h
index 1062b20767..6966191cc4 100644
--- a/Source/Core/Common/Src/Common.h
+++ b/Source/Core/Common/Src/Common.h
@@ -218,6 +218,7 @@ class LogTypes
WII_IPC_DVD,
WII_IPC_ES,
WII_IPC_FILEIO,
+ WII_IPC_NET,
WII_IPC_WIIMOTE,
NUMBER_OF_LOGS
};
diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp
index bc141a5517..7660aeb824 100644
--- a/Source/Core/Common/Src/FileUtil.cpp
+++ b/Source/Core/Common/Src/FileUtil.cpp
@@ -148,6 +148,21 @@ bool CreateDir(const char *path)
#endif
}
+bool DeleteDir(const char *filename)
+{
+#ifdef _WIN32
+ if (!File::IsDirectory(filename))
+ return false;
+
+ return ::RemoveDirectory (filename) ? true : false;
+#else
+
+ PanicAlert("File::DeleteDir() not implemented");
+ return false;
+
+#endif
+}
+
std::string GetUserDirectory()
{
#ifdef _WIN32
@@ -254,4 +269,61 @@ bool CreateEmptyFile(const char *filename)
return true;
}
+
+bool DeleteDirRecursively(const std::string& _Directory)
+{
+#ifdef _WIN32
+
+ bool Result = false;
+
+ WIN32_FIND_DATA ffd;
+ std::string searchName = _Directory + "\\*";
+ HANDLE hFind = FindFirstFile(searchName.c_str(), &ffd);
+
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ // check for "." and ".."
+ if (((ffd.cFileName[0] == '.') && (ffd.cFileName[1] == 0x00)) ||
+ ((ffd.cFileName[0] == '.') && (ffd.cFileName[1] == '.') && (ffd.cFileName[2] == 0x00)))
+ continue;
+
+ // build path
+ std::string newPath(_Directory);
+ newPath += '\\';
+ newPath += ffd.cFileName;
+
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ if (!File::DeleteDirRecursively(newPath))
+ goto error_jmp;
+ }
+ else
+ {
+ if (!File::Delete(newPath.c_str()))
+ goto error_jmp;
+ }
+
+ } while (FindNextFile(hFind, &ffd) != 0);
+ }
+
+ if (!File::DeleteDir(_Directory.c_str()))
+ goto error_jmp;
+
+ Result = true;
+
+error_jmp:
+
+ FindClose(hFind);
+
+ return Result;
+#else
+
+ PanicAlert("File::DeleteDirRecursively() not implemented");
+ return false;
+
+#endif
+}
+
} // namespace
diff --git a/Source/Core/Common/Src/FileUtil.h b/Source/Core/Common/Src/FileUtil.h
index 42fd731b37..778846d4a6 100644
--- a/Source/Core/Common/Src/FileUtil.h
+++ b/Source/Core/Common/Src/FileUtil.h
@@ -42,12 +42,15 @@ void Explore(const char *path);
bool IsDirectory(const char *filename);
bool CreateDir(const char *filename);
bool Delete(const char *filename);
+bool DeleteDir(const char *filename);
u64 GetSize(const char *filename);
std::string GetUserDirectory();
bool CreateEmptyFile(const char *filename);
u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry);
+bool DeleteDirRecursively(const std::string& _Directory);
+
} // namespace
#endif
diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj
index 71c21b6b1c..13fd3691f9 100644
--- a/Source/Core/Core/Core.vcproj
+++ b/Source/Core/Core/Core.vcproj
@@ -1111,6 +1111,10 @@
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_fs.h"
>
+
+
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 4c08639f3c..9653fbcff2 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -139,6 +139,10 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName
{
pDevice = new CWII_IPC_HLE_Device_net_kd_time(_DeviceID, _rDeviceName);
}
+ else if (_rDeviceName.c_str() == std::string("/dev/net/ncd/manage"))
+ {
+ pDevice = new CWII_IPC_HLE_Device_net_ncd_manage(_DeviceID, _rDeviceName);
+ }
else if (_rDeviceName.c_str() == std::string("/dev/es"))
{
pDevice = new CWII_IPC_HLE_Device_es(_DeviceID, _rDeviceName);
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 d88c636a6e..b777a9a05a 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
@@ -71,6 +71,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
const char Modes[][128] =
{
+ { "Unk Mode" },
{ "Read only" },
{ "Write only" },
{ "Read and Write" }
@@ -98,6 +99,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
}
else
{
+ LOG(WII_IPC_FILEIO, " failed - File doesn't exist");
ReturnValue = -106;
}
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
index 7e79b83a3c..cb001a7d9e 100644
--- 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
@@ -16,13 +16,14 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
+
+#include "WII_IPC_HLE_Device_fs.h"
+
#include "StringUtil.h"
#include "FileSearch.h"
#include "FileUtil.h"
-#include "WII_IPC_HLE_Device_fs.h"
-
-
+#include "../VolumeHandler.h"
extern std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
@@ -43,18 +44,33 @@ 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++)
+ // clear tmp folder
{
- if (rFilenames[i].c_str()[0] != '.')
- remove(rFilenames[i].c_str());
+ std::string WiiTempFolder("Wii/tmp");
+ bool Result = File::DeleteDirRecursively(WiiTempFolder.c_str());
+ if (Result == false)
+ {
+ PanicAlert("Cant delete Wii Temp folder");
+ }
+ File::CreateDir(WiiTempFolder.c_str());
+ }
+
+ // create home directory
+ {
+ u32 TitleID = VolumeHandler::Read32(0);
+ if (TitleID == 0)
+ TitleID = 0xF00DBEEF;
+
+ char* pTitleID = (char*)&TitleID;
+
+ char Path[260+1];
+ sprintf(Path, "Wii/title/00010000/%02x%02x%02x%02x", (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]);
+ if (!File::IsDirectory(Path))
+ {
+ File::CreateDir(Path);
+ sprintf(Path, "Wii/title/00010000/%02x%02x%02x%02x/data", (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]);
+ File::CreateDir(Path);
+ }
}
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
@@ -146,18 +162,47 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
case IOCTL_GETUSAGE:
{
+ // check buffer sizes
+ _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);
+
// 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), CommandBuffer.InBuffer[0].m_Size));
+ u32 fsBlock = 0;
+ u32 iNodes = 0;
LOG(WII_IPC_FILEIO, "FS: IOCTL_GETUSAGE %s", Filename.c_str());
+ if (File::IsDirectory(Filename.c_str()))
+ {
+ // make a file search
+ CFileSearch::XStringVector Directories;
+ Directories.push_back(Filename);
- Memory::Write_U32(0, CommandBuffer.PayloadBuffer[0].m_Address);
- Memory::Write_U32(0, CommandBuffer.PayloadBuffer[1].m_Address);
+ CFileSearch::XStringVector Extensions;
+ Extensions.push_back("*.*");
- ReturnValue = 0;
+ CFileSearch FileSearch(Extensions, Directories);
+ fsBlock = (u32)FileSearch.GetFileNames().size();
+ iNodes = fsBlock * 10;
+
+ ReturnValue = 0;
+
+ LOG(WII_IPC_FILEIO, " fsBlock: %i, iNodes: %i", fsBlock, iNodes);
+ }
+ else
+ {
+ fsBlock = 0;
+ iNodes = 0;
+ ReturnValue = 0;
+ LOG(WII_IPC_FILEIO, " error: not executed on a valid directoy: %s", Filename.c_str());
+ }
+
+ Memory::Write_U32(fsBlock, CommandBuffer.PayloadBuffer[0].m_Address);
+ Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address);
}
break;
@@ -212,8 +257,8 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
u16 GroupID = 0;
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64);
u8 OwnerPerm = 0;
- u8 GroupPerm = 0;
- u8 OtherPerm = 0;
+ u8 GroupPerm = 0;
+ u8 OtherPerm = 0;
u8 Attributes = 0;
if (File::IsDirectory(Filename.c_str()))
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp
new file mode 100644
index 0000000000..969fd2bd93
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp
@@ -0,0 +1,97 @@
+// 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 "WII_IPC_HLE_Device_net.h"
+
+CWII_IPC_HLE_Device_net_kd_request::CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName)
+ : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+{
+}
+
+CWII_IPC_HLE_Device_net_kd_request::~CWII_IPC_HLE_Device_net_kd_request()
+{
+
+}
+
+bool CWII_IPC_HLE_Device_net_kd_request::Open(u32 _CommandAddress, u32 _Mode)
+{
+ Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
+{
+ LOG(WII_IPC_NET, "NET_KD_REQ: 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;
+}
+
+s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize)
+{
+ switch(_Parameter)
+ {
+ default:
+ LOG(WII_IPC_NET, "CWII_IPC_HLE_Device_net_kd_request::IOCtl: ni 0x%x (iBufferSize: %i, oBufferSize: %i)", _Parameter, _BufferInSize, _BufferOutSize);
+ _dbg_assert_msg_(WII_IPC_NET, 0, "CWII_IPC_HLE_Device_net_kd_request::IOCtl: ni 0x%x (iBufferSize: %i, oBufferSize: %i)", _Parameter, _BufferInSize, _BufferOutSize);
+ break;
+ }
+ return 0;
+}
+
+// **********************************************************************************
+
+CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _DeviceID, const std::string& _rDeviceName)
+ : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+{}
+
+CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
+{}
+
+bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
+{
+ Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
+ return true;
+}
+
+
+bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
+{
+ u32 ReturnValue = 0;
+
+ SIOCtlVBuffer CommandBuffer(_CommandAddress);
+
+ switch(CommandBuffer.Parameter)
+ {
+ default:
+ LOG(WII_IPC_NET, "CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
+ _dbg_assert_msg_(WII_IPC_NET, 0, "CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
+ break;
+ }
+
+ Memory::Write_U32(ReturnValue, _CommandAddress+4);
+
+ return true;
+}
\ No newline at end of file
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 16f99e638c..756497c95a 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
@@ -14,6 +14,7 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
+
#ifndef _WII_IPC_HLE_DEVICE_NET_H_
#define _WII_IPC_HLE_DEVICE_NET_H_
@@ -23,21 +24,21 @@ class CWII_IPC_HLE_Device_net_kd_request : public IWII_IPC_HLE_Device
{
public:
- CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName) :
- IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
- {}
+ CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName);
- virtual ~CWII_IPC_HLE_Device_net_kd_request()
- {}
+ virtual ~CWII_IPC_HLE_Device_net_kd_request();
- virtual bool Open(u32 _CommandAddress, u32 _Mode)
- {
- Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
+ virtual bool Open(u32 _CommandAddress, u32 _Mode);
- return true;
- }
+ virtual bool IOCtl(u32 _CommandAddress);
+
+private:
+
+ s32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
};
+// **************************************************************************************
+
class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device
{
public:
@@ -80,6 +81,8 @@ public:
}
};
+// **************************************************************************************
+
class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device
{
public:
@@ -98,4 +101,19 @@ public:
};
+// **************************************************************************************
+
+class CWII_IPC_HLE_Device_net_ncd_manage : public IWII_IPC_HLE_Device
+{
+public:
+ CWII_IPC_HLE_Device_net_ncd_manage(u32 _DeviceID, const std::string& _rDeviceName);
+
+ virtual ~CWII_IPC_HLE_Device_net_ncd_manage();
+
+ virtual bool Open(u32 _CommandAddress, u32 _Mode);
+
+ virtual bool IOCtlV(u32 _CommandAddress);
+
+};
+
#endif
diff --git a/Source/Core/Core/Src/LogManager.cpp b/Source/Core/Core/Src/LogManager.cpp
index 8916347a42..7998e42b01 100644
--- a/Source/Core/Core/Src/LogManager.cpp
+++ b/Source/Core/Core/Src/LogManager.cpp
@@ -117,6 +117,7 @@ void LogManager::Init()
m_Log[LogTypes::WII_IPC_DVD] = new CDebugger_Log("WII_IPC_DVD", "WII IPC DVD");
m_Log[LogTypes::WII_IPC_ES] = new CDebugger_Log("WII_IPC_ES", "WII IPC ES");
m_Log[LogTypes::WII_IPC_FILEIO] = new CDebugger_Log("WII_IPC_FILEIO", "WII IPC FILEIO");
+ m_Log[LogTypes::WII_IPC_NET] = new CDebugger_Log("WII_IPC_NET", "WII IPC NET");
m_Log[LogTypes::WII_IPC_WIIMOTE] = new CDebugger_Log("WII_IPC_WIIMOTE", "WII IPC WIIMOTE");
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)