diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 734d966781..7eb87d6f90 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -139,6 +139,7 @@ set(SRCS Src/ActionReplay.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp
+ Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp
@@ -192,7 +193,7 @@ set(SRCS Src/ActionReplay.cpp
Src/PowerPC/JitCommon/JitCache.cpp
Src/PowerPC/JitCommon/Jit_Util.cpp)
-set(LIBS bdisasm inputcommon videoogl videosoftware sfml-network)
+set(LIBS bdisasm inputcommon videoogl videosoftware sfml-network ssl)
if(WIN32)
set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 1e0561bc23..6b361b8793 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -115,7 +115,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -127,7 +127,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -139,7 +139,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -153,7 +153,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -167,7 +167,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -181,7 +181,7 @@
- .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)
+ .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;..\..\..\Externals\openssl\$(PlatformName);%(AdditionalIncludeDirectories)
true
@@ -327,6 +327,7 @@
+
@@ -518,6 +519,7 @@
+
@@ -528,6 +530,7 @@
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 66b25af176..e5d3df1d13 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -537,6 +537,9 @@
FifoPlayer
+
+ IPC HLE %28IOS/Starlet%29\Net
+
FifoPlayer
@@ -1030,8 +1033,11 @@
FifoPlayer
-
- HW %28Flipper/Hollywood%29\GCMemcard
+
+ IPC HLE %28IOS/Starlet%29\Net
+
+
+ IPC HLE %28IOS/Starlet%29\Net
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 921d704a69..9c0991fb4f 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -46,6 +46,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC
#include "WII_IPC_HLE_Device_stm.h"
#include "WII_IPC_HLE_Device_fs.h"
#include "WII_IPC_HLE_Device_net.h"
+#include "WII_IPC_HLE_Device_net_ssl.h"
#include "WII_IPC_HLE_Device_es.h"
#include "WII_IPC_HLE_Device_usb.h"
#include "WII_IPC_HLE_Device_usb_kbd.h"
@@ -91,6 +92,7 @@ void Init()
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_time(i, std::string("/dev/net/kd/time")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ncd_manage(i, std::string("/dev/net/ncd/manage")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ip_top(i, std::string("/dev/net/ip/top")); i++;
+ g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ssl(i, std::string("/dev/net/ssl")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++;
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 36709a084f..c738a5379d 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
@@ -93,11 +93,11 @@ public:
virtual bool IsHardware() { return m_Hardware; }
virtual bool IsOpened() { return m_Active; }
-
+public:
+ std::string m_Name;
protected:
// STATE_TO_SAVE
- std::string m_Name;
u32 m_DeviceID;
bool m_Hardware;
bool m_Active;
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 c2ed0fac36..c69ee15919 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
@@ -348,7 +348,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
_BufferOutSize);
u32 OwnerID = 0;
- u16 GroupID = 0;
+ u16 GroupID = 0x3031;
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64);
u8 OwnerPerm = 0x3; // read/write
u8 GroupPerm = 0x3; // read/write
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
index 75db39b994..711cd51677 100644
--- 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
@@ -22,19 +22,19 @@ it's used by for example SSBB, Mario Kart, Metroid Prime 3
0x01 SuspendScheduler (Input: none, Output: 32 bytes)
0x02 ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes) // Sounds like it will
- check if it should suspend the updates scheduler or not. If I returned
- (OutBuffer: 0, Ret: -1) to Metroid Prime 3 it got stuck in an endless loops of
- requests, probably harmless but I changed it to (OutBuffer: 1, Ret: 0) to stop
- the calls. However then it also calls 0x3 and then changes its error message
- to a Wii Memory error message from just a general Error message.
+check if it should suspend the updates scheduler or not. If I returned
+(OutBuffer: 0, Ret: -1) to Metroid Prime 3 it got stuck in an endless loops of
+requests, probably harmless but I changed it to (OutBuffer: 1, Ret: 0) to stop
+the calls. However then it also calls 0x3 and then changes its error message
+to a Wii Memory error message from just a general Error message.
0x03 ? (Input: none, Output: 32 bytes) // This is only called if 0x02
- does not return -1
+does not return -1
0x0f NWC24iRequestGenerateUserId (Input: none, Output: 32 bytes)
Requests are made in this order by these games
- Mario Kart: 2, 1, f, 3
- SSBB: 2, 3
+Mario Kart: 2, 1, f, 3
+SSBB: 2, 3
For Mario Kart I had to return -1 from at least 2, f and 3 to convince it that the network
was unavailable and prevent if from looking for shared2/wc24 files (and do a PPCHalt when
@@ -42,30 +42,45 @@ it failed)
*/
#ifdef _MSC_VER
-#pragma warning(disable : 4065) // switch statement contains 'default' but no 'case' labels
+#pragma warning(disable: 4748)
+#pragma optimize("",off)
#endif
#include "WII_IPC_HLE_Device_net.h"
#include "FileUtil.h"
#include
#include
+
#ifdef _WIN32
#include
#include
+#include
+
+#include "fakepoll.h"
+#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
+#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
+
#elif defined(__linux__)
+#include
+#include
#include
#include
#include
+#include
#include
#include
+#include
#else
#include
#include
+#include
#include
+#include
#endif
extern std::queue > g_ReplyQueueLater;
-
+const u8 default_address[] = { 0x00, 0x17, 0xAB, 0x99, 0x99, 0x99 };
+int status = 3;
// **********************************************************************************
// Handle /dev/net/kd/request requests
CWII_IPC_HLE_Device_net_kd_request::CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName)
@@ -116,14 +131,20 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR - NI");
break;
- case IOCTL_NWC24_UNK_3: // NWC24iResumeForCloseLib
- INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_UNK_3 - NI");
+ case IOCTL_NWC24_EXEC_RESUME_SCHEDULAR : // NWC24iResumeForCloseLib
+ INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULAR - NI");
break;
case IOCTL_NWC24_STARTUP_SOCKET: // NWC24iStartupSocket
+ Memory::Write_U32(0, BufferOut);
+ Memory::Write_U32(0, BufferOut+4);
+ ReturnValue = 0;
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI");
break;
-
+ case IOCTL_NWC24_CLEANUP_SOCKET:
+ Memory::Memset(BufferOut, 0, BufferOutSize);
+ INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_CLEANUP_SOCKET - NI");
+ break;
case IOCTL_NWC24_LOCK_SOCKET: // WiiMenu
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_LOCK_SOCKET - NI");
break;
@@ -134,7 +155,11 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes)
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID");
- memcpy(Memory::GetPointer(BufferOut), m_UserID.c_str(), m_UserID.length() + 1);
+ Memory::Write_U32(0xFFFFFFDC, BufferOut);
+ Memory::Write_U32(0x00050495, BufferOut + 4);
+ Memory::Write_U32(0x90CFBF35, BufferOut + 8);
+ Memory::Write_U32(0x00000002, BufferOut + 0xC);
+ //Memory::WriteBigEData((u8*)m_UserID.c_str(), BufferOut, m_UserID.length() + 1);
break;
case IOCTL_NWC24_GET_SCHEDULAR_STAT:
@@ -178,8 +203,8 @@ CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _Devi
// wired connection on IP 192.168.1.1 using gateway 192.168.1.2
memset(&m_Ifconfig, 0, sizeof(m_Ifconfig));
- m_Ifconfig.header4 = 1; // got one "valid" connection
- m_Ifconfig.header6 = 7; // this is always 7?
+ m_Ifconfig.connType = 1;
+ m_Ifconfig.linkTimeout = 7;
m_Ifconfig.connection[0].flags = 167;
m_Ifconfig.connection[0].ip[0] = 192;
m_Ifconfig.connection[0].ip[1] = 168;
@@ -188,11 +213,50 @@ CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _Devi
m_Ifconfig.connection[0].netmask[0] = 255;
m_Ifconfig.connection[0].netmask[1] = 255;
m_Ifconfig.connection[0].netmask[2] = 255;
- m_Ifconfig.connection[0].netmask[3] = 255;
+ m_Ifconfig.connection[0].netmask[3] = 0;
m_Ifconfig.connection[0].gateway[0] = 192;
m_Ifconfig.connection[0].gateway[1] = 168;
m_Ifconfig.connection[0].gateway[2] = 1;
m_Ifconfig.connection[0].gateway[3] = 2;
+ m_Ifconfig.connection[0].dns1[0] = 10;
+ m_Ifconfig.connection[0].dns1[1] = 0;
+ m_Ifconfig.connection[0].dns1[2] = 1;
+ m_Ifconfig.connection[0].dns1[3] = 1;
+ m_Ifconfig.connection[1].flags = 167;
+ m_Ifconfig.connection[1].ip[0] = 192;
+ m_Ifconfig.connection[1].ip[1] = 168;
+ m_Ifconfig.connection[1].ip[2] = 1;
+ m_Ifconfig.connection[1].ip[3] = 1;
+ m_Ifconfig.connection[1].netmask[0] = 255;
+ m_Ifconfig.connection[1].netmask[1] = 255;
+ m_Ifconfig.connection[1].netmask[2] = 255;
+ m_Ifconfig.connection[1].netmask[3] = 0;
+ m_Ifconfig.connection[1].gateway[0] = 192;
+ m_Ifconfig.connection[1].gateway[1] = 168;
+ m_Ifconfig.connection[1].gateway[2] = 1;
+ m_Ifconfig.connection[1].gateway[3] = 2;
+ m_Ifconfig.connection[1].dns1[0] = 10;
+ m_Ifconfig.connection[1].dns1[1] = 0;
+ m_Ifconfig.connection[1].dns1[2] = 1;
+ m_Ifconfig.connection[1].dns1[3] = 1;
+ m_Ifconfig.connection[2].flags = 167;
+ m_Ifconfig.connection[2].ip[0] = 192;
+ m_Ifconfig.connection[2].ip[1] = 168;
+ m_Ifconfig.connection[2].ip[2] = 1;
+ m_Ifconfig.connection[2].ip[3] = 1;
+ m_Ifconfig.connection[2].netmask[0] = 255;
+ m_Ifconfig.connection[2].netmask[1] = 255;
+ m_Ifconfig.connection[2].netmask[2] = 255;
+ m_Ifconfig.connection[2].netmask[3] = 0;
+ m_Ifconfig.connection[2].gateway[0] = 192;
+ m_Ifconfig.connection[2].gateway[1] = 168;
+ m_Ifconfig.connection[2].gateway[2] = 1;
+ m_Ifconfig.connection[2].gateway[3] = 2;
+ m_Ifconfig.connection[2].dns1[0] = 10;
+ m_Ifconfig.connection[2].dns1[1] = 0;
+ m_Ifconfig.connection[2].dns1[2] = 1;
+ m_Ifconfig.connection[2].dns1[3] = 1;
+
}
}
@@ -220,117 +284,83 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 _CommandAddress, bool _bForce
bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
{
u32 ReturnValue = 0;
-
SIOCtlVBuffer CommandBuffer(_CommandAddress);
switch (CommandBuffer.Parameter)
{
- case IOCTLV_NCD_READCONFIG: // 7004 out, 32 out
- // first out buffer gets filled with contents of /shared2/sys/net/02/config.dat
- // TODO: What's the second output buffer for?
- {
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETIFCONFIG");
+ case IOCTLV_NCD_READCONFIG: // 7004 Out, 32 Out. 2nd, 3rd
+ INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_READCONFIG");
+ //break;
- // fill output buffer, taking care of endianness
- u32 addr = CommandBuffer.PayloadBuffer.at(0).m_Address;
- Memory::WriteBigEData((const u8*)&m_Ifconfig, addr, 8);
- addr += 8;
- for (unsigned int i = 0; i < 3; i++)
+ case IOCTLV_NCD_GETCONFIG: // 7004 out, 32 out
+ // first out buffer gets filled with contents of /shared2/sys/net/02/config.dat
+ // TODO: What's the second output buffer for?
{
- netcfg_connection_t *conn = &m_Ifconfig.connection[i];
+ INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG");
+ u8 params1[0x1b5c];
+ u8 params2[0x20];
- Memory::WriteBigEData((const u8*)conn, addr, 26);
- Memory::Write_U16(Common::swap16(conn->mtu), addr+26);
- Memory::WriteBigEData((const u8*)conn->padding_3, addr+28, 8);
+ // fill output buffer, taking care of endianness
+ u32 addr = CommandBuffer.PayloadBuffer.at(0).m_Address;
+ u32 _BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
- Memory::WriteBigEData((const u8*)&conn->proxy_settings, addr+36, 260);
- Memory::Write_U16(Common::swap16(conn->proxy_settings.proxy_port), addr+296);
- Memory::WriteBigEData((const u8*)&conn->proxy_settings.proxy_username, addr+298, 65);
- Memory::Write_U8(conn->padding_4, addr+363);
+ Memory::ReadBigEData((u8*)params1, addr, 0x1b5c);
+ Memory::ReadBigEData((u8*)params2, CommandBuffer.PayloadBuffer.at(1).m_Address, 0x20);
- Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy, addr+364, 260);
- Memory::Write_U16(Common::swap16(conn->proxy_settings_copy.proxy_port), addr+624);
- Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy.proxy_username, addr+626, 65);
- Memory::WriteBigEData((const u8*)conn->padding_5, addr+691, 1641);
- addr += sizeof(netcfg_connection_t);
- }
- ReturnValue = 0;
- break;
- }
-
- case IOCTLV_NCD_UNK4: // 7004 In, 32 Out. 4th
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_UNK4");
- break;
-
- case 0x05: // 7004 Out, 32 Out. 2nd, 3rd
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCtlV 0x5");
- break;
-
- case IOCTLV_NCD_GETLINKSTATUS: // 32 Out. 5th
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS");
- break;
-
- case IOCTLV_NCD_GETWIRELESSMACADDRESS: // 32 Out, 6 Out. 1st
- // TODO: What's the first output buffer for?
- // second out buffer gets filled with first four bytes of the wireless MAC address.
- // No idea why the fifth and sixth bytes are left untouched.
- {
- // hardcoded address as a fallback
- // TODO: Make this configurable? Different MAC addresses MIGHT be needed for requesting a user id or encrypting content with NWC24
- const u8 default_address[] = { 0x00, 0x19, 0x1e, 0xfd, 0x71, 0x84 };
-
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS");
-
-#if defined(__linux__)
- const char *check_devices[3] = { "wlan0", "ath0", "eth0" };
- int fd, ret;
- struct ifreq ifr;
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- ifr.ifr_addr.sa_family = AF_INET;
-
- for (unsigned int dev = 0; dev < 3; dev++ )
- {
- strncpy(ifr.ifr_name, check_devices[dev], IFNAMSIZ-1);
- ret = ioctl(fd, SIOCGIFHWADDR, &ifr);
- if (ret == 0)
+ Memory::WriteBigEData((const u8*)&m_Ifconfig, addr, 8);
+ addr += 8;
+ for (unsigned int i = 0; i < 3; i++)
{
- INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS returning local MAC address of %s", check_devices[dev]);
- Memory::WriteBigEData((const u8*)ifr.ifr_hwaddr.sa_data, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
- break;
+ netcfg_connection_t *conn = &m_Ifconfig.connection[i];
+
+ Memory::WriteBigEData((const u8*)conn, addr, 26);
+ Memory::Write_U16(Common::swap16(conn->mtu), addr+26);
+ Memory::WriteBigEData((const u8*)conn->padding_3, addr+28, 8);
+
+ Memory::WriteBigEData((const u8*)&conn->proxy_settings, addr+36, 260);
+ Memory::Write_U16(Common::swap16(conn->proxy_settings.proxy_port), addr+296);
+ Memory::WriteBigEData((const u8*)&conn->proxy_settings.proxy_username, addr+298, 65);
+ Memory::Write_U8(conn->padding_4, addr+363);
+
+ Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy, addr+364, 260);
+ Memory::Write_U16(Common::swap16(conn->proxy_settings_copy.proxy_port), addr+624);
+ Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy.proxy_username, addr+626, 65);
+ Memory::WriteBigEData((const u8*)conn->padding_5, addr+691, 1641);
+ addr += sizeof(netcfg_connection_t);
}
- }
- if (ret != 0)
- {
- // fall back to the hardcoded address
- Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
- }
- close(fd);
-
-#elif defined(_WIN32)
- IP_ADAPTER_INFO *adapter_info = NULL;
- DWORD len = 0;
-
- DWORD ret = GetAdaptersInfo(adapter_info, &len);
- if (ret != ERROR_BUFFER_OVERFLOW || !len)
- {
- Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
+ Memory::Write_U32(0, _BufferOut2);
+ Memory::Write_U32(0, _BufferOut2+4);
+ ReturnValue = 0;
break;
}
- // LPFaint99: len is sizeof(IP_ADAPTER_INFO) * nics - 0x20
- adapter_info = new IP_ADAPTER_INFO[(len / sizeof(IP_ADAPTER_INFO)) + 1];
- ret = GetAdaptersInfo(adapter_info, &len);
-
- if (SUCCEEDED(ret)) Memory::WriteBigEData(adapter_info->Address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
- else Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
-
- delete[] adapter_info;
-#else
- Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
-#endif
+ case IOCTLV_NCD_SETCONFIG: // 7004 In, 32 Out. 4th
+ u8 param1[7004];
+ Memory::ReadBigEData(param1,CommandBuffer.InBuffer[0].m_Address, 100);
+ /*if (param1[4] == 2)
+ status = 3;
+ if (param1[4] == 1)
+ status = 5;
+ if (param1[4] == 0)
+ status = 2;*/
+ INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_SETCONFIG");
break;
- }
+
+ case IOCTLV_NCD_GETLINKSTATUS: // 32 Out. 5th
+ {
+ INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS");
+ Memory::Write_U32(0x00000000, CommandBuffer.PayloadBuffer[0].m_Address);
+ Memory::Write_U32(status, CommandBuffer.PayloadBuffer[0].m_Address+4);
+ break;
+ }
+
+ case IOCTLV_NCD_GETWIRELESSMACADDRESS: // 32 Out, 6 Out. 1st
+ {
+ INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS");
+ Memory::Write_U32(0, CommandBuffer.PayloadBuffer.at(0).m_Address);
+ Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 6);
+ break;
+ }
default:
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter);
@@ -346,10 +376,17 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
CWII_IPC_HLE_Device_net_ip_top::CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
{
+#ifdef _WIN32
+ int ret = WSAStartup(MAKEWORD(2,2), &InitData);
+ INFO_LOG(WII_IPC_NET, "WSAStartup: %d", ret);
+#endif
}
CWII_IPC_HLE_Device_net_ip_top::~CWII_IPC_HLE_Device_net_ip_top()
{
+#ifdef _WIN32
+ WSACleanup();
+#endif
}
bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
@@ -377,103 +414,448 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
u32 Command = Memory::Read_U32(_CommandAddress + 0x0C);
-// INFO_LOG(WII_IPC_NET,"%s - Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)\n", GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
-
u32 ReturnValue = ExecuteCommand(Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
return true;
}
-struct bind_params {
+
+struct bind_params
+{
u32 socket;
u32 has_name;
u8 name[28];
};
-struct GC_sockaddr {
+
+struct GC_sockaddr
+{
u8 sa_len;
u8 sa_family;
s8 sa_data[14];
};
-struct GC_in_addr {
- u32 s_addr_; // this cannot be named s_addr under windows - collides with some crazy define.
+
+struct GC_in_addr
+{
+ // this cannot be named s_addr under windows - collides with some crazy define.
+ u32 s_addr_;
};
-struct GC_sockaddr_in {
+
+struct GC_sockaddr_in
+{
u8 sin_len;
u8 sin_family;
u16 sin_port;
struct GC_in_addr sin_addr;
s8 sin_zero[8];
};
-u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn, u32 BufferInSize, u32 BufferOut, u32 BufferOutSize)
-{
- // Clean the location of the output buffer to zeros as a safety precaution */
- Memory::Memset(BufferOut, 0, BufferOutSize);
+#ifdef _WIN32
+char *DecodeError(int ErrorCode)
+{
+ static char Message[1024];
+
+ // If this program was multi-threaded, we'd want to use FORMAT_MESSAGE_ALLOCATE_BUFFER
+ // instead of a static buffer here.
+ // (And of course, free the buffer when we were done with it)
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)Message, 1024, NULL);
+ return Message;
+}
+#endif
+
+static int getNetErrorCode(int ret, std::string caller)
+{
+#ifdef _WIN32
+ INFO_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d\n",
+ caller.c_str(), WSAGetLastError(), DecodeError(WSAGetLastError()), ret);
+
+ if (ret>= 0)
+ return ret;
+
+ switch (WSAGetLastError())
+ {
+ case 10040:
+ return 1;
+ case 10054:
+ return -15;
+ case 10035:
+ return -26;
+ case 6:
+ return -26;
+ default:
+ return -1;
+ }
+#else
+ INFO_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d\n",
+ caller.c_str(), 0x1337, "hmm", ret);
+ return ret;
+#endif
+}
+
+static int inet_pton(const char *src, unsigned char *dst)
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[4], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int newt = *tp * 10 + (pch - digits);
+
+ if (newt > 255)
+ return (0);
+ *tp = newt;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, 4);
+ return (1);
+}
+
+
+u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command,
+ u32 _BufferIn, u32 BufferInSize,
+ u32 _BufferOut, u32 BufferOutSize)
+{
switch (_Command)
{
case IOCTL_SO_STARTUP:
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_STARTUP "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
break;
+ case IOCTL_SO_CONNECT:
+ {
+ //struct sockaddr_in echoServAddr;
+ struct connect_params{
+ u32 socket;
+ u32 has_addr;
+ u8 addr[28];
+ };
+ struct connect_params params;
+ struct sockaddr_in serverAddr;
+
+ Memory::ReadBigEData((u8*)¶ms, _BufferIn, sizeof(connect_params));
+
+ if (Common::swap32(params.has_addr) != 1)
+ return -1;
+
+ memset(&serverAddr, 0, sizeof(serverAddr));
+ memcpy(&serverAddr, params.addr, params.addr[0]);
+
+ // GC/Wii sockets have a length param as well, we dont really care :)
+ serverAddr.sin_family = serverAddr.sin_family >> 8;
+
+ int ret = connect(Common::swap32(params.socket), (struct sockaddr *) &serverAddr, sizeof(serverAddr));
+
+ INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtl request IOCTL_SO_CONNECT (%08x, %s:%d)",
+ Common::swap32(params.socket), inet_ntoa(serverAddr.sin_addr), Common::swap16(serverAddr.sin_port));
+
+ return getNetErrorCode(ret, "SO_CONNECT");
+ break;
+ }
+
+ case IOCTL_SO_SHUTDOWN:
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_SHUTDOWN "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 how = Memory::Read_U32(_BufferIn+4);
+ int ret = shutdown(sock, how);
+ return getNetErrorCode(ret, "SO_SHUTDOWN");
+ break;
+ }
+
+ case IOCTL_SO_CLOSE:
+ {
+ u32 sock = Memory::Read_U32(_BufferIn);
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_CLOSE (%08x)", sock);
+
+ #ifdef _WIN32
+ u32 ret = closesocket(sock);
+
+ return getNetErrorCode(ret, "IOCTL_SO_CLOSE");
+ #else
+ return close(sock);
+ #endif
+ break;
+ }
+
case IOCTL_SO_SOCKET:
- {
- u32 AF = Memory::Read_U32(_BufferIn);
- u32 TYPE = Memory::Read_U32(_BufferIn + 0x04);
- u32 PROT = Memory::Read_U32(_BufferIn + 0x04 * 2);
-// u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3);
- u32 Socket = (u32)socket(AF, TYPE, PROT);
- return Common::swap32(Socket); // So it doesn't get mangled later on
- break;
- }
+ {
+ u32 AF = Memory::Read_U32(_BufferIn);
+ u32 TYPE = Memory::Read_U32(_BufferIn + 0x04);
+ u32 PROT = Memory::Read_U32(_BufferIn + 0x08);
+ u32 s = (u32)socket(AF, TYPE, PROT);
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_SOCKET "
+ "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ s, AF, TYPE, PROT, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ return getNetErrorCode(s, "SO_SOCKET");
+ break;
+ }
case IOCTL_SO_BIND:
- {
- bind_params *addr = (bind_params*)Memory::GetPointer(_BufferIn);
- GC_sockaddr_in addrPC;
- memcpy(&addrPC, addr->name, sizeof(GC_sockaddr_in));
- sockaddr_in address;
- address.sin_family = addrPC.sin_family;
- address.sin_addr.s_addr = addrPC.sin_addr.s_addr_;
- address.sin_port = htons(addrPC.sin_port);
- int Return = bind(addr->socket, (sockaddr*)&address, sizeof(address));
- return Return;
- //int bind(int s, struct sockaddr *addr, int addrlen);
- break;
- }
+ {
+ bind_params *addr = (bind_params*)Memory::GetPointer(_BufferIn);
+ GC_sockaddr_in addrPC;
+ memcpy(&addrPC, addr->name, sizeof(GC_sockaddr_in));
+ sockaddr_in address;
+ address.sin_family = addrPC.sin_family;
+ address.sin_addr.s_addr = addrPC.sin_addr.s_addr_;
+ address.sin_port = addrPC.sin_port;
+ int ret = bind(Common::swap32(addr->socket), (sockaddr*)&address, sizeof(address));
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_BIND (%s:%d) "
+ "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ inet_ntoa(address.sin_addr), Common::swap16(address.sin_port),
+ Common::swap32(addr->socket), _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ return getNetErrorCode(ret, "SO_BIND");
+ break;
+ }
case IOCTL_SO_LISTEN:
- {
- u32 S = Memory::Read_U32(_BufferIn);
- u32 BACKLOG = Memory::Read_U32(_BufferIn + 0x04);
- u32 Return = listen(S, BACKLOG);
- return Return;
- break;
- }
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_LISTEN "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ u32 S = Memory::Read_U32(_BufferIn);
+ u32 BACKLOG = Memory::Read_U32(_BufferIn + 0x04);
+ u32 ret = listen(S, BACKLOG);
+ return getNetErrorCode(ret, "SO_LISTEN");
+ break;
+ }
case IOCTL_SO_ACCEPT:
- {
- //TODO: (Sonic)Check if this is correct
- u32 S = Memory::Read_U32(_BufferIn);
- socklen_t addrlen;
- struct sockaddr_in address;
- u32 Return = (u32)accept(S, (struct sockaddr *)&address, &addrlen);
- GC_sockaddr_in *addr = (GC_sockaddr_in*)Memory::GetPointer(BufferOut);
- addr->sin_family = (u8)address.sin_family;
- addr->sin_addr.s_addr_ = address.sin_addr.s_addr;
- addr->sin_port = address.sin_port;
- socklen_t *Len = (socklen_t *)Memory::GetPointer(BufferOut + 0x04);
- *Len = addrlen;
- return Return;
- //int accept(int s, struct sockaddr *addr, int *addrlen);
- ///dev/net/ip/top::IOCtl request 0x1 (BufferIn: (000318c0, 4), BufferOut: (00058a4c, 8)
- }
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_ACCEPT "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
- case IOCTL_SO_GETHOSTID:
- return 127 << 24 | 1;
+ u32 S = Memory::Read_U32(_BufferIn);
+ struct sockaddr* addr = (struct sockaddr*) Memory::GetPointer(_BufferOut);
+ socklen_t* addrlen = (socklen_t*) Memory::GetPointer(BufferOutSize);
+ *addrlen = sizeof(struct sockaddr);
+ int ret = accept(S, addr, addrlen);
+ return getNetErrorCode(ret, "SO_ACCEPT");
+ }
+
+ case IOCTL_SO_GETSOCKOPT:
+ {
+ u32 sock = Memory::Read_U32(_BufferOut);
+ u32 level = Memory::Read_U32(_BufferOut + 4);
+ u32 optname = Memory::Read_U32(_BufferOut + 8);
+ u8 optval[20];
+ u32 optlen = 8;
+
+ INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtl request IOCTL_SO_GETSOCKOPT "
+ "Socket: %08x, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ sock, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ int ret = getsockopt (sock, level, optname, (char *) optval, (socklen_t*)&optlen);
+ Memory::Write_U32(optlen, _BufferOut + 0xC);
+ Memory::WriteBigEData((u8 *) optval, _BufferOut + 0x10, optlen);
+ return ret;
+ }
+
+ case IOCTL_SO_SETSOCKOPT:
+ {
+ u32 S = Memory::Read_U32(_BufferIn);
+ u32 level = Memory::Read_U32(_BufferIn + 4);
+ u32 optname = Memory::Read_U32(_BufferIn + 8);
+ u32 optlen = Memory::Read_U32(_BufferIn + 0xc);
+ u8 optval[20];
+ Memory::ReadBigEData(optval, _BufferIn + 0x10, optlen);
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_SETSOCKOPT "
+ "Socket: %08x, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ S, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ int ret = setsockopt(S, level, optname, (char*)optval, optlen);
+
+ return ret;
+ }
+
+ case IOCTL_SO_FCNTL:
+ {
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 cmd = Memory::Read_U32(_BufferIn + 4);
+ u32 arg = Memory::Read_U32(_BufferIn + 8);
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_FCNTL(%08X, %08X) "
+ "Socket: %08x, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ cmd, arg,
+ sock, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ #ifdef _WIN32
+ #define F_GETFL 3
+ #define F_SETFL 4
+ #define F_NONBLOCK 4
+ if (cmd == F_GETFL)
+ {
+ INFO_LOG(WII_IPC_NET, "F_GETFL WTF?");
+ }
+ else if (cmd == F_SETFL)
+ {
+ u_long iMode = 0;
+ if (arg & F_NONBLOCK)
+ iMode = 1;
+ int ioctlret = ioctlsocket(sock, FIONBIO, &iMode);
+ return getNetErrorCode(ioctlret, "SO_FCNTL");
+ }
+ else
+ {
+ INFO_LOG(WII_IPC_NET, "UNKNOWN WTF?");
+ }
+ return 0;
+ #else
+ return fcntl(sock, cmd, arg);
+ #endif
+ }
+
+ case IOCTL_SO_GETSOCKNAME:
+ {
+ u32 sock = Memory::Read_U32(_BufferIn);
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_GETSOCKNAME "
+ "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ sock, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ struct sockaddr sa;
+ socklen_t sa_len;
+ sa_len = sizeof(sa);
+ int ret = getsockname(sock, &sa, &sa_len);
+
+ Memory::Write_U8(BufferOutSize, _BufferOut);
+ Memory::Write_U8(sa.sa_family, _BufferOut+1);
+ Memory::WriteBigEData((u8*)&sa.sa_data, _BufferOut+2, BufferOutSize-2);
+ return ret;
+ }
+
+ case IOCTL_SO_GETHOSTID:
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_GETHOSTID "
+ "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ return 10 << 24 | 1 << 8 | 30;
+
+ case IOCTL_SO_INETATON:
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_INETATON "
+ "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ (char*)Memory::GetPointer(_BufferIn), _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ struct hostent *remoteHost = gethostbyname((char*)Memory::GetPointer(_BufferIn));
+ Memory::Write_U32(Common::swap32(*(u_long *)remoteHost->h_addr_list[0]), _BufferOut);
+ return remoteHost->h_addr_list[0] == 0 ? -1 : 0;
+ }
+
+ case IOCTL_SO_INETPTON:
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_INETPTON "
+ "(Translating: %s)", Memory::GetPointer(_BufferIn));
+ return inet_pton((char*)Memory::GetPointer(_BufferIn), Memory::GetPointer(_BufferOut+4));
break;
+ case IOCTL_SO_POLL:
+ {
+ #ifdef _WIN32
+ u32 unknown = Memory::Read_U32(_BufferIn);
+ u32 timeout = Memory::Read_U32(_BufferIn + 4);
+
+ int nfds = BufferOutSize / 0xc;
+ if (nfds == 0)
+ ERROR_LOG(WII_IPC_NET,"Hidden POLL");
+ pollfd_t* ufds = (pollfd_t *)malloc(sizeof(pollfd_t) * nfds);
+ if (ufds == NULL)
+ return -1;
+ for (int i = 0; i < nfds; i++)
+ {
+ ufds[i].fd = Memory::Read_U32(_BufferOut + 0xc*i);
+ ufds[i].events = Memory::Read_U32(_BufferOut + 0xc*i + 4);
+ ufds[i].revents = Memory::Read_U32(_BufferOut + 0xc*i + 8);
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtl request IOCTL_SO_POLL(%d) "
+ "Sock: %08x, Unknown: %08x, Events: %08x, "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ i, ufds[i].fd, unknown, ufds[i].events,
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ }
+ int ret = poll(ufds, nfds, timeout);
+ for (int i = 0; ih_name, 255);
+ Memory::WriteBigEData((u8*)remoteHost->h_name, _BufferOut + 0x10, hnamelen);
+
+ Memory::Write_U16(remoteHost->h_addrtype, _BufferOut + 0x8);
+ Memory::Write_U16(remoteHost->h_length, _BufferOut + 0xA);
+ Memory::Write_U32(_BufferOut + 0x340, _BufferOut + 0xC);
+
+ for (i = 0; remoteHost->h_addr_list[i] != 0; i++)
+ {
+ u32 ip = *(u_long *)remoteHost->h_addr_list[i];
+ Memory::Write_U32(_BufferOut + 0x110 + i*4 ,_BufferOut + 0x340 + i*4);
+ Memory::Write_U32(Common::swap32(ip), _BufferOut + 0x110 + i*4);
+ }
+ i++;
+ Memory::Write_U32(_BufferOut + 0x340 + i*4, _BufferOut + 0x4);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+ break;
+ }
+
default:
- INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- _Command, _BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtl request 0x%x "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _Command, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
break;
}
@@ -481,25 +863,358 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn,
return 0;
}
+u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer)
+{
+ u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
+ u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
+
+ u32 _BufferOut = 0, _BufferOut2 = 0, _BufferOut3 = 0;
+ u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;
+
+ if (CommandBuffer.InBuffer.size() > 0)
+ {
+ _BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
+ BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
+ }
+ if (CommandBuffer.InBuffer.size() > 1)
+ {
+ _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
+ BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
+ }
+ if (CommandBuffer.InBuffer.size() > 2)
+ {
+ _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address;
+ BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size;
+ }
+
+ if (CommandBuffer.PayloadBuffer.size() > 0)
+ {
+ _BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
+ BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
+ }
+ if (CommandBuffer.PayloadBuffer.size() > 1)
+ {
+ _BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
+ BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
+ }
+ if (CommandBuffer.PayloadBuffer.size() > 2)
+ {
+ _BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
+ BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
+ }
+
+ //struct ifreq { /* BUGBUG: reduced form of ifreq just for this hack */
+ // char ifr_name[16];
+ // struct sockaddr ifr_addr;
+ //};
+
+ //struct ifreq ifr; struct sockaddr_in saddr;
+ //int fd;
+
+ #ifdef _WIN32
+ PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
+ ULONG OutBufferLength = 0;
+ ULONG RetVal = 0, i;
+ #endif
+
+ u32 param = 0, param2 = 0, param3, param4, param5 = 0;
+
+ switch (_Parameter)
+ {
+ case IOCTLV_SO_GETINTERFACEOPT:
+ {
+ param = Memory::Read_U32(_BufferIn);
+ param2 = Memory::Read_U32(_BufferIn+4);
+ param3 = Memory::Read_U32(_BufferOut);
+ param4 = Memory::Read_U32(_BufferOut2);
+ if (BufferOutSize >= 8)
+ {
+
+ param5 = Memory::Read_U32(_BufferOut+4);
+ }
+
+ INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtlV request IOCTLV_SO_GETINTERFACEOPT(%08X, %08X) "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
+ param, param2,
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
+
+ switch (param2)
+ {
+ case 0xb003:
+ {
+ u32 address = 0;
+ /*fd=socket(PF_INET,SOCK_STREAM,0);
+ strcpy(ifr.ifr_name,"name of interface");
+ ioctl(fd,SIOCGIFADDR,&ifr);
+ saddr=*((struct sockaddr_in *)(&(ifr.ifr_addr)));
+ */
+ #ifdef _WIN32
+ for (i = 0; i < 5; i++)
+ {
+ RetVal = GetAdaptersAddresses(
+ AF_INET,
+ 0,
+ NULL,
+ AdapterAddresses,
+ &OutBufferLength);
+
+ if (RetVal != ERROR_BUFFER_OVERFLOW) {
+ break;
+ }
+
+ if (AdapterAddresses != NULL) {
+ FREE(AdapterAddresses);
+ }
+
+ AdapterAddresses = (PIP_ADAPTER_ADDRESSES)MALLOC(OutBufferLength);
+ if (AdapterAddresses == NULL) {
+ RetVal = GetLastError();
+ break;
+ }
+ }
+ if (RetVal == NO_ERROR)
+ {
+ unsigned long dwBestIfIndex = 0;
+ IPAddr dwDestAddr = (IPAddr)0x08080808;
+ // If successful, output some information from the data we received
+ PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses;
+ if (GetBestInterface(dwDestAddr,&dwBestIfIndex) == NO_ERROR)
+ {
+ while (AdapterList)
+ {
+ if (AdapterList->IfIndex == dwBestIfIndex &&
+ AdapterList->FirstDnsServerAddress &&
+ AdapterList->OperStatus == IfOperStatusUp)
+ {
+ INFO_LOG(WII_IPC_NET, "Name of valid interface: %S", AdapterList->FriendlyName);
+ INFO_LOG(WII_IPC_NET, "DNS: %u.%u.%u.%u",
+ (unsigned char)AdapterList->FirstDnsServerAddress->Address.lpSockaddr->sa_data[2],
+ (unsigned char)AdapterList->FirstDnsServerAddress->Address.lpSockaddr->sa_data[3],
+ (unsigned char)AdapterList->FirstDnsServerAddress->Address.lpSockaddr->sa_data[5],
+ (unsigned char)AdapterList->FirstDnsServerAddress->Address.lpSockaddr->sa_data[6]);
+ address = Common::swap32(*(u32*)(&AdapterList->FirstDnsServerAddress->Address.lpSockaddr->sa_data[2]));
+ break;
+ }
+ AdapterList = AdapterList->Next;
+ }
+ }
+ }
+ if (AdapterAddresses != NULL) {
+ FREE(AdapterAddresses);
+ }
+ #endif
+ if (address == 0)
+ address = 0x08080808;
+
+ Memory::Write_U32(address, _BufferOut);
+ Memory::Write_U32(0x08080808, _BufferOut+4);
+ break;
+ }
+
+ case 0x1003:
+ Memory::Write_U32(0, _BufferOut);
+ break;
+
+ case 0x1004:
+ Memory::WriteBigEData(default_address, _BufferOut, 6);
+ break;
+
+ case 0x4002:
+ Memory::Write_U32(2, _BufferOut);
+ break;
+
+ case 0x4003:
+ Memory::Write_U32(0xC, _BufferOut2);
+ Memory::Write_U32(10 << 24 | 1 << 8 | 30, _BufferOut);
+ Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, _BufferOut+4);
+ Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, _BufferOut+8);
+ break;
+
+ default:
+ ERROR_LOG(WII_IPC_NET, "Unknown param2: %08X", param2);
+ break;
+
+ }
+
+ return 0;
+ break;
+ }
+
+ case IOCTLV_SO_SENDTO:
+ {
+ struct sendto_params {
+ u32 socket;
+ u32 flags;
+ u32 has_destaddr;
+ u8 destaddr[28];
+ };
+ struct sendto_params params;
+ Memory::ReadBigEData((u8*)¶ms, _BufferIn2, BufferInSize2);
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtlV request IOCTLV_SO_SENDTO "
+ "Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
+ Common::swap32(params.socket), _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
+
+ if (params.has_destaddr)
+ {
+ struct sockaddr_in* addr = (struct sockaddr_in*)¶ms.destaddr;
+ u8 len = sizeof(sockaddr); //addr->sin_family & 0xFF;
+ addr->sin_family = addr->sin_family >> 8;
+ int ret = sendto(Common::swap32(params.socket), (char*)Memory::GetPointer(_BufferIn),
+ BufferInSize, Common::swap32(params.flags), (struct sockaddr*)addr, len);
+ return getNetErrorCode(ret, "SO_SENDTO");
+ }
+ else
+ {
+ int ret = send(Common::swap32(params.socket), (char*)Memory::GetPointer(_BufferIn),
+ BufferInSize, Common::swap32(params.flags));
+ return getNetErrorCode(ret, "SO_SEND");
+ }
+ break;
+ }
+
+ case IOCTLV_SO_RECVFROM:
+ {
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 flags = Memory::Read_U32(_BufferIn + 4);
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtlV request IOCTLV_SO_RECVFROM "
+ "Socket: %08X, Flags: %08X, "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",
+ sock, flags,
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferOut, BufferOutSize, _BufferOut2, BufferOutSize2);
+
+ char *buf = (char *)Memory::GetPointer(_BufferOut);
+ int len = BufferOutSize;
+ struct sockaddr_in addr;
+ socklen_t fromlen = 0;
+
+ if (_BufferOut2 != 0)
+ {
+ fromlen = BufferOutSize2 >= sizeof(struct sockaddr) ? BufferOutSize2 : sizeof(struct sockaddr);
+ }
+
+ if (flags != 2)
+ flags = 0;
+ else
+ flags = MSG_PEEK;
+
+
+ int ret = recvfrom(sock, buf, len, flags,
+ fromlen ? (struct sockaddr*) &addr : NULL, fromlen ? &fromlen : NULL);
+ if (_BufferOut2 != 0)
+ {
+ addr.sin_family = (addr.sin_family << 8) | (BufferOutSize2&0xFF);
+ Memory::WriteBigEData((u8*)&addr, _BufferOut2, BufferOutSize2);
+ }
+ return getNetErrorCode(ret, "SO_RECVFROM");
+ break;
+ }
+
+ case IOCTLV_SO_GETADDRINFO:
+ {
+ struct addrinfo hints;
+ struct addrinfo *result = NULL;
+
+ if (BufferInSize3)
+ {
+ hints.ai_flags = Memory::Read_U32(_BufferIn3);
+ hints.ai_family = Memory::Read_U32(_BufferIn3 + 0x4);
+ hints.ai_socktype = Memory::Read_U32(_BufferIn3 + 0x8);
+ hints.ai_protocol = Memory::Read_U32(_BufferIn3 + 0xC);
+ hints.ai_addrlen = Memory::Read_U32(_BufferIn3 + 0x10);
+ hints.ai_canonname = (char*)Memory::Read_U32(_BufferIn3 + 0x14);
+ hints.ai_addr = (sockaddr *)Memory::Read_U32(_BufferIn3 + 0x18);
+ hints.ai_next = (addrinfo *)Memory::Read_U32(_BufferIn3 + 0x1C);
+ }
+
+ char* pNodeName = NULL;
+ if (BufferInSize > 0)
+ pNodeName = (char*)Memory::GetPointer(_BufferIn);
+
+ char* pServiceName = NULL;
+ if (BufferInSize2 > 0)
+ pServiceName = (char*)Memory::GetPointer(_BufferIn2);
+
+ int ret = getaddrinfo(pNodeName, pServiceName, &hints, &result);
+ u32 addr = _BufferOut;
+ u32 sockoffset = addr + 0x460;
+ if (ret >= 0)
+ {
+ while (result != NULL)
+ {
+ Memory::Write_U32(result->ai_flags, addr);
+ Memory::Write_U32(result->ai_family, addr + 0x04);
+ Memory::Write_U32(result->ai_socktype, addr + 0x08);
+ Memory::Write_U32(result->ai_protocol, addr + 0x0C);
+ Memory::Write_U32(result->ai_addrlen, addr + 0x10);
+ // what to do? where to put? the buffer of 0x834 doesn't allow space for this
+ Memory::Write_U32(/*result->ai_cannonname*/ 0, addr + 0x14);
+
+ if (result->ai_addr)
+ {
+ Memory::Write_U32(sockoffset, addr + 0x18);
+ Memory::Write_U16(((result->ai_addr->sa_family & 0xFF) << 8) | (result->ai_addrlen & 0xFF), sockoffset);
+ Memory::WriteBigEData((u8*)result->ai_addr->sa_data, sockoffset + 0x2, sizeof(result->ai_addr->sa_data));
+ sockoffset += 0x1C;
+ }
+ else
+ {
+ Memory::Write_U32(0, addr + 0x18);
+ }
+
+ if (result->ai_next)
+ {
+ Memory::Write_U32(addr + sizeof(addrinfo), addr + 0x1C);
+ }
+ else
+ {
+ Memory::Write_U32(0, addr + 0x1C);
+ }
+
+ addr += sizeof(addrinfo);
+ result = result->ai_next;
+ }
+ }
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ip/top::IOCtlV request IOCTLV_SO_GETADDRINFO "
+ "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetPointer(_BufferIn));
+ return ret;
+ }
+
+ default:
+ INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtlV request 0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
+ _Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
+ break;
+
+ }
+ return 0;
+}
+
bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 _CommandAddress)
{
u32 ReturnValue = 0;
-
SIOCtlVBuffer CommandBuffer(_CommandAddress);
switch (CommandBuffer.Parameter)
{
- case IOCTL_SO_BIND:
- case IOCTLV_SO_RECVFROM:
- case IOCTL_SO_SOCKET:
- case IOCTL_SO_GETHOSTID:
- case IOCTL_SO_STARTUP:
- //break;
-
- default:
- INFO_LOG(WII_IPC_NET, "NET_IP_TOP IOCtlV: 0x%08X\n", CommandBuffer.Parameter);
- break;
+ case IOCTLV_SO_SENDTO:
+ case IOCTL_SO_BIND:
+ case IOCTLV_SO_RECVFROM:
+ case IOCTL_SO_SOCKET:
+ case IOCTL_SO_GETHOSTID:
+ case IOCTL_SO_STARTUP:
+ default:
+ ReturnValue = ExecuteCommandV(CommandBuffer.Parameter, CommandBuffer);
+ break;
}
Memory::Write_U32(ReturnValue, _CommandAddress+4);
return true;
}
+
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#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 29769e5b85..739a3d7780 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
@@ -18,12 +18,22 @@
#ifndef _WII_IPC_HLE_DEVICE_NET_H_
#define _WII_IPC_HLE_DEVICE_NET_H_
+#ifdef _MSC_VER
+#pragma warning(disable: 4748)
+#pragma optimize("",off)
+#endif
+
#include "WII_IPC_HLE_Device.h"
+#ifdef _WIN32
+#include
+#endif
+
+
// data layout of the network configuration file (/shared2/sys/net/02/config.dat)
// needed for /dev/net/ncd/manage
#pragma pack(1)
-typedef struct
+struct netcfg_proxy_t
{
u8 use_proxy; // 0x00 -> no proxy; 0x01 -> proxy
u8 use_proxy_userandpass; // 0x00 -> don't use username and password; 0x01 -> use username and password
@@ -34,9 +44,9 @@ typedef struct
u8 proxy_username[32];
u8 padding_3;
u8 proxy_password[32];
-} netcfg_proxy_t;
+};
-typedef struct
+struct netcfg_connection_t
{
// settings common to both wired and wireless connections
u8 flags; // Connection selected
@@ -87,27 +97,24 @@ typedef struct
u8 key[64]; // encryption key; for WEP, key is stored 4 times (20 bytes for WEP64 and 52 bytes for WEP128) then padded with 0x00
u8 padding_12[236];
-} netcfg_connection_t;
+};
-typedef struct
+struct network_config_t
{
- u8 header0; // 0x00
- u8 header1; // 0x00
- u8 header2; // 0x00
- u8 header3; // 0x00
- u8 header4; // 0x01 if there's at least one valid connection to the Internet.
- u8 header5; // 0x00
- u8 header6; // always 0x07?
- u8 header7; // 0x00
+ u32 version;
+ u8 connType; // 0x01 if there's at least one valid connection to the Internet.
+ u8 nwc24Permission; // 0x00
+ u8 linkTimeout; // always 0x07?
+ u8 padding; // 0x00
netcfg_connection_t connection[3];
-} network_config_t;
+};
#pragma pack()
-// **********************************************************************************
-// KD is the IOS module responsible for implementing WiiConnect24 functionality. It
-// can perform HTTPS downloads, send and receive mail via SMTP, and execute a
+//////////////////////////////////////////////////////////////////////////
+// KD is the IOS module responsible for implementing WiiConnect24 functionality.
+// It can perform HTTPS downloads, send and receive mail via SMTP, and execute a
// JavaScript-like language while the Wii is in standby mode.
class CWII_IPC_HLE_Device_net_kd_request : public IWII_IPC_HLE_Device
{
@@ -125,24 +132,24 @@ private:
{
IOCTL_NWC24_SUSPEND_SCHEDULAR = 0x01,
IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR = 0x02,
- IOCTL_NWC24_UNK_3 = 0x03,
- IOCTL_NWC24_UNK_4 = 0x04,
+ IOCTL_NWC24_EXEC_RESUME_SCHEDULAR = 0x03,
+ IOCTL_NWC24_KD_GET_TIME_TRIGGERS = 0x04,
IOCTL_NWC24_UNK_5 = 0x05,
IOCTL_NWC24_STARTUP_SOCKET = 0x06,
IOCTL_NWC24_CLEANUP_SOCKET = 0x07,
IOCTL_NWC24_LOCK_SOCKET = 0x08,
IOCTL_NWC24_UNLOCK_SOCKET = 0x09,
- IOCTL_NWC24_UNK_A = 0x0A,
- IOCTL_NWC24_UNK_B = 0x0B,
- IOCTL_NWC24_UNK_C = 0x0C,
+ IOCTL_NWC24_CHECK_MAIL_NOW = 0x0A,
+ IOCTL_NWC24_SEND_MAIL_NOW = 0x0B,
+ IOCTL_NWC24_RECEIVE_MAIL_NOW = 0x0C,
IOCTL_NWC24_SAVE_MAIL_NOW = 0x0D,
IOCTL_NWC24_DOWNLOAD_NOW_EX = 0x0E,
IOCTL_NWC24_REQUEST_GENERATED_USER_ID = 0x0F,
IOCTL_NWC24_REQUEST_REGISTER_USER_ID = 0x10,
IOCTL_NWC24_GET_SCHEDULAR_STAT = 0x1E,
- IOCTL_NWC24_UNK_1F = 0x1F,
- IOCTL_NWC24_UNK_20 = 0x20,
- IOCTL_NWC24_UNK_21 = 0x21,
+ IOCTL_NWC24_SET_FILTER_MODE = 0x1F,
+ IOCTL_NWC24_SET_DEBUG_MODE = 0x20,
+ IOCTL_NWC24_KD_SET_NEXT_WAKEUP = 0x21,
IOCTL_NWC24_SET_SCRIPT_MODE = 0x22,
IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28,
};
@@ -151,13 +158,16 @@ private:
std::string m_UserID;
};
-// **********************************************************************************
+//////////////////////////////////////////////////////////////////////////
class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device
{
+ u64 timediff;
public:
- CWII_IPC_HLE_Device_net_kd_time(u32 _DeviceID, const std::string& _rDeviceName) :
- IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
- {}
+ CWII_IPC_HLE_Device_net_kd_time(u32 _DeviceID, const std::string& _rDeviceName)
+ : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+ {
+ timediff = 1337; // this must be stored somewhere?
+ }
virtual ~CWII_IPC_HLE_Device_net_kd_time()
{}
@@ -188,26 +198,29 @@ public:
switch (Parameter)
{
case IOCTL_NW24_SET_RTC_COUNTER: // NWC24iSetRtcCounter (but prolly just the first 4 bytes are intresting...)
+ {
_dbg_assert_msg_(WII_IPC_NET, BufferInSize==0x20, "NET_KD_TIME: Set RTC Counter BufferIn to small");
_dbg_assert_msg_(WII_IPC_NET, BufferOutSize==0x20, "NET_KD_TIME: Set RTC Counter BufferOut to small");
-
- for (int i=0; i<0x20; i++)
- {
- m_RtcCounter[i] = Memory::Read_U8(BufferIn+i);
- }
-
- // send back for sync?? at least there is a out buffer...
- for (int i=0; i<0x20; i++)
- {
- Memory::Write_U8(m_RtcCounter[i], BufferOut+i);
- }
-
+ u64 rtctime = Memory::Read_U64(BufferIn+4);
+ Memory::Write_U32(0, BufferOut);
+ Memory::Write_U64(rtctime + timediff, BufferOut+4);
+
INFO_LOG(WII_IPC_NET, "NET_KD_TIME: Set RTC Counter");
Memory::Write_U32(0, _CommandAddress + 0x4);
return true;
+ }
+
+ case IOCTL_NW24_GET_TIME_DIFF:
+ {
+ Memory::Write_U32(0, BufferOut);
+ Memory::Write_U64(timediff, BufferOut+4);
+ INFO_LOG(WII_IPC_NET, "NET_KD_TIME: Get time diff");
+
+ Memory::Write_U32(0, _CommandAddress + 0x4);
+ return true;
+ }
- case IOCTL_NW24_GET_TIME_DIFF: // Input: none, Output: 32
default:
ERROR_LOG(WII_IPC_NET, "%s - IOCtl:\n"
" Parameter: 0x%x (0x17 NWC24iSetRtcCounter) \n"
@@ -234,7 +247,7 @@ private:
u8 m_RtcCounter[0x20];
};
-// **********************************************************************************
+//////////////////////////////////////////////////////////////////////////
class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device
{
public:
@@ -248,7 +261,12 @@ public:
virtual bool IOCtlV(u32 _CommandAddress);
private:
- enum {
+#ifdef _WIN32
+ WSADATA InitData;
+#endif
+
+ enum
+ {
IOCTL_SO_ACCEPT = 1,
IOCTL_SO_BIND,
IOCTL_SO_CLOSE,
@@ -287,6 +305,7 @@ private:
};
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
+ u32 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);
};
// **********************************************************************************
@@ -303,16 +322,23 @@ public:
virtual bool IOCtlV(u32 _CommandAddress);
private:
- enum {
- IOCTLV_NCD_UNK1 = 0x1, // NCDLockWirelessDriver
- IOCTLV_NCD_UNK2 = 0x2, // NCDUnlockWirelessDriver
- IOCTLV_NCD_READCONFIG = 0x3, // NCDReadConfig?
- IOCTLV_NCD_UNK4 = 0x4,
- IOCTLV_NCD_GETLINKSTATUS = 0x7, // NCDGetLinkStatus
- IOCTLV_NCD_GETWIRELESSMACADDRESS = 0x8, // NCDGetWirelessMacAddress
+ enum
+ {
+ IOCTLV_NCD_LOCKWIRELESSDRIVER = 0x1, // NCDLockWirelessDriver
+ IOCTLV_NCD_UNLOCKWIRELESSDRIVER = 0x2, // NCDUnlockWirelessDriver
+ IOCTLV_NCD_GETCONFIG = 0x3, // NCDiGetConfig
+ IOCTLV_NCD_SETCONFIG = 0x4, // NCDiSetConfig
+ IOCTLV_NCD_READCONFIG = 0x5,
+ IOCTLV_NCD_WRITECONFIG = 0x6,
+ IOCTLV_NCD_GETLINKSTATUS = 0x7, // NCDGetLinkStatus
+ IOCTLV_NCD_GETWIRELESSMACADDRESS = 0x8, // NCDGetWirelessMacAddress
};
network_config_t m_Ifconfig;
};
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#endif
+
#endif
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp
new file mode 100644
index 0000000000..7e59eb715a
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp
@@ -0,0 +1,467 @@
+// Copyright (C) 2003 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/
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4748)
+#pragma optimize("",off)
+#endif
+
+#include
+#include "FileUtil.h"
+#include "WII_IPC_HLE_Device_net_ssl.h"
+
+CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName)
+ : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+{
+ SSL_library_init();
+ sslfds[0] = NULL;
+ sslfds[1] = NULL;
+ sslfds[2] = NULL;
+ sslfds[3] = NULL;
+}
+
+CWII_IPC_HLE_Device_net_ssl::~CWII_IPC_HLE_Device_net_ssl()
+{
+}
+
+int CWII_IPC_HLE_Device_net_ssl::getSSLFreeID()
+{
+ for (int i = 0; i < NET_SSL_MAXINSTANCES; i++)
+ {
+ if (sslfds[i] == NULL)
+ return i + 1;
+ }
+ return 0;
+}
+bool CWII_IPC_HLE_Device_net_ssl::Open(u32 _CommandAddress, u32 _Mode)
+{
+ Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
+ m_Active = true;
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_net_ssl::Close(u32 _CommandAddress, bool _bForce)
+{
+ if (!_bForce)
+ Memory::Write_U32(0, _CommandAddress + 4);
+ m_Active = false;
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_net_ssl::IOCtl(u32 _CommandAddress)
+{
+ 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 Command = Memory::Read_U32(_CommandAddress + 0x0C);
+
+ u32 ReturnValue = ExecuteCommand(Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
+{
+ u32 ReturnValue = 0;
+ SIOCtlVBuffer CommandBuffer(_CommandAddress);
+
+ ReturnValue = ExecuteCommandV(CommandBuffer.Parameter, CommandBuffer);
+
+ Memory::Write_U32(ReturnValue, _CommandAddress+4);
+ return true;
+}
+
+u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer)
+{
+ u32 returnValue = 0;
+
+ u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
+ u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
+
+ u32 _BufferOut = 0, _BufferOut2 = 0, _BufferOut3 = 0;
+ u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;
+
+ if (CommandBuffer.InBuffer.size() > 0)
+ {
+ _BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
+ BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
+ }
+ if (CommandBuffer.InBuffer.size() > 1)
+ {
+ _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
+ BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
+ }
+ if (CommandBuffer.InBuffer.size() > 2)
+ {
+ _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address;
+ BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size;
+ }
+
+ if (CommandBuffer.PayloadBuffer.size() > 0)
+ {
+ _BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
+ BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
+ }
+ if (CommandBuffer.PayloadBuffer.size() > 1)
+ {
+ _BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
+ BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
+ }
+ if (CommandBuffer.PayloadBuffer.size() > 2)
+ {
+ _BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
+ BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
+ }
+
+ switch (_Parameter)
+ {
+ case IOCTLV_NET_SSL_NEW:
+ {
+ char in1[32];
+ char out1[32];
+ char out2[256];
+
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ Memory::ReadBigEData((u8*)out2, _BufferOut2, 256);
+
+ int freeSSL = this->getSSLFreeID();
+ if (freeSSL)
+ {
+ Memory::Write_U32(freeSSL, _BufferIn);
+
+ SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
+
+ //SSL_CTX_set_options(ctx,0);
+
+ SSL* ssl = SSL_new(ctx);
+ sslfds[freeSSL-1] = ssl;
+
+ }
+
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_NEW "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ case IOCTLV_NET_SSL_SHUTDOWN:
+ {
+ char in1[32];
+ char out1[32];
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ SSL_CTX* ctx = sslfds[sslID]->ctx;
+ SSL_shutdown(sslfds[sslID]);
+ if (ctx)
+ SSL_CTX_free(ctx);
+ sslfds[sslID] = NULL;
+ Memory::Write_U32(0, _BufferIn);
+ }
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_SHUTDOWN "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ case IOCTLV_NET_SSL_SETBUILTINCLIENTCERT:
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_SETBUILTINCLIENTCERT "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+
+ char in1[32];
+ char out1[32];
+ char out2[32];
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ Memory::ReadBigEData((u8*)out2, _BufferOut2, 32);
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ SSL* ssl = sslfds[sslID];
+
+ std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
+ FILE * clientca = fopen((cert_base_path + "clientca.cer").c_str(), "rb");
+ if (clientca == NULL)
+ break;
+
+ X509 *cert = d2i_X509_fp(clientca, NULL);
+ fclose(clientca);
+
+ FILE * clientcakey = fopen((cert_base_path + "clientcakey.der").c_str(), "rb");
+ if (clientcakey == NULL)
+ break;
+
+
+ EVP_PKEY * key = d2i_PrivateKey_fp(clientcakey, NULL);
+
+
+ if (SSL_use_certificate(ssl,cert) <= 0)
+ break;
+ if (SSL_use_PrivateKey(ssl,key) <= 0)
+ break;
+
+
+ if (!SSL_check_private_key(ssl))
+ break;
+
+ if (cert)
+ X509_free(cert);
+ if (key)
+ EVP_PKEY_free(key);
+
+ /*PKCS12 *p12;
+
+ FILE* f = fopen("c:\\wii_retail.p12", "rb");
+
+ if (!f)
+ break;
+
+
+ p12 = d2i_PKCS12_fp(f, NULL);
+ fclose(f);
+ if (!p12)
+ break;
+ EVP_PKEY *pkey = NULL;
+ X509 *cert = NULL;
+ STACK_OF(X509) *ca = sk_X509_new_null();
+
+ PKCS12_PBE_add();
+
+ if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
+ break;
+
+ if (cert) {
+ SSL_CTX_use_certificate(ssl->ctx, cert);
+ X509_free(cert);
+ }
+ if (pkey)
+{
+ SSL_CTX_use_PrivateKey(ssl->ctx, pkey);
+ EVP_PKEY_free(pkey);
+ }
+
+
+ for (int i = 0; i < sk_X509_num(ca); i++) {
+ X509 *cert2 = sk_X509_value(ca, i);
+
+ char buf[200];
+
+ X509_NAME_oneline(X509_get_subject_name(cert2), buf, sizeof(buf));
+ SSL_CTX_add_extra_chain_cert(ssl->ctx, cert2);
+
+ }
+ sk_X509_free(ca);
+
+ PKCS12_free(p12);
+ */
+
+ //SSL_CTX_use_certificate_chain_file(ssl->ctx, (char*)ssl->cert);
+ Memory::Write_U32(0, _BufferIn);
+ }
+ break;
+ }
+
+ case IOCTLV_NET_SSL_SETBUILTINROOTCA:
+ {
+ char in1[32];
+ char out1[32];
+ char out2[32];
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ Memory::ReadBigEData((u8*)out2, _BufferOut2, 32);
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+{
+
+ Memory::Write_U32(0, _BufferIn);
+ }
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_SETBUILTINROOTCA "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ case IOCTLV_NET_SSL_CONNECT:
+ {
+ char in1[32];
+ char out1[32];
+ char out2[32];
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ Memory::ReadBigEData((u8*)out2, _BufferOut2, 32);
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ int sock = Memory::Read_U32(_BufferOut2);
+ SSL* ssl = sslfds[sslID];
+ SSL_set_fd(ssl,sock);
+ returnValue = SSL_connect(ssl);
+ Memory::Write_U32(0, _BufferIn);
+ }
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_CONNECT "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ case IOCTLV_NET_SSL_DOHANDSHAKE:
+ {
+ char in1[32];
+ char out1[32];
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ SSL* ssl = sslfds[sslID];
+ returnValue = SSL_do_handshake(ssl);
+ if (returnValue == 1)
+ Memory::Write_U32(0, _BufferIn);
+ }
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_DOHANDSHAKE "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ case IOCTLV_NET_SSL_WRITE:
+ {
+ char in1[32];
+ char out1[32];
+ char out2[256];
+
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+ Memory::ReadBigEData((u8*)out2, _BufferOut2, 256);
+
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ SSL* ssl = sslfds[sslID];
+ returnValue = SSL_write(ssl, Memory::GetPointer(_BufferOut2), BufferOutSize2);
+ Memory::Write_U32(returnValue, _BufferIn);
+ returnValue = 0;
+ }
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_WRITE "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ INFO_LOG(WII_IPC_NET, "%s", Memory::GetPointer(_BufferOut2));
+ break;
+ }
+
+ case IOCTLV_NET_SSL_READ:
+ {
+ char in1[32];
+ char in2[256];
+ char out1[32];
+ memset(in2, 0, 256);
+ Memory::ReadBigEData((u8*)in1, _BufferIn, 32);
+ //Memory::ReadBigEData((u8*)in2, _BufferIn2, BufferInSize2);
+ Memory::ReadBigEData((u8*)out1, _BufferOut, 32);
+
+ int sslID = Memory::Read_U32(_BufferOut) - 1;
+ if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
+ {
+ SSL* ssl = sslfds[sslID];
+ returnValue = SSL_read(ssl, Memory::GetPointer(_BufferIn2), BufferInSize2);
+ Memory::Write_U32(returnValue, _BufferIn);
+ //returnValue = 0;
+ }
+ strncpy(in2, (char*)Memory::GetPointer(_BufferIn2), BufferInSize2);
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request IOCTLV_NET_SSL_READ(%d) %s "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ returnValue, in2,
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+
+ default:
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtlV request %x "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
+ "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
+ _Parameter,
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
+ _BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
+ break;
+ }
+ }
+ return returnValue;
+}
+
+u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommand(u32 _Command,
+ u32 _BufferIn, u32 BufferInSize,
+ u32 _BufferOut, u32 BufferOutSize)
+{
+ switch (_Command)
+ {
+ default:
+ {
+ INFO_LOG(WII_IPC_NET, "/dev/net/ssl::IOCtl request %x "
+ "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _Command,
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ break;
+ }
+ }
+ return 0;
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#endif
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h
new file mode 100644
index 0000000000..156892d0d5
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2003 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/
+
+#ifndef _WII_IPC_HLE_DEVICE_NET_SSL_H_
+#define _WII_IPC_HLE_DEVICE_NET_SSL_H_
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4748)
+#pragma optimize("",off)
+#endif
+
+#include "WII_IPC_HLE_Device.h"
+#include
+#include
+#include
+#include
+
+#define NET_SSL_MAXINSTANCES 4
+
+class CWII_IPC_HLE_Device_net_ssl : public IWII_IPC_HLE_Device
+{
+public:
+
+ CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName);
+
+ virtual ~CWII_IPC_HLE_Device_net_ssl();
+
+ virtual bool Open(u32 _CommandAddress, u32 _Mode);
+
+ virtual bool Close(u32 _CommandAddress, bool _bForce);
+
+ virtual bool IOCtl(u32 _CommandAddress);
+ virtual bool IOCtlV(u32 _CommandAddress);
+ int getSSLFreeID();
+
+private:
+ SSL * sslfds[NET_SSL_MAXINSTANCES];
+ enum
+ {
+ IOCTLV_NET_SSL_NEW = 0x01,
+ IOCTLV_NET_SSL_CONNECT = 0x02,
+ IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
+ IOCTLV_NET_SSL_READ = 0x04,
+ IOCTLV_NET_SSL_WRITE = 0x05,
+ IOCTLV_NET_SSL_SHUTDOWN = 0x06,
+ IOCTLV_NET_SSL_SETCLIENTCERT = 0x07,
+ IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT = 0x08,
+ IOCTLV_NET_SSL_REMOVECLIENTCERT = 0x09,
+ IOCTLV_NET_SSL_SETROOTCA = 0x0A,
+ IOCTLV_NET_SSL_SETROOTCADEFAULT = 0x0B,
+ IOCTLV_NET_SSL_DOHANDSHAKEEX = 0x0C,
+ IOCTLV_NET_SSL_SETBUILTINROOTCA = 0x0D,
+ IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = 0x0E,
+ IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
+ IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
+ IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
+ };
+
+
+ u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
+ u32 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);
+};
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+#endif
diff --git a/Source/Core/Core/Src/IPC_HLE/fakepoll.h b/Source/Core/Core/Src/IPC_HLE/fakepoll.h
new file mode 100644
index 0000000000..25bf123567
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/fakepoll.h
@@ -0,0 +1,178 @@
+// fakepoll.h
+// poll using select
+//Matthew Parlane sourced this from http://www.sealiesoftware.com/
+//Was listed as "Public domain." as of 31/07/2010
+
+// Warning: a call to this poll() takes about 4K of stack space.
+
+// Greg Parker gparker-web@sealiesoftware.com December 2000
+// This code is in the public domain and may be copied or modified without
+// permission.
+
+// Updated May 2002:
+// * fix crash when an fd is less than 0
+// * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
+// * don't set POLLIN or POLLOUT in revents if it wasn't requested
+// in events (only happens when an fd is in the poll set twice)
+
+#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+
+#ifndef _FAKE_POLL_H
+#define _FAKE_POLL_H
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4748)
+#pragma optimize("",off)
+#endif
+
+#include
+#include
+#include
+
+typedef struct pollfd {
+ int fd; /* file desc to poll */
+ short events; /* events of interest on fd */
+ short revents; /* events that occurred on fd */
+} pollfd_t;
+
+#define EINVAL 22
+// poll flags
+#define POLLIN 0x0001
+#define POLLOUT 0x0008
+#define POLLERR 0x0040
+
+// synonyms
+#define POLLNORM POLLIN
+#define POLLPRI POLLIN
+#define POLLRDNORM POLLIN
+#define POLLRDBAND POLLIN
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND POLLOUT
+
+// ignored
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+inline int poll(struct pollfd *pollSet, int pollCount, int pollTimeout)
+{
+ struct timeval tv;
+ struct timeval *tvp;
+ fd_set readFDs, writeFDs, exceptFDs;
+ fd_set *readp, *writep, *exceptp;
+ struct pollfd *pollEnd, *p;
+ int selected;
+ int result;
+ int maxFD;
+
+ if (!pollSet) {
+ pollEnd = NULL;
+ readp = NULL;
+ writep = NULL;
+ exceptp = NULL;
+ maxFD = 0;
+ }
+ else {
+ pollEnd = pollSet + pollCount;
+ readp = &readFDs;
+ writep = &writeFDs;
+ exceptp = &exceptFDs;
+
+ FD_ZERO(readp);
+ FD_ZERO(writep);
+ FD_ZERO(exceptp);
+
+ // Find the biggest fd in the poll set
+ maxFD = 0;
+ for (p = pollSet; p < pollEnd; p++) {
+ if (p->fd > maxFD) maxFD = p->fd;
+ }
+
+ // Transcribe flags from the poll set to the fd sets
+ for (p = pollSet; p < pollEnd; p++) {
+ if (p->fd < 0) {
+ // Negative fd checks nothing and always reports zero
+ } else {
+ if (p->events & POLLIN) FD_SET(p->fd, readp);
+ if (p->events & POLLOUT) FD_SET(p->fd, writep);
+ if (p->events != 0) FD_SET(p->fd, exceptp);
+ // POLLERR is never set coming in; poll() always reports errors
+ // But don't report if we're not listening to anything at all.
+ }
+ }
+ }
+
+ // poll timeout is in milliseconds. Convert to struct timeval.
+ // poll timeout == -1 : wait forever : select timeout of NULL
+ // poll timeout == 0 : return immediately : select timeout of zero
+ if (pollTimeout >= 0) {
+ tv.tv_sec = pollTimeout / 1000;
+ tv.tv_usec = (pollTimeout % 1000) * 1000;
+ tvp = &tv;
+ } else {
+ tvp = NULL;
+ }
+
+
+ selected = select(maxFD+1, readp, writep, exceptp, tvp);
+
+
+ if (selected < 0) {
+ // Error during select
+ result = -1;
+ }
+ else if (selected > 0) {
+ // Select found something
+ // Transcribe result from fd sets to poll set.
+ // Also count the number of selected fds. poll returns the
+ // number of ready fds; select returns the number of bits set.
+ int polled = 0;
+ for (p = pollSet; p < pollEnd; p++) {
+ p->revents = 0;
+ if (p->fd < 0) {
+ // Negative fd always reports zero
+ } else {
+ int isToRead = FD_ISSET(p->fd, readp);
+ if ((p->events & POLLIN) && isToRead) {
+ p->revents |= POLLIN;
+ }
+
+ int isToWrite = FD_ISSET(p->fd, writep);
+ if ((p->events & POLLOUT) && isToWrite) {
+ p->revents |= POLLOUT;
+ }
+
+ int isToError = FD_ISSET(p->fd, exceptp);
+ if ((p->events != 0) && isToError) {
+ p->revents |= POLLERR;
+ }
+
+ if (p->revents) polled++;
+ }
+ }
+ result = polled;
+ }
+ else {
+ // selected == 0, select timed out before anything happened
+ // Clear all result bits and return zero.
+ for (p = pollSet; p < pollEnd; p++) {
+ p->revents = 0;
+
+ }
+ result = 0;
+ }
+ return result;
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",on)
+#endif
+
+
+#endif
+
+#else // (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+
+typedef pollfd pollfd_t;
+#define poll WSAPoll
+
+#endif
diff --git a/Source/VSProps/CodeGen_Debug.props b/Source/VSProps/CodeGen_Debug.props
index 9c321b75aa..ea95e744b7 100644
--- a/Source/VSProps/CodeGen_Debug.props
+++ b/Source/VSProps/CodeGen_Debug.props
@@ -10,6 +10,9 @@
Disabled
false
+
+ libeay32d.lib;ssleay32d.lib;%(AdditionalDependencies)
+
\ No newline at end of file
diff --git a/Source/VSProps/CodeGen_DebugFast.props b/Source/VSProps/CodeGen_DebugFast.props
index dc534c6a85..d6203032d3 100644
--- a/Source/VSProps/CodeGen_DebugFast.props
+++ b/Source/VSProps/CodeGen_DebugFast.props
@@ -11,6 +11,9 @@
MultiThreaded
false
+
+ libeay32.lib;ssleay32.lib;%(AdditionalDependencies)
+
\ No newline at end of file
diff --git a/Source/VSProps/CodeGen_Release.props b/Source/VSProps/CodeGen_Release.props
index 74770b6910..df94824093 100644
--- a/Source/VSProps/CodeGen_Release.props
+++ b/Source/VSProps/CodeGen_Release.props
@@ -24,6 +24,7 @@
true
true
+ libeay32.lib;ssleay32.lib;%(AdditionalDependencies)
diff --git a/Source/VSProps/Dolphin.Win32.props b/Source/VSProps/Dolphin.Win32.props
index 8908f84c94..fead4baff9 100644
--- a/Source/VSProps/Dolphin.Win32.props
+++ b/Source/VSProps/Dolphin.Win32.props
@@ -7,7 +7,7 @@
- ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)
+ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName);..\..\..\Externals\openssl\$(PlatformName)
portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies)
diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props
index b729ff4414..336fd2c1c4 100644
--- a/Source/VSProps/Dolphin.x64.props
+++ b/Source/VSProps/Dolphin.x64.props
@@ -8,7 +8,7 @@
- ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)
+ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName);..\..\..\Externals\openssl\$(PlatformName)
portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies)