summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp12
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp1654
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h87
3 files changed, 733 insertions, 1020 deletions
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 9c1072f030..83e2fa9092 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -535,14 +535,14 @@ void ExecuteCommand(u32 _Address)
}
}
+ // It seems that the original hardware overwrites the command after it has been
+ // executed. We write 8 which is not any valid command, and what IOS does
+ Memory::Write_U32(8, _Address);
+ // IOS seems to write back the command that was responded to
+ Memory::Write_U32(Command, _Address + 8);
+
if (CmdSuccess)
{
- // It seems that the original hardware overwrites the command after it has been
- // executed. We write 8 which is not any valid command, and what IOS does
- Memory::Write_U32(8, _Address);
- // IOS seems to write back the command that was responded to
- Memory::Write_U32(Command, _Address + 8);
-
// Ensure replies happen in order, fairly ugly
// Without this, tons of games fail now that DI commads have different reply delays
int reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
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 e7a9896fae..fa4c98dac2 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
@@ -55,7 +55,6 @@ it failed)
#include "ICMP.h"
#include "CommonPaths.h"
#include "SettingsHandler.h"
-#include "WII_IPC_HLE.h"
#include "ec_wii.h"
@@ -90,10 +89,6 @@ typedef struct pollfd pollfd_t;
#include <errno.h>
#endif
-#ifdef _WIN32
-#define SHUT_RDWR SD_BOTH
-#endif
-
extern std::queue<std::pair<u32,std::string> > g_ReplyQueueLater;
const u8 default_address[] = { 0x00, 0x17, 0xAB, 0x99, 0x99, 0x99 };
@@ -108,30 +103,30 @@ 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)
+bool CWII_IPC_HLE_Device_net_kd_request::Open(u32 _CommandAddress, u32 _Mode)
{
INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: Open");
- Memory::Write_U32(GetDeviceID(), CommandAddress + 4);
+ Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
m_Active = true;
return true;
}
-bool CWII_IPC_HLE_Device_net_kd_request::Close(u32 CommandAddress, bool _bForce)
+bool CWII_IPC_HLE_Device_net_kd_request::Close(u32 _CommandAddress, bool _bForce)
{
INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: Close");
if (!_bForce)
- Memory::Write_U32(0, CommandAddress + 4);
+ Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}
-bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 CommandAddress)
+bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
{
- 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 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 = 0;
switch (Parameter)
@@ -250,8 +245,8 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 CommandAddress)
break;
}
- // g_ReplyQueueLater.push(std::pair<u32, std::string>(CommandAddress, GetDeviceName()));
- Memory::Write_U32(ReturnValue, CommandAddress + 4);
+ // g_ReplyQueueLater.push(std::pair<u32, std::string>(_CommandAddress, GetDeviceName()));
+ Memory::Write_U32(ReturnValue, _CommandAddress + 4);
return true;
}
@@ -367,30 +362,30 @@ 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)
+bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open");
- Memory::Write_U32(GetDeviceID(), CommandAddress+4);
+ Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
}
-bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 CommandAddress, bool _bForce)
+bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 _CommandAddress, bool _bForce)
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close");
if (!_bForce)
- Memory::Write_U32(0, CommandAddress + 4);
+ Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}
-bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 CommandAddress)
+bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
{
u32 return_value = 0;
u32 common_result = 0;
u32 common_vector = 0;
- SIOCtlVBuffer CommandBuffer(CommandAddress);
+ SIOCtlVBuffer CommandBuffer(_CommandAddress);
switch (CommandBuffer.Parameter)
{
@@ -476,7 +471,7 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 CommandAddress)
Memory::Write_U32(common_result,
CommandBuffer.PayloadBuffer.at(common_vector).m_Address + 4);
}
- Memory::Write_U32(return_value, CommandAddress + 4);
+ Memory::Write_U32(return_value, _CommandAddress + 4);
return true;
}
@@ -607,13 +602,6 @@ CWII_IPC_HLE_Device_net_ip_top::CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, co
int ret = WSAStartup(MAKEWORD(2,2), &InitData);
INFO_LOG(WII_IPC_NET, "WSAStartup: %d", ret);
#endif
-
- u32 s = 0xDEADBEEF;
- std::lock_guard<std::mutex> lk(socketMapMutex);
- _tSocket* sock = new _tSocket();
- socketMap[s] = sock;
- sock->thread = new std::thread([this, s]{this->processSocket(s);});
-
}
CWII_IPC_HLE_Device_net_ip_top::~CWII_IPC_HLE_Device_net_ip_top()
@@ -621,61 +609,150 @@ CWII_IPC_HLE_Device_net_ip_top::~CWII_IPC_HLE_Device_net_ip_top()
#ifdef _WIN32
WSACleanup();
#endif
-
- std::lock_guard<std::mutex> lk(socketMapMutex);
- auto i = socketMap.begin();
- while(i != socketMap.end())
- {
- u32 s = i->first;
- _tSocket * sock = i->second;
- if(s != 0xDEADBEEF)
- {
- (void)shutdown(s, SHUT_RDWR);
- #ifdef _WIN32
- (void)closesocket(s);
- #else
- (void)close(s);
- #endif
- }
-
- sock->StopAndJoin();
- delete sock;
- socketMap.erase(i++);
- }
}
-bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 CommandAddress, u32 _Mode)
+bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
{
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open");
- Memory::Write_U32(GetDeviceID(), CommandAddress+4);
+ Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
}
-bool CWII_IPC_HLE_Device_net_ip_top::Close(u32 CommandAddress, bool _bForce)
+bool CWII_IPC_HLE_Device_net_ip_top::Close(u32 _CommandAddress, bool _bForce)
{
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close");
if (!_bForce)
- Memory::Write_U32(0, CommandAddress + 4);
+ Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}
+bool CWII_IPC_HLE_Device_net_ip_top::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;
+}
+
+struct bind_params
+{
+ u32 socket;
+ u32 has_name;
+ u8 name[28];
+};
+
+struct GC_sockaddr
+{
+ u8 sa_len;
+ u8 sa_family;
+ s8 sa_data[14];
+};
+
+struct GC_in_addr
+{
+ // this cannot be named s_addr under windows - collides with some crazy define.
+ u32 s_addr_;
+};
+
+struct GC_sockaddr_in
+{
+ u8 sin_len;
+ u8 sin_family;
+ u16 sin_port;
+ struct GC_in_addr sin_addr;
+ s8 sin_zero[8];
+};
+
+char* DecodeError(int ErrorCode)
+{
+
+#ifdef _WIN32
+ 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;
+#else
+ return strerror(ErrorCode);
+#endif
+}
+
+static int getNetErrorCode(int ret, std::string caller, bool isRW)
+{
+#ifdef _WIN32
+ int errorCode = WSAGetLastError();
+#else
+ int errorCode = errno;
+#endif
+
+ if (ret >= 0)
+ return ret;
+
+ WARN_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d",
+ caller.c_str(), errorCode, DecodeError(errorCode), ret);
+
+#ifdef _WIN32
+#define ERRORCODE(name) WSA ## name
+#define EITHER(win32, posix) win32
+#else
+#define ERRORCODE(name) name
+#define EITHER(win32, posix) posix
+#endif
+
+ switch (errorCode)
+ {
+ case ERRORCODE(EMSGSIZE):
+ WARN_LOG(WII_IPC_NET, "Find out why this happened, looks like PEEK failure?");
+ return -1;
+ case ERRORCODE(ECONNRESET):
+ return -15; // ECONNRESET
+ case ERRORCODE(EISCONN):
+ return -30; // EISCONN
+ case ERRORCODE(ENOTCONN):
+ return -6; // EAGAIN
+ case EITHER(WSAEWOULDBLOCK, EAGAIN):
+ case ERRORCODE(EINPROGRESS):
+ if(isRW){
+ return -6; // EAGAIN
+ }else{
+ return -26; // EINPROGRESS
+ }
+ case EITHER(WSA_INVALID_HANDLE, EBADF):
+ return -26; // EINPROGRESS
+ default:
+ return -1;
+ }
+
+#undef ERRORCODE
+#undef EITHER
+}
+
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;
@@ -711,467 +788,517 @@ static unsigned int opt_name_mapping[][2] = {
{ SO_ERROR, 0x1009 }
};
-
-bool CWII_IPC_HLE_Device_net_ip_top::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);
- s32 ReturnValue = 0;
-
- switch (Command)
+u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command,
+ u32 _BufferIn, u32 BufferInSize,
+ u32 _BufferOut, u32 BufferOutSize)
+{
+ switch (_Command)
{
- case IOCTL_SO_CONNECT:
- case IOCTL_SO_ACCEPT:
+ case IOCTL_SO_STARTUP:
+ WARN_LOG(WII_IPC_NET, "IOCTL_SO_STARTUP "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ break;
+
+ case IOCTL_SO_CONNECT:
{
- u32 s = Memory::Read_U32(BufferIn);
- _tSocket * sock = NULL;
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- if(socketMap.find(s) != socketMap.end())
- sock = socketMap[s];
- }
- if(sock)
- {
- sock->addCommand(CommandAddress);
- return false;
- }
- else
+ //struct sockaddr_in echoServAddr;
+ struct connect_params
{
- ReturnValue = -8; // EBADF
- }
-
- ERROR_LOG(WII_IPC_NET, "Failed to find socket %d %08X", s, Command);
+ u32 socket;
+ u32 has_addr;
+ u8 addr[28];
+ } params;
+ sockaddr_in serverAddr;
+
+ Memory::ReadBigEData((u8*)&params, _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));
+ ret = getNetErrorCode(ret, "SO_CONNECT", false);
+ WARN_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT (%08x, %s:%d)",
+ Common::swap32(params.socket), inet_ntoa(serverAddr.sin_addr), Common::swap16(serverAddr.sin_port));
+ return ret;
break;
}
- case IOCTL_SO_POLL:
+
+ case IOCTL_SO_SHUTDOWN:
{
- u32 s = 0xDEADBEEF;
- _tSocket * sock = NULL;
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- if(socketMap.find(s) != socketMap.end())
- sock = socketMap[s];
- }
- if(sock)
- {
- sock->addCommand(CommandAddress);
- return false;
- }
- else
- {
- ReturnValue = -8; // EBADF
- }
-
- ERROR_LOG(WII_IPC_NET, "Failed to find socket %d %08X", s, Command);
+ WARN_LOG(WII_IPC_NET, "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", false);
break;
}
-
- case IOCTL_SO_SOCKET:
+
+ case IOCTL_SO_CLOSE:
{
- u32 AF = Memory::Read_U32(BufferIn);
- u32 TYPE = Memory::Read_U32(BufferIn + 0x04);
- u32 PROT = Memory::Read_U32(BufferIn + 0x08);
+ u32 sock = Memory::Read_U32(_BufferIn);
+ WARN_LOG(WII_IPC_NET, "IOCTL_SO_CLOSE (%08x)", sock);
+
+#ifdef _WIN32
+ u32 ret = closesocket(sock);
+
+ return getNetErrorCode(ret, "IOCTL_SO_CLOSE", false);
+#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 + 0x08);
u32 s = (u32)socket(AF, TYPE, PROT);
WARN_LOG(WII_IPC_NET, "IOCTL_SO_SOCKET "
- "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- s, AF, TYPE, PROT, BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ s, AF, TYPE, PROT, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
- ReturnValue = getNetErrorCode(s, "SO_SOCKET", false);
-
- if (ReturnValue > 0)
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- _tSocket* sock = new _tSocket();
- socketMap[s] = sock;
- sock->thread = new std::thread([this, s]{this->processSocket(s);});
+ int ret = getNetErrorCode(s, "SO_SOCKET", false);
+ if(ret>=0){
+#ifdef _WIN32
+ u32 millis = 3000;
+#else
+ struct timeval millis;
+ millis.tv_sec = 3;
+ millis.tv_usec = 0;
+#endif
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis,sizeof(millis));
}
- break;
- }
- case IOCTL_SO_STARTUP:
- {
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_STARTUP "
- "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- BufferIn, BufferInSize, BufferOut, BufferOutSize);
- break;
- }
-
- case IOCTL_SO_SHUTDOWN:
- {
- WARN_LOG(WII_IPC_NET, "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);
- ReturnValue = shutdown(sock, how);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_SHUTDOWN", false);
- break;
- }
-
- case IOCTL_SO_CLOSE:
- {
- u32 s = Memory::Read_U32(BufferIn);
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_CLOSE (%08x)", s);
- ReturnValue = shutdown(s, SHUT_RDWR);
- #ifdef _WIN32
- ReturnValue = closesocket(s);
- #else
- ReturnValue = close(s);
- #endif
-
- ReturnValue = getNetErrorCode(ReturnValue, "IOCTL_SO_CLOSE", false);
-
- _tSocket * sock = NULL;
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- if(socketMap.find(s) != socketMap.end())
- sock = socketMap[s];
- if(sock)
- {
- //cascading failures hopefully
- sock->StopAndJoin();
- delete sock;
- socketMap.erase(s);
- }
- }
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_CLOSE finished (%08x) = ", s, ReturnValue);
-
+ return ret;
break;
}
- case IOCTL_SO_BIND:
+
+ case IOCTL_SO_BIND:
{
- bind_params *addr = (bind_params*)Memory::GetPointer(BufferIn);
+ 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;
-
- ReturnValue = bind(Common::swap32(addr->socket), (sockaddr*)&address, sizeof(address));
-
+ int ret = bind(Common::swap32(addr->socket), (sockaddr*)&address, sizeof(address));
+
WARN_LOG(WII_IPC_NET, "IOCTL_SO_BIND (%s:%d) = %d "
- "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- inet_ntoa(address.sin_addr), Common::swap16(address.sin_port), ReturnValue,
- Common::swap32(addr->socket), BufferIn, BufferInSize, BufferOut, BufferOutSize);
-
- ReturnValue = getNetErrorCode(ReturnValue, "SO_BIND", false);
+ "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ inet_ntoa(address.sin_addr), Common::swap16(address.sin_port), ret,
+ Common::swap32(addr->socket), _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ return getNetErrorCode(ret, "SO_BIND", false);
break;
}
-
- case IOCTL_SO_LISTEN:
+
+ case IOCTL_SO_LISTEN:
{
WARN_LOG(WII_IPC_NET, "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);
- ReturnValue = listen(S, BACKLOG);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_LISTEN", false);
+ "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", false);
break;
}
-
- case IOCTL_SO_GETSOCKOPT:
+
+ case IOCTL_SO_ACCEPT:
{
- u32 sock = Memory::Read_U32(BufferOut);
- u32 level = Memory::Read_U32(BufferOut + 4);
- u32 optname = Memory::Read_U32(BufferOut + 8);
-
+ WARN_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT "
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
+ 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", false);
+ }
+
+ case IOCTL_SO_GETSOCKOPT:
+ {
+ u32 sock = Memory::Read_U32(_BufferOut);
+ u32 level = Memory::Read_U32(_BufferOut + 4);
+ u32 optname = Memory::Read_U32(_BufferOut + 8);
+
WARN_LOG(WII_IPC_NET,"IOCTL_SO_GETSOCKOPT(%08x, %08x, %08x)"
- "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- sock, level, optname,
- BufferIn, BufferInSize, BufferOut, BufferOutSize);
-
+ "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ sock, level, optname,
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
// Do the level/optname translation
int nat_level = -1, nat_optname = -1;
-
+
for (unsigned int i = 0; i < sizeof (opt_level_mapping) / sizeof (opt_level_mapping[0]); ++i)
if (level == opt_level_mapping[i][1])
nat_level = opt_level_mapping[i][0];
-
- for (unsigned int i = 0; i < sizeof (opt_name_mapping) / sizeof (opt_name_mapping[0]); ++i)
- if (optname == opt_name_mapping[i][1])
- nat_optname = opt_name_mapping[i][0];
-
- u8 optval[20];
- u32 optlen = 4;
-
- ReturnValue = getsockopt (sock, nat_level, nat_optname, (char *) &optval, (socklen_t*)&optlen);
-
- ReturnValue = getNetErrorCode(ReturnValue, "SO_GETSOCKOPT", false);
-
-
- Memory::Write_U32(optlen, BufferOut + 0xC);
- Memory::WriteBigEData((u8 *) optval, BufferOut + 0x10, optlen);
-
+
+ for (unsigned int i = 0; i < sizeof (opt_name_mapping) / sizeof (opt_name_mapping[0]); ++i)
+ if (optname == opt_name_mapping[i][1])
+ nat_optname = opt_name_mapping[i][0];
+
+ u8 optval[20];
+ u32 optlen = 4;
+
+ int ret = getsockopt (sock, nat_level, nat_optname, (char *) &optval, (socklen_t*)&optlen);
+
+ ret = getNetErrorCode(ret, "SO_GETSOCKOPT", false);
+
+
+ Memory::Write_U32(optlen, _BufferOut + 0xC);
+ Memory::WriteBigEData((u8 *) optval, _BufferOut + 0x10, optlen);
+
if(optname == 0x1007){
- s32 errorcode = Memory::Read_U32(BufferOut + 0x10);
+ s32 errorcode = Memory::Read_U32(_BufferOut + 0x10);
WARN_LOG(WII_IPC_NET,"IOCTL_SO_GETSOCKOPT error code = %i", errorcode);
}
- break;
+ return ret;
}
-
- case IOCTL_SO_SETSOCKOPT:
+
+ 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);
+ 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);
-
+ Memory::ReadBigEData(optval, _BufferIn + 0x10, optlen);
+
//TODO: bug booto about this, 0x2005 most likely timeout related, default value on wii is , 0x2001 is most likely tcpnodelay
if (level == 6 && (optname == 0x2005 || optname == 0x2001)){
- ReturnValue = 0;
- break;
+ return 0;
}
WARN_LOG(WII_IPC_NET, "IOCTL_SO_SETSOCKOPT(%08x, %08x, %08x, %08x) "
"BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
"%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
- S, level, optname, optlen, BufferIn, BufferInSize, BufferOut, BufferOutSize,
- optval[0], optval[1], optval[2], optval[3],
- optval[4], optval[5], optval[6], optval[7],
- optval[8], optval[9], optval[10], optval[11],
- optval[12], optval[13], optval[14], optval[15],
- optval[16], optval[17], optval[18], optval[19]);
-
+ S, level, optname, optlen, _BufferIn, BufferInSize, _BufferOut, BufferOutSize, optval[0], optval[1], optval[2], optval[3], optval[4], optval[5], optval[6], optval[7], optval[8], optval[9], optval[10], optval[11], optval[12], optval[13], optval[14], optval[15], optval[16], optval[17], optval[18], optval[19]);
+
// Do the level/optname translation
int nat_level = -1, nat_optname = -1;
-
+
for (unsigned int i = 0; i < sizeof (opt_level_mapping) / sizeof (opt_level_mapping[0]); ++i)
if (level == opt_level_mapping[i][1])
nat_level = opt_level_mapping[i][0];
-
+
for (unsigned int i = 0; i < sizeof (opt_name_mapping) / sizeof (opt_name_mapping[0]); ++i)
if (optname == opt_name_mapping[i][1])
nat_optname = opt_name_mapping[i][0];
-
+
if (nat_level == -1 || nat_optname == -1)
{
WARN_LOG(WII_IPC_NET, "SO_SETSOCKOPT: unknown level %d or optname %d", level, optname);
-
+
// Default to the given level/optname. They match on Windows...
nat_level = level;
nat_optname = optname;
}
-
- ReturnValue = setsockopt(S, nat_level, nat_optname, (char*)optval, optlen);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_SETSOCKOPT", false);
-
- break;
+
+ int ret = setsockopt(S, nat_level, nat_optname, (char*)optval, optlen);
+
+ ret = getNetErrorCode(ret, "SO_SETSOCKOPT", false);
+
+ return ret;
}
-
- case IOCTL_SO_FCNTL:
+
+ case IOCTL_SO_FCNTL:
{
- u32 sock = Memory::Read_U32(BufferIn);
- u32 cmd = Memory::Read_U32(BufferIn + 4);
- u32 arg = Memory::Read_U32(BufferIn + 8);
-
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 cmd = Memory::Read_U32(_BufferIn + 4);
+ u32 arg = Memory::Read_U32(_BufferIn + 8);
+
WARN_LOG(WII_IPC_NET, "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)
- {
- WARN_LOG(WII_IPC_NET, "F_GETFL WTF?");
- }
- else if (cmd == F_SETFL)
- {
- u_long iMode = 0;
- if (arg & F_NONBLOCK)
- iMode = 1;
- ReturnValue = ioctlsocket(sock, FIONBIO, &iMode);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_FCNTL", false);
- }
- else
- {
- WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command");
- }
- #else
- // Map POSIX <-> Wii socket flags
- // First one is POSIX, second one is Wii
- static int mapping[][2] = {
- { O_NONBLOCK, 0x4 },
- };
-
- if (cmd == F_GETFL)
- {
- int flags = fcntl(sock, F_GETFL, 0);
- ReturnValue = 0;
-
- for (unsigned int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i)
- if (flags & mapping[i][0])
- ReturnValue |= mapping[i][1];
- }
- else if (cmd == F_SETFL)
+ "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)
+ {
+ WARN_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", false);
+ }
+ else
+ {
+ WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command");
+ }
+ return 0;
+#else
+ // Map POSIX <-> Wii socket flags
+ // First one is POSIX, second one is Wii
+ static int mapping[][2] = {
+ { O_NONBLOCK, 0x4 },
+ };
+
+ if (cmd == F_GETFL)
+ {
+ int flags = fcntl(sock, F_GETFL, 0);
+ int ret = 0;
+
+ for (unsigned int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i)
+ if (flags & mapping[i][0])
+ ret |= mapping[i][1];
+ return ret;
+ }
+ else if (cmd == F_SETFL)
+ {
+ int posix_flags = O_NONBLOCK; //0;
+
+ for (unsigned int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i)
{
- int posix_flags = 0;
-
- for (unsigned int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i)
+ if (arg & mapping[i][1])
{
- if (arg & mapping[i][1])
- {
- posix_flags |= mapping[i][0];
- arg &= ~mapping[i][1];
- }
+ posix_flags |= mapping[i][0];
+ arg &= ~mapping[i][1];
}
-
- if (arg)
- WARN_LOG(WII_IPC_NET, "SO_FCNTL F_SETFL unhandled flags: %08x", arg);
-
- ReturnValue = fcntl(sock, F_SETFL, posix_flags);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_FCNTL", false);
}
- else
- {
- WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command");
- }
- #endif
- break;
+
+ if (arg)
+ WARN_LOG(WII_IPC_NET, "SO_FCNTL F_SETFL unhandled flags: %08x", arg);
+
+ int ret = fcntl(sock, F_SETFL, posix_flags);
+ return getNetErrorCode(ret, "SO_FCNTL", false);
+ }
+ else
+ {
+ WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command");
+ }
+ return 0;
+#endif
}
-
- case IOCTL_SO_GETSOCKNAME:
+
+ case IOCTL_SO_GETSOCKNAME:
{
- u32 sock = Memory::Read_U32(BufferIn);
-
+ u32 sock = Memory::Read_U32(_BufferIn);
+
WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKNAME "
- "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- sock, BufferIn, BufferInSize, BufferOut, BufferOutSize);
-
+ "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ sock, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
sockaddr sa;
socklen_t sa_len;
sa_len = sizeof(sa);
- ReturnValue = getsockname(sock, &sa, &sa_len);
-
- Memory::Write_U8(BufferOutSize, BufferOut);
- Memory::Write_U8(sa.sa_family & 0xFF, BufferOut + 1);
- Memory::WriteBigEData((u8*)&sa.sa_data, BufferOut + 2, BufferOutSize - 2);
- break;
+ int ret = getsockname(sock, &sa, &sa_len);
+
+ Memory::Write_U8(BufferOutSize, _BufferOut);
+ Memory::Write_U8(sa.sa_family & 0xFF, _BufferOut + 1);
+ Memory::WriteBigEData((u8*)&sa.sa_data, _BufferOut + 2, BufferOutSize - 2);
+ return ret;
}
- case IOCTL_SO_GETPEERNAME:
+ case IOCTL_SO_GETPEERNAME:
{
- u32 sock = Memory::Read_U32(BufferIn);
-
+ u32 sock = Memory::Read_U32(_BufferIn);
+
sockaddr sa;
socklen_t sa_len;
sa_len = sizeof(sa);
-
- ReturnValue = getpeername(sock, &sa, &sa_len);
- ReturnValue = getNetErrorCode(ReturnValue, "IOCTL_SO_GETPEERNAME", false);
-
- Memory::Write_U8(BufferOutSize, BufferOut);
- Memory::Write_U8(AF_INET, BufferOut + 1);
- Memory::WriteBigEData((u8*)&sa.sa_data, BufferOut + 2, BufferOutSize - 2);
+
+ int ret = getpeername(sock, &sa, &sa_len);
+
+ Memory::Write_U8(BufferOutSize, _BufferOut);
+ Memory::Write_U8(AF_INET, _BufferOut + 1);
+ Memory::WriteBigEData((u8*)&sa.sa_data, _BufferOut + 2, BufferOutSize - 2);
WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETPEERNAME(%x)", sock);
-
- break;
+
+ return ret;
}
- case IOCTL_SO_GETHOSTID:
+
+ case IOCTL_SO_GETHOSTID:
{
WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTID "
- "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- BufferIn, BufferInSize, BufferOut, BufferOutSize);
- ReturnValue = 192 << 24 | 168 << 16 | 1 << 8 | 150;
- break;
+ "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ return 192 << 24 | 168 << 16 | 1 << 8 | 150;
}
- case IOCTL_SO_INETATON:
+
+ case IOCTL_SO_INETATON:
{
- struct hostent *remoteHost = gethostbyname((char*)Memory::GetPointer(BufferIn));
-
- Memory::Write_U32(Common::swap32(*(u32 *)remoteHost->h_addr_list[0]), BufferOut);
+ struct hostent *remoteHost = gethostbyname((char*)Memory::GetPointer(_BufferIn));
+
+ Memory::Write_U32(Common::swap32(*(u32 *)remoteHost->h_addr_list[0]), _BufferOut);
WARN_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = %d "
- "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X",remoteHost->h_addr_list[0] == 0 ? -1 : 0,
- (char*)Memory::GetPointer(BufferIn), BufferIn, BufferInSize, BufferOut, BufferOutSize, Common::swap32(*(u32 *)remoteHost->h_addr_list[0]));
- ReturnValue = remoteHost->h_addr_list[0] == 0 ? 0 : 1;
- break;
+ "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X",remoteHost->h_addr_list[0] == 0 ? -1 : 0,
+ (char*)Memory::GetPointer(_BufferIn), _BufferIn, BufferInSize, _BufferOut, BufferOutSize, Common::swap32(*(u32 *)remoteHost->h_addr_list[0]));
+ return remoteHost->h_addr_list[0] == 0 ? 0 : 1;
}
- case IOCTL_SO_INETPTON:
+
+ case IOCTL_SO_INETPTON:
{
WARN_LOG(WII_IPC_NET, "IOCTL_SO_INETPTON "
- "(Translating: %s)", Memory::GetPointer(BufferIn));
- ReturnValue = inet_pton((char*)Memory::GetPointer(BufferIn), Memory::GetPointer(BufferOut+4));
+ "(Translating: %s)", Memory::GetPointer(_BufferIn));
+ return inet_pton((char*)Memory::GetPointer(_BufferIn), Memory::GetPointer(_BufferOut+4));
break;
}
- case IOCTL_SO_INETNTOP:
+
+ case IOCTL_SO_INETNTOP:
{
- u32 af = Memory::Read_U32(BufferIn);
- //u32 af = Memory::Read_U32(BufferIn + 4);
- u32 src = Memory::Read_U32(BufferIn + 8);
- //u32 af = Memory::Read_U32(BufferIn + 12);
- //u32 af = Memory::Read_U32(BufferIn + 16);
- //u32 af = Memory::Read_U32(BufferIn + 20);
+ u32 af = Memory::Read_U32(_BufferIn);
+ //u32 af = Memory::Read_U32(_BufferIn + 4);
+ u32 src = Memory::Read_U32(_BufferIn + 8);
+ //u32 af = Memory::Read_U32(_BufferIn + 12);
+ //u32 af = Memory::Read_U32(_BufferIn + 16);
+ //u32 af = Memory::Read_U32(_BufferIn + 20);
char ip_s[16];
sprintf(ip_s, "%i.%i.%i.%i",
- Memory::Read_U8(BufferIn + 8),
- Memory::Read_U8(BufferIn + 8 + 1),
- Memory::Read_U8(BufferIn + 8 + 2),
- Memory::Read_U8(BufferIn + 8 + 3)
- );
+ Memory::Read_U8(_BufferIn + 8),
+ Memory::Read_U8(_BufferIn + 8 + 1),
+ Memory::Read_U8(_BufferIn + 8 + 2),
+ Memory::Read_U8(_BufferIn + 8 + 3)
+ );
WARN_LOG(WII_IPC_NET, "IOCTL_SO_INETNTOP %s", ip_s);
- memset(Memory::GetPointer(BufferOut), 0, BufferOutSize);
- memcpy(Memory::GetPointer(BufferOut), ip_s, strlen(ip_s));
- break;
- }
- case IOCTL_SO_GETHOSTBYNAME:
+ memset(Memory::GetPointer(_BufferOut), 0, BufferOutSize);
+ memcpy(Memory::GetPointer(_BufferOut), ip_s, strlen(ip_s));
+ return 0;
+ }
+
+ case IOCTL_SO_POLL:
{
- hostent *remoteHost = gethostbyname((char*)Memory::GetPointer(BufferIn));
+ // Map Wii/native poll events types
+ unsigned int mapping[][2] = {
+ { POLLIN, 0x0001 },
+ { POLLOUT, 0x0008 },
+ { POLLHUP, 0x0040 },
+ };
+
+ 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); //fd
+ int events = Memory::Read_U32(_BufferOut + 0xc*i + 4); //events
+ ufds[i].revents = Memory::Read_U32(_BufferOut + 0xc*i + 8); //revents
+
+ // Translate Wii to native events
+ int unhandled_events = events;
+ ufds[i].events = 0;
+ for (unsigned int j = 0; j < sizeof (mapping) / sizeof (mapping[0]); ++j)
+ {
+ if (events & mapping[j][1])
+ ufds[i].events |= mapping[j][0];
+ unhandled_events &= ~mapping[j][1];
+ }
+
+ WARN_LOG(WII_IPC_NET, "IOCTL_SO_POLL(%d) "
+ "Sock: %08x, Unknown: %08x, Events: %08x, "
+ "NativeEvents: %08x",
+ i, ufds[i].fd, unknown, events, ufds[i].events
+ );
+
+ if (unhandled_events)
+ ERROR_LOG(WII_IPC_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events);
+ }
+
+ int ret = poll(ufds, nfds, timeout);
+
+ ret = getNetErrorCode(ret, "SO_POLL", false);
+
+ for (int i = 0; i<nfds; i++)
+ {
+
+ // Translate native to Wii events
+ int revents = 0;
+ for (unsigned int j = 0; j < sizeof (mapping) / sizeof (mapping[0]); ++j)
+ {
+ if (ufds[i].revents & mapping[j][0])
+ revents |= mapping[j][1];
+ }
+
+ // No need to change fd or events as they are input only.
+ //Memory::Write_U32(ufds[i].fd, _BufferOut + 0xc*i); //fd
+ //Memory::Write_U32(events, _BufferOut + 0xc*i + 4); //events
+ Memory::Write_U32(revents, _BufferOut + 0xc*i + 8); //revents
+
+ WARN_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d revents %08X events %08X", i, revents, ufds[i].events);
+ }
+ free(ufds);
+ return ret;
+ }
+
+ case IOCTL_SO_GETHOSTBYNAME:
+ {
+ hostent *remoteHost = gethostbyname((char*)Memory::GetPointer(_BufferIn));
+
WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTBYNAME "
- "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- (char*)Memory::GetPointer(BufferIn), BufferIn, BufferInSize, BufferOut, BufferOutSize);
-
+ "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ (char*)Memory::GetPointer(_BufferIn), _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+
if (remoteHost)
{
for (int i = 0; remoteHost->h_aliases[i]; ++i)
{
WARN_LOG(WII_IPC_NET, "alias%i:%s", i, remoteHost->h_aliases[i]);
}
-
+
for (int i = 0; remoteHost->h_addr_list[i]; ++i)
{
u32 ip = Common::swap32(*(u32*)(remoteHost->h_addr_list[i]));
char ip_s[16];
sprintf(ip_s, "%i.%i.%i.%i",
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
+ ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
DEBUG_LOG(WII_IPC_NET, "addr%i:%s", i, ip_s);
}
-
- Memory::Memset(BufferOut, 0, BufferOutSize);
- u32 wii_addr = BufferOut + 4 * 3 + 2 * 2;
-
+
+ Memory::Memset(_BufferOut, 0, BufferOutSize);
+ u32 wii_addr = _BufferOut + 4 * 3 + 2 * 2;
+
u32 name_length = strlen(remoteHost->h_name) + 1;
Memory::WriteBigEData((const u8 *)remoteHost->h_name, wii_addr, name_length);
- Memory::Write_U32(wii_addr, BufferOut);
+ Memory::Write_U32(wii_addr, _BufferOut);
wii_addr += (name_length + 4) & ~3;
-
+
// aliases - empty
- Memory::Write_U32(wii_addr, BufferOut + 4);
+ Memory::Write_U32(wii_addr, _BufferOut + 4);
Memory::Write_U32(wii_addr + sizeof(u32), wii_addr);
wii_addr += sizeof(u32);
Memory::Write_U32((u32)NULL, wii_addr);
wii_addr += sizeof(u32);
-
+
// hardcode to ipv4
_dbg_assert_msg_(WII_IPC_NET,
- remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32),
- "returned host info is not IPv4");
- Memory::Write_U16(AF_INET, BufferOut + 8);
- Memory::Write_U16(sizeof(u32), BufferOut + 10);
-
+ remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32),
+ "returned host info is not IPv4");
+ Memory::Write_U16(AF_INET, _BufferOut + 8);
+ Memory::Write_U16(sizeof(u32), _BufferOut + 10);
+
// addrlist - probably only really need to return 1 anyways...
- Memory::Write_U32(wii_addr, BufferOut + 12);
+ Memory::Write_U32(wii_addr, _BufferOut + 12);
u32 num_addr = 0;
while (remoteHost->h_addr_list[num_addr])
num_addr++;
@@ -1189,499 +1316,142 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 CommandAddress)
Memory::Write_U32_Swap(*(u32*)(remoteHost->h_addr_list[i]), wii_addr);
wii_addr += sizeof(u32);
}
-
+
//ERROR_LOG(WII_IPC_NET, "\n%s",
- // ArrayToString(Memory::GetPointer(BufferOut), BufferOutSize, 16).c_str());
- ReturnValue = 0;
+ // ArrayToString(Memory::GetPointer(_BufferOut), BufferOutSize, 16).c_str());
+ return 0;
}
else
{
- ReturnValue = -1;
+ return -1;
}
-
+
break;
}
-
- case IOCTL_SO_ICMPSOCKET:
+
+ case IOCTL_SO_ICMPSOCKET:
{
// AF type?
- u32 arg = Memory::Read_U32(BufferIn);
+ u32 arg = Memory::Read_U32(_BufferIn);
u32 sock = (u32)socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %x", arg, sock);
- ReturnValue = getNetErrorCode(sock, "IOCTL_SO_ICMPSOCKET", false);
- break;
- }
-
- case IOCTL_SO_ICMPCANCEL:
- ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCANCEL");
- goto default_;
-
- case IOCTL_SO_ICMPCLOSE:
- {
- u32 sock = Memory::Read_U32(BufferIn);
- #ifdef _WIN32
- u32 ReturnValue = closesocket(sock);
- #else
- u32 ReturnValue = close(sock);
- #endif
- DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCLOSE(%x) %x", sock, ReturnValue);
- ReturnValue = getNetErrorCode(ReturnValue, "IOCTL_SO_ICMPCLOSE", false);
- break;
+ return getNetErrorCode(sock, "IOCTL_SO_ICMPSOCKET", false);
}
-
- default:
- {
- WARN_LOG(WII_IPC_NET,"0x%x "
- "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
-default_:
- if (BufferInSize)
- {
- ERROR_LOG(WII_IPC_NET, "in addr %x size %x", BufferIn, BufferInSize);
- ERROR_LOG(WII_IPC_NET, "\n%s",
- ArrayToString(Memory::GetPointer(BufferIn), BufferInSize, 4).c_str()
- );
- }
-
- if (BufferOutSize)
- {
- ERROR_LOG(WII_IPC_NET, "out addr %x size %x", BufferOut, BufferOutSize);
- }
- break;
- }
- }
-
- Memory::Write_U32(ReturnValue, CommandAddress + 0x4);
- return true;
-}
-
-char* DecodeError(int ErrorCode)
-{
-
-#ifdef _WIN32
- char Message[1024];
- 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;
-#else
- return strerror(ErrorCode);
-#endif
-}
-
-int getNetErrorCode(int ret, std::string caller, bool isRW)
-{
-#ifdef _WIN32
- int errorCode = WSAGetLastError();
-#else
- int errorCode = errno;
-#endif
-
- if (ret >= 0)
- return ret;
-
- WARN_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d",
- caller.c_str(), errorCode, DecodeError(errorCode), ret);
+ case IOCTL_SO_ICMPCANCEL:
+ ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCANCEL");
+ goto default_;
+ case IOCTL_SO_ICMPCLOSE:
+ {
+ u32 sock = Memory::Read_U32(_BufferIn);
#ifdef _WIN32
-#define ERRORCODE(name) WSA ## name
-#define EITHER(win32, posix) win32
+ u32 ret = closesocket(sock);
#else
-#define ERRORCODE(name) name
-#define EITHER(win32, posix) posix
+ u32 ret = close(sock);
#endif
-
- switch (errorCode)
- {
- case ERRORCODE(EMSGSIZE):
- WARN_LOG(WII_IPC_NET, "Find out why this happened, looks like PEEK failure?");
- return -1;
- case ERRORCODE(ECONNRESET):
- return -15; // ECONNRESET
- case ERRORCODE(EISCONN):
- return -30; // EISCONN
- case ERRORCODE(ENOTCONN):
- return -6; // EAGAIN
- case EITHER(WSAEWOULDBLOCK, EAGAIN):
- case ERRORCODE(EINPROGRESS):
- if(isRW){
- return -6; // EAGAIN
- }else{
- return -26; // EINPROGRESS
+ DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCLOSE(%x) %x", sock, ret);
+ return getNetErrorCode(ret, "IOCTL_SO_ICMPCLOSE", false);
}
- case EITHER(WSA_INVALID_HANDLE, EBADF):
- return -26; // EINPROGRESS (should be -8)
- default:
- return -1;
- }
-
-#undef ERRORCODE
-#undef EITHER
-}
-
-s32 CWII_IPC_HLE_Device_net_ip_top::processSocketIoctl(u32 CommandAddress, u32 socket)
-{
- s32 ReturnValue = 0;
- 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);
- switch(Command)
- {
- case IOCTL_SO_ACCEPT:
- {
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT(%d) "
+ default:
+ WARN_LOG(WII_IPC_NET,"0x%x "
"BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- socket, BufferIn, BufferInSize, BufferOut, BufferOutSize);
- struct sockaddr* addr = (struct sockaddr*) Memory::GetPointer(BufferOut);
- socklen_t* addrlen = (socklen_t*) Memory::GetPointer(BufferOutSize);
- *addrlen = sizeof(struct sockaddr);
- ReturnValue = accept(socket, addr, addrlen);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_ACCEPT", false);
- break;
- }
- case IOCTL_SO_CONNECT:
- {
- //struct sockaddr_in echoServAddr;
- struct connect_params
- {
- u32 socket;
- u32 has_addr;
- u8 addr[28];
- } params;
- sockaddr_in serverAddr;
-
- Memory::ReadBigEData((u8*)&params, BufferIn, sizeof(connect_params));
-
- if (Common::swap32(params.has_addr) != 1)
- {
- WARN_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT: failed");
- ReturnValue = -1;
- break;
- }
-
- 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;
-
- ReturnValue = connect(socket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
- ReturnValue = getNetErrorCode(ReturnValue, "SO_CONNECT", false);
- WARN_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT (%08x, %s:%d)",
- socket, inet_ntoa(serverAddr.sin_addr), Common::swap16(serverAddr.sin_port));
- break;
- }
- case IOCTL_SO_POLL:
+ _Command, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ default_:
+ if (BufferInSize)
{
- // Map Wii/native poll events types
- unsigned int mapping[][2] = {
- { POLLIN , 0x0001 },
- { POLLOUT, 0x0008 },
- { POLLHUP, 0x0040 },
- };
-
- 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)
- {
- ReturnValue = -1;
- break;
- }
-
- for (int i = 0; i < nfds; i++)
- {
- ufds[i].fd = Memory::Read_U32(BufferOut + 0xc*i); //fd
- int events = Memory::Read_U32(BufferOut + 0xc*i + 4); //events
- ufds[i].revents = Memory::Read_U32(BufferOut + 0xc*i + 8); //revents
-
- // Translate Wii to native events
- int unhandled_events = events;
- ufds[i].events = 0;
- for (unsigned int j = 0; j < sizeof (mapping) / sizeof (mapping[0]); ++j)
- {
- if (events & mapping[j][1])
- ufds[i].events |= mapping[j][0];
- unhandled_events &= ~mapping[j][1];
- }
-
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_POLL(%d) "
- "Sock: %08x, Unknown: %08x, Events: %08x, "
- "NativeEvents: %08x",
- i, ufds[i].fd, unknown, events, ufds[i].events
+ ERROR_LOG(WII_IPC_NET, "in addr %x size %x", _BufferIn, BufferInSize);
+ ERROR_LOG(WII_IPC_NET, "\n%s",
+ ArrayToString(Memory::GetPointer(_BufferIn), BufferInSize, 4).c_str()
);
-
- if (unhandled_events)
- ERROR_LOG(WII_IPC_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events);
- }
-
- ReturnValue = poll(ufds, nfds, timeout);
- ReturnValue = getNetErrorCode(ReturnValue, "SO_POLL", false);
-
- for (int i = 0; i<nfds; i++)
- {
-
- // Translate native to Wii events
- int revents = 0;
- for (unsigned int j = 0; j < sizeof (mapping) / sizeof (mapping[0]); ++j)
- {
- if (ufds[i].revents & mapping[j][0])
- revents |= mapping[j][1];
- }
-
- // No need to change fd or events as they are input only.
- // Memory::Write_U32(ufds[i].fd, BufferOut + 0xc*i); //fd
- // Memory::Write_U32(events, BufferOut + 0xc*i + 4); //events
- Memory::Write_U32(revents, BufferOut + 0xc*i + 8); //revents
-
- WARN_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d revents %08X events %08X", i, revents, ufds[i].events);
- }
- free(ufds);
-
- break;
- }
- default:
- {
-
- ERROR_LOG(WII_IPC_NET, "Socket %08x has received an unknown IOCTLV %d.", socket, Command);
- break;
}
- }
- return ReturnValue;
-}
-s32 CWII_IPC_HLE_Device_net_ip_top::processSocketIoctlv(u32 CommandAddress, u32 socket)
-{
- SIOCtlVBuffer CommandBuffer(CommandAddress);
-
- s32 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(CommandBuffer.Parameter)
- {
- case IOCTLV_SO_RECVFROM:
- {
-
- u32 flags = Memory::Read_U32(BufferIn + 4);
-
- char *buf = (char *)Memory::GetPointer(BufferOut);
- int len = BufferOutSize;
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(sockaddr_in));
- socklen_t fromlen = 0;
-
- if (BufferOutSize2 != 0)
- {
- fromlen = BufferOutSize2 >= sizeof(struct sockaddr) ? BufferOutSize2 : sizeof(struct sockaddr);
- }
-
- if (flags != 2)
- flags = 0;
- else
- flags = MSG_PEEK;
- #ifdef _WIN32
- if(flags & MSG_PEEK){
- unsigned long totallen = 0;
- ioctlsocket(socket, FIONREAD, &totallen);
- ReturnValue = totallen;
- break;
- }
- #endif
- ReturnValue = recvfrom(socket, buf, len, flags,
- fromlen ? (struct sockaddr*) &addr : NULL,
- fromlen ? &fromlen : 0);
-
- ReturnValue = getNetErrorCode(ReturnValue, fromlen ? "SO_RECVFROM" : "SO_RECV", true);
-
-
- WARN_LOG(WII_IPC_NET, "%s(%d, %p) Socket: %08X, Flags: %08X, "
- "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
- "BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",fromlen ? "IOCTLV_SO_RECVFROM " : "IOCTLV_SO_RECV ",
- ReturnValue, buf, socket, flags,
- BufferIn, BufferInSize, BufferIn2, BufferInSize2,
- BufferOut, BufferOutSize, BufferOut2, BufferOutSize2);
-
- if (BufferOutSize2 != 0)
- {
- addr.sin_family = (addr.sin_family << 8) | (BufferOutSize2&0xFF);
- Memory::WriteBigEData((u8*)&addr, BufferOut2, BufferOutSize2);
- }
-
- break;
- }
- default:
- {
-
- ERROR_LOG(WII_IPC_NET, "Socket %d has received an unknown IOCTLV %d.", socket, CommandBuffer.Parameter);
- break;
- }
- }
- return ReturnValue;
-}
-void CWII_IPC_HLE_Device_net_ip_top::processSocket(u32 socket)
-{
- //DEBUG_LOG(WII_IPC_NET, "Socket %08X has started a thread.... oh dear.", socket);
- _tSocket* sock = NULL;
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- if(socketMap.find(socket) == socketMap.end())
+ if (BufferOutSize)
{
- ERROR_LOG(WII_IPC_NET, "Socket %d could not be found in the socket map.", socket);
- return;
+ ERROR_LOG(WII_IPC_NET, "out addr %x size %x", _BufferOut, BufferOutSize);
}
- sock = socketMap[socket];
- }
- while((sock->WaitForEvent(), true) && sock->running)
- {
- u32 CommandAddress = 0;
- while(sock->getCommand(CommandAddress))
- {
-
- using WII_IPC_HLE_Interface::ECommandType;
- using WII_IPC_HLE_Interface::COMMAND_IOCTL;
- using WII_IPC_HLE_Interface::COMMAND_IOCTLV;
-
- s32 ReturnValue = 0;
-
- ECommandType CommandType = static_cast<ECommandType>(Memory::Read_U32(CommandAddress));
-
- if(CommandType == COMMAND_IOCTL)
- {
- ReturnValue = processSocketIoctl(CommandAddress, socket);
- }
- else if (CommandType == COMMAND_IOCTLV)
- {
- ReturnValue = processSocketIoctlv(CommandAddress, socket);
- }
-
- Memory::Write_U32(8, CommandAddress);
- // IOS seems to write back the command that was responded to
- Memory::Write_U32(CommandType, CommandAddress + 8);
- // Return value
- Memory::Write_U32(ReturnValue, CommandAddress + 4);
- WII_IPC_HLE_Interface::EnqReply(CommandAddress);
- }
-
- //DEBUG_LOG(WII_IPC_NET, "Socket %d has processed all events.", socket);
+ break;
}
- //DEBUG_LOG(WII_IPC_NET, "Socket %d has died.", socket);
-}
+ // We return a success for any potential unknown requests
+ return 0;
+}
-bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
-{
- SIOCtlVBuffer CommandBuffer(CommandAddress);
-
- s32 ReturnValue = 0;
-
- u32 BufferIn = 0, BufferIn2 = 0, BufferIn3 = 0;
+u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(SIOCtlVBuffer& CommandBuffer)
+{
+ u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
- u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 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;
+ _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;
+ _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;
+ _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;
+ _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;
+ _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;
+ _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 (CommandBuffer.Parameter)
{
case IOCTLV_SO_GETINTERFACEOPT:
- {
- #ifdef _WIN32
- PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
- ULONG OutBufferLength = 0;
- ULONG RetVal = 0, i;
- #endif
-
- u32 param = 0, param2 = 0, param3, param4, param5 = 0;
- param = Memory::Read_U32(BufferIn);
- param2 = Memory::Read_U32(BufferIn+4);
- param3 = Memory::Read_U32(BufferOut);
- param4 = Memory::Read_U32(BufferOut2);
+ {
+ 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);
+ param5 = Memory::Read_U32(_BufferOut+4);
}
WARN_LOG(WII_IPC_NET,"IOCTLV_SO_GETINTERFACEOPT(%08X, %08X) "
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
param, param2,
- BufferIn, BufferInSize, BufferIn2, BufferInSize2);
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
switch (param2)
{
@@ -1751,32 +1521,32 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
if (address == 0)
address = 0x08080808;
- Memory::Write_U32(address, BufferOut);
- Memory::Write_U32(0x08080808, BufferOut+4);
+ Memory::Write_U32(address, _BufferOut);
+ Memory::Write_U32(0x08080808, _BufferOut+4);
break;
}
case 0x1003:
- Memory::Write_U32(0, BufferOut);
+ Memory::Write_U32(0, _BufferOut);
break;
case 0x1004:
- Memory::WriteBigEData(default_address, BufferOut, 6);
+ Memory::WriteBigEData(default_address, _BufferOut, 6);
break;
case 0x1005:
- Memory::Write_U32(1, BufferOut);
- Memory::Write_U32(4, BufferOut2);
+ Memory::Write_U32(1, _BufferOut);
+ Memory::Write_U32(4, _BufferOut2);
break;
case 0x4002:
- Memory::Write_U32(2, BufferOut);
+ 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);
+ 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:
@@ -1785,87 +1555,109 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
}
- ReturnValue = 0;
+ return 0;
break;
}
- case IOCTLV_SO_RECVFROM:
- {
- u32 s = 0;
- if (CommandBuffer.Parameter == IOCTLV_SO_SENDTO)
- {
- s = Memory::Read_U32(BufferIn2);
- } else {
- s = Memory::Read_U32(BufferIn);
- }
- ERROR_LOG(WII_IPC_NET, "Adding sendto or recvfrom %08X %08X", s, CommandBuffer.Parameter);
-
- _tSocket * sock = NULL;
- {
- std::lock_guard<std::mutex> lk(socketMapMutex);
- if(socketMap.find(s) != socketMap.end())
- sock = socketMap[s];
- }
- if(sock)
- {
- sock->addCommand(CommandAddress);
- return false;
- }
- else
- {
- ReturnValue = -8; // EBADF
- }
-
- ERROR_LOG(WII_IPC_NET, "Failed to find socket %d %08X", s, CommandBuffer.Parameter);
- break;
- }
-
case IOCTLV_SO_SENDTO:
- {
- struct sendto_params
{
- u32 socket;
- u32 flags;
- u32 has_destaddr;
- u8 destaddr[28];
- } params;
- u32 socket = Memory::Read_U32(BufferIn2);
- char * data = (char*)Memory::GetPointer(BufferIn);
- Memory::ReadBigEData((u8*)&params, BufferIn2, BufferInSize2);
-
- if (params.has_destaddr)
+ struct sendto_params
+ {
+ u32 socket;
+ u32 flags;
+ u32 has_destaddr;
+ u8 destaddr[28];
+ } params;
+
+ char * data = (char*)Memory::GetPointer(_BufferIn);
+ Memory::ReadBigEData((u8*)&params, _BufferIn2, BufferInSize2);
+
+ if (params.has_destaddr)
+ {
+ struct sockaddr_in* addr = (struct sockaddr_in*)&params.destaddr;
+ u8 len = sizeof(sockaddr); //addr->sin_family & 0xFF;
+ addr->sin_family = addr->sin_family >> 8;
+
+ int ret = sendto(Common::swap32(params.socket), data,
+ BufferInSize, Common::swap32(params.flags), (struct sockaddr*)addr, len);
+
+ WARN_LOG(WII_IPC_NET,
+ "IOCTLV_SO_SENDTO = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u",
+ ret, Common::swap32(params.socket), _BufferIn, BufferInSize,
+ _BufferIn2, BufferInSize2,
+ addr->sin_addr.s_addr & 0xFF,
+ (addr->sin_addr.s_addr >> 8) & 0xFF,
+ (addr->sin_addr.s_addr >> 16) & 0xFF,
+ (addr->sin_addr.s_addr >> 24) & 0xFF
+ );
+
+ return getNetErrorCode(ret, "SO_SENDTO", true);
+ }
+ else
+ {
+ int ret = send(Common::swap32(params.socket), data,
+ BufferInSize, Common::swap32(params.flags));
+ WARN_LOG(WII_IPC_NET, "IOCTLV_SO_SEND = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
+ ret, Common::swap32(params.socket), _BufferIn, BufferInSize,
+ _BufferIn2, BufferInSize2);
+
+ return getNetErrorCode(ret, "SO_SEND", true);
+ }
+ break;
+ }
+
+ case IOCTLV_SO_RECVFROM:
{
- struct sockaddr_in* addr = (struct sockaddr_in*)&params.destaddr;
- u8 len = sizeof(sockaddr_in); //addr->sin_family & 0xFF;
- addr->sin_family = addr->sin_family >> 8;
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 flags = Memory::Read_U32(_BufferIn + 4);
- ReturnValue = sendto(socket, data,
- BufferInSize, Common::swap32(params.flags), (struct sockaddr*)addr, len);
+ char *buf = (char *)Memory::GetPointer(_BufferOut);
+ int len = BufferOutSize;
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(sockaddr_in));
+ socklen_t fromlen = 0;
- WARN_LOG(WII_IPC_NET,
- "IOCTLV_SO_SENDTO = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u",
- ReturnValue, socket, BufferIn, BufferInSize,
- BufferIn2, BufferInSize2,
- addr->sin_addr.s_addr & 0xFF,
- (addr->sin_addr.s_addr >> 8) & 0xFF,
- (addr->sin_addr.s_addr >> 16) & 0xFF,
- (addr->sin_addr.s_addr >> 24) & 0xFF
- );
+ if (BufferOutSize2 != 0)
+ {
+ fromlen = BufferOutSize2 >= sizeof(struct sockaddr) ? BufferOutSize2 : sizeof(struct sockaddr);
+ }
- ReturnValue = getNetErrorCode(ReturnValue, "SO_SENDTO", true);
- }
- else
- {
- ReturnValue = send(socket, data,
- BufferInSize, Common::swap32(params.flags));
- WARN_LOG(WII_IPC_NET, "IOCTLV_SO_SEND = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
- ReturnValue, socket, BufferIn, BufferInSize,
- BufferIn2, BufferInSize2);
+ if (flags != 2)
+ flags = 0;
+ else
+ flags = MSG_PEEK;
- ReturnValue = getNetErrorCode(ReturnValue, "SO_SEND", true);
+ static int ret;
+#ifdef _WIN32
+ if(flags & MSG_PEEK){
+ unsigned long totallen = 0;
+ ioctlsocket(sock, FIONREAD, &totallen);
+ return totallen;
+ }
+#endif
+ ret = recvfrom(sock, buf, len, flags,
+ fromlen ? (struct sockaddr*) &addr : NULL,
+ fromlen ? &fromlen : 0);
+
+ int err = getNetErrorCode(ret, fromlen ? "SO_RECVFROM" : "SO_RECV", true);
+
+
+ WARN_LOG(WII_IPC_NET, "%s(%d, %p) Socket: %08X, Flags: %08X, "
+ "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
+ "BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",fromlen ? "IOCTLV_SO_RECVFROM " : "IOCTLV_SO_RECV ",
+ err, buf, sock, flags,
+ _BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
+ _BufferOut, BufferOutSize, _BufferOut2, BufferOutSize2);
+
+ if (BufferOutSize2 != 0)
+ {
+ addr.sin_family = (addr.sin_family << 8) | (BufferOutSize2&0xFF);
+ Memory::WriteBigEData((u8*)&addr, _BufferOut2, BufferOutSize2);
+ }
+
+ return err;
}
- break;
- }
+
case IOCTLV_SO_GETADDRINFO:
{
struct addrinfo hints;
@@ -1873,28 +1665,28 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
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);
+ 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);
+ pNodeName = (char*)Memory::GetPointer(_BufferIn);
char* pServiceName = NULL;
if (BufferInSize2 > 0)
- pServiceName = (char*)Memory::GetPointer(BufferIn2);
+ pServiceName = (char*)Memory::GetPointer(_BufferIn2);
- ReturnValue = getaddrinfo(pNodeName, pServiceName, BufferInSize3 ? &hints : NULL, &result);
- u32 addr = BufferOut;
+ int ret = getaddrinfo(pNodeName, pServiceName, BufferInSize3 ? &hints : NULL, &result);
+ u32 addr = _BufferOut;
u32 sockoffset = addr + 0x460;
- if (ReturnValue >= 0)
+ if (ret >= 0)
{
while (result != NULL)
{
@@ -1934,9 +1726,9 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
WARN_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO "
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
- BufferIn, BufferInSize, BufferOut, BufferOutSize);
- WARN_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetPointer(BufferIn));
- break;
+ _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
+ WARN_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetPointer(_BufferIn));
+ return ret;
}
case IOCTLV_SO_ICMPPING:
@@ -1949,19 +1741,19 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
u32 ip;
} ip_info;
- u32 sock = Memory::Read_U32(BufferIn);
- u32 num_ip = Memory::Read_U32(BufferIn + 4);
- u64 timeout = Memory::Read_U64(BufferIn + 8);
+ u32 sock = Memory::Read_U32(_BufferIn);
+ u32 num_ip = Memory::Read_U32(_BufferIn + 4);
+ u64 timeout = Memory::Read_U64(_BufferIn + 8);
if (num_ip != 1)
{
WARN_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING %i IPs", num_ip);
}
- ip_info.length = Memory::Read_U8(BufferIn + 16);
- ip_info.addr_family = Memory::Read_U8(BufferIn + 17);
- ip_info.icmp_id = Memory::Read_U16(BufferIn + 18);
- ip_info.ip = Memory::Read_U32(BufferIn + 20);
+ ip_info.length = Memory::Read_U8(_BufferIn + 16);
+ ip_info.addr_family = Memory::Read_U8(_BufferIn + 17);
+ ip_info.icmp_id = Memory::Read_U16(_BufferIn + 18);
+ ip_info.ip = Memory::Read_U32(_BufferIn + 20);
if (ip_info.length != 8 || ip_info.addr_family != AF_INET)
{
@@ -1982,7 +1774,7 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
s32 icmp_length = sizeof(data);
if (BufferInSize2 == sizeof(data))
- memcpy(data, Memory::GetPointer(BufferIn2), BufferInSize2);
+ memcpy(data, Memory::GetPointer(_BufferIn2), BufferInSize2);
else
{
// TODO sequence number is incremented either statically, by
@@ -1992,20 +1784,19 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
icmp_length = 22;
}
- ReturnValue = icmp_echo_req(sock, &addr, data, icmp_length);
- if (ReturnValue == icmp_length)
+ int ret = icmp_echo_req(sock, &addr, data, icmp_length);
+ if (ret == icmp_length)
{
- ReturnValue = icmp_echo_rep(sock, &addr, (u32)timeout, icmp_length);
+ ret = icmp_echo_rep(sock, &addr, (u32)timeout, icmp_length);
}
// TODO proper error codes
- ReturnValue = 0;
- break;
+ return 0;
}
default:
WARN_LOG(WII_IPC_NET,"0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
- CommandBuffer.Parameter, BufferIn, BufferInSize, BufferIn2, BufferInSize2);
+ CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
default_:
for (u32 i = 0; i < CommandBuffer.NumberInBuffer; ++i)
{
@@ -2024,7 +1815,16 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
}
break;
}
- Memory::Write_U32(ReturnValue, CommandAddress + 4);
+
+ return 0;
+}
+
+bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
+{
+ SIOCtlVBuffer buf(CommandAddress);
+
+ u32 return_value = ExecuteCommandV(buf);
+ Memory::Write_U32(return_value, CommandAddress + 4);
return true;
}
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 209d7a240b..75ff25c6eb 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
@@ -29,7 +29,6 @@
#include <ws2tcpip.h>
#endif
#include "Timer.h"
-#include "Thread.h"
#include "FileUtil.h"
// data layout of the network configuration file (/shared2/sys/net/02/config.dat)
@@ -569,54 +568,6 @@ private:
}
};
-class _tSocket
-{
-public:
- bool running;
- std::mutex m_mutex;
- std::thread* thread;
-
- _tSocket()
- {
- running = true;
- }
-
- bool getCommand(u32& commandAddress)
- {
- std::lock_guard<std::mutex> lk(m_mutex);
- if (commands.empty())
- return false;
- commandAddress = commands.front();
- commands.pop();
- return true;
- }
-
- void addCommand(u32 commandAddress)
- {
- std::lock_guard<std::mutex> lk(m_mutex);
- commands.push(commandAddress);
- event.Set();
- }
-
- void StopAndJoin()
- {
- running = false;
- event.Set();
- thread->join();
- delete thread;
- thread = NULL;
- }
-
- void WaitForEvent()
- {
- event.Wait();
- }
-private:
- Common::Event event;
- std::queue<u32> commands;
-
-};
-
//////////////////////////////////////////////////////////////////////////
class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device
{
@@ -634,11 +585,6 @@ private:
#ifdef _WIN32
WSADATA InitData;
#endif
- std::map<u32, _tSocket*> socketMap;
- std::mutex socketMapMutex;
- void processSocket(u32 socket);
- s32 processSocketIoctl(u32 CommandAddress, u32 socket);
- s32 processSocketIoctlv(u32 CommandAddress, u32 socket);
enum
{
@@ -683,39 +629,6 @@ private:
u32 ExecuteCommandV(SIOCtlVBuffer& CommandBuffer);
};
-static int getNetErrorCode(int ret, std::string caller, bool isRW);
-
-
-struct bind_params
-{
- u32 socket;
- u32 has_name;
- u8 name[28];
-};
-
-struct GC_sockaddr
-{
- u8 sa_len;
- u8 sa_family;
- s8 sa_data[14];
-};
-
-struct GC_in_addr
-{
- // this cannot be named s_addr under windows - collides with some crazy define.
- u32 s_addr_;
-};
-
-struct GC_sockaddr_in
-{
- u8 sin_len;
- u8 sin_family;
- u16 sin_port;
- struct GC_in_addr sin_addr;
- s8 sin_zero[8];
-};
-
-
// **********************************************************************************
// Interface for reading and changing network configuration (probably some other stuff as well)
class CWII_IPC_HLE_Device_net_ncd_manage : public IWII_IPC_HLE_Device