Bug Summary

File:Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp
Location:line 177, column 8
Description:Value stored to 'BufferInSize' during its initialization is never read

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "WII_Socket.h"
6#include "WII_IPC_HLE.h"
7#include "WII_IPC_HLE_Device.h"
8// No Wii socket support while using NetPlay or TAS
9#include "NetPlayClient.h"
10#include "Movie.h"
11
12using WII_IPC_HLE_Interface::ECommandType;
13using WII_IPC_HLE_Interface::COMMAND_IOCTL;
14using WII_IPC_HLE_Interface::COMMAND_IOCTLV;
15
16#ifdef _WIN32
17#define ERRORCODE(name) WSA ## name
18#define EITHER(win32, posix) win32
19#else
20#define ERRORCODE(name) name
21#define EITHER(win32, posix) posix
22#endif
23
24char* WiiSockMan::DecodeError(s32 ErrorCode)
25{
26#ifdef _WIN32
27 static char Message[1024];
28 // If this program was multi-threaded, we'd want to use FORMAT_MESSAGE_ALLOCATE_BUFFER
29 // instead of a static buffer here.
30 // (And of course, free the buffer when we were done with it)
31 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
32 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL__null, ErrorCode,
33 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)Message, 1024, NULL__null);
34 return Message;
35#else
36 return strerror(ErrorCode);
37#endif
38}
39
40
41s32 WiiSockMan::getNetErrorCode(s32 ret, std::string caller, bool isRW)
42{
43#ifdef _WIN32
44 s32 errorCode = WSAGetLastError();
45#else
46 s32 errorCode = errno(*__errno_location ());
47#endif
48 if (ret >= 0)
49 return ret;
50
51 DEBUG_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d",do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 52, "%s failed with error %d: %s, ret= %d", caller.c_str(),
errorCode, DecodeError(errorCode), ret); } } while (0)
52 caller.c_str(), errorCode, DecodeError(errorCode), ret)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 52, "%s failed with error %d: %s, ret= %d", caller.c_str(),
errorCode, DecodeError(errorCode), ret); } } while (0)
;
53
54 switch (errorCode)
55 {
56 case ERRORCODE(EMSGSIZE90):
57 ERROR_LOG(WII_IPC_NET, "Find out why this happened, looks like PEEK failure?")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 57, "Find out why this happened, looks like PEEK failure?")
; } } while (0)
;
58 return -1; // Should be -SO_EMSGSIZE
59 case EITHER(WSAENOTSOCK, EBADF9):
60 return -SO_EBADF;
61 case ERRORCODE(EADDRINUSE98):
62 return -SO_EADDRINUSE;
63 case ERRORCODE(ECONNRESET104):
64 return -SO_ECONNRESET;
65 case ERRORCODE(EISCONN106):
66 return -SO_EISCONN;
67 case ERRORCODE(ENOTCONN107):
68 return -SO_EAGAIN; // After proper blocking SO_EAGAIN shouldn't be needed...
69 case ERRORCODE(EINPROGRESS115):
70 return -SO_EINPROGRESS;
71 case ERRORCODE(EALREADY114):
72 return -SO_EALREADY;
73 case ERRORCODE(EACCES13):
74 return -SO_EACCES;
75 case ERRORCODE(ECONNREFUSED111):
76 return -SO_ECONNREFUSED;
77 case ERRORCODE(ENETUNREACH101):
78 return -SO_ENETUNREACH;
79 case ERRORCODE(EHOSTUNREACH113):
80 return -SO_EHOSTUNREACH;
81 case EITHER(WSAEWOULDBLOCK, EAGAIN11):
82 if (isRW){
83 return -SO_EAGAIN; // EAGAIN
84 }else{
85 return -SO_EINPROGRESS; // EINPROGRESS
86 }
87 default:
88 return -1;
89 }
90
91}
92
93WiiSocket::~WiiSocket()
94{
95 if (fd >= 0)
96 {
97 (void)closeFd();
98 }
99}
100
101void WiiSocket::setFd(s32 s)
102{
103 if (fd >= 0)
104 (void)closeFd();
105
106 nonBlock = false;
107 fd = s;
108
109 // Set socket to NON-BLOCK
110#ifdef _WIN32
111 u_long iMode = 1;
112 ioctlsocket(fd, FIONBIO0x5421, &iMode);
113#else
114 int flags;
115 if (-1 == (flags = fcntl(fd, F_GETFL3, 0)))
116 flags = 0;
117 fcntl(fd, F_SETFL4, flags | O_NONBLOCK04000);
118#endif
119}
120
121s32 WiiSocket::closeFd()
122{
123 s32 ReturnValue = 0;
124 if (fd >= 0)
125 {
126#ifdef _WIN32
127 s32 ret = closesocket(fd);
128#else
129 s32 ret = close(fd);
130#endif
131 ReturnValue = WiiSockMan::getNetErrorCode(ret, "delSocket", false);
132 }
133 else
134 {
135 ReturnValue = WiiSockMan::getNetErrorCode(EITHER(WSAENOTSOCK, EBADF9), "delSocket", false);
136 }
137 fd = -1;
138 return ReturnValue;
139}
140
141s32 WiiSocket::_fcntl(u32 cmd, u32 arg)
142{
143#define F_GETFL3 3
144#define F_SETFL4 4
145#define F_NONBLOCK4 4
146 s32 ret = 0;
147 if (cmd == F_GETFL3)
148 {
149 ret = nonBlock ? F_NONBLOCK4 : 0;
150 }
151 else if (cmd == F_SETFL4)
152 {
153 nonBlock = (arg & F_NONBLOCK4) == F_NONBLOCK4;
154 }
155 else
156 {
157 ERROR_LOG(WII_IPC_NET, "SO_FCNTL unknown command")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 157, "SO_FCNTL unknown command"); } } while (0)
;
158 }
159
160 INFO_LOG(WII_IPC_NET, "IOCTL_SO_FCNTL(%08x, %08X, %08X)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 161, "IOCTL_SO_FCNTL(%08x, %08X, %08X)", fd, cmd, arg); } }
while (0)
161 fd, cmd, arg)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 161, "IOCTL_SO_FCNTL(%08x, %08X, %08X)", fd, cmd, arg); } }
while (0)
;
162
163 return ret;
164}
165
166void WiiSocket::update(bool read, bool write, bool except)
167{
168 auto it = pending_sockops.begin();
169 while (it != pending_sockops.end())
170 {
171 s32 ReturnValue = 0;
172 bool forceNonBlock = false;
173 ECommandType ct = static_cast<ECommandType>(Memory::Read_U32(it->_CommandAddress));
174 if (!it->is_ssl && ct == COMMAND_IOCTL)
175 {
176 u32 BufferIn = Memory::Read_U32(it->_CommandAddress + 0x10);
177 u32 BufferInSize = Memory::Read_U32(it->_CommandAddress + 0x14);
Value stored to 'BufferInSize' during its initialization is never read
178 u32 BufferOut = Memory::Read_U32(it->_CommandAddress + 0x18);
179 u32 BufferOutSize = Memory::Read_U32(it->_CommandAddress + 0x1C);
180
181 switch(it->net_type)
182 {
183 case IOCTL_SO_FCNTL:
184 {
185 u32 cmd = Memory::Read_U32(BufferIn + 4);
186 u32 arg = Memory::Read_U32(BufferIn + 8);
187 ReturnValue = _fcntl(cmd, arg);
188 break;
189 }
190 case IOCTL_SO_BIND:
191 {
192 //u32 has_addr = Memory::Read_U32(BufferIn + 0x04);
193 sockaddr_in local_name;
194 WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08);
195 WiiSockMan::Convert(*wii_name, local_name);
196
197 int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name));
198 ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_BIND", false);
199
200 INFO_LOG(WII_IPC_NET, "IOCTL_SO_BIND (%08X %s:%d) = %d ", fd,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 201, "IOCTL_SO_BIND (%08X %s:%d) = %d ", fd, inet_ntoa(local_name
.sin_addr), Common::swap16(local_name.sin_port), ret); } } while
(0)
201 inet_ntoa(local_name.sin_addr), Common::swap16(local_name.sin_port), ret)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 201, "IOCTL_SO_BIND (%08X %s:%d) = %d ", fd, inet_ntoa(local_name
.sin_addr), Common::swap16(local_name.sin_port), ret); } } while
(0)
;
202 break;
203 }
204 case IOCTL_SO_CONNECT:
205 {
206 //u32 has_addr = Memory::Read_U32(BufferIn + 0x04);
207 sockaddr_in local_name;
208 WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08);
209 WiiSockMan::Convert(*wii_name, local_name);
210
211 int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name));
212 ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_CONNECT", false);
213
214 INFO_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT (%08x, %s:%d)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 215, "IOCTL_SO_CONNECT (%08x, %s:%d)", fd, inet_ntoa(local_name
.sin_addr), Common::swap16(local_name.sin_port)); } } while (
0)
215 fd, inet_ntoa(local_name.sin_addr), Common::swap16(local_name.sin_port))do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 215, "IOCTL_SO_CONNECT (%08x, %s:%d)", fd, inet_ntoa(local_name
.sin_addr), Common::swap16(local_name.sin_port)); } } while (
0)
;
216 break;
217 }
218 case IOCTL_SO_ACCEPT:
219 {
220
221 if (BufferOutSize > 0)
222 {
223 sockaddr_in local_name;
224 WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferOut);
225 WiiSockMan::Convert(*wii_name, local_name);
226
227 socklen_t addrlen = sizeof(sockaddr_in);
228 int ret = (s32)accept(fd, (sockaddr*)&local_name, &addrlen);
229 ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_ACCEPT", false);
230
231 WiiSockMan::Convert(local_name, *wii_name, addrlen);
232 }
233 else
234 {
235 int ret = (s32)accept(fd, NULL__null, 0);
236 ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_ACCEPT", false);
237 }
238
239 WiiSockMan::getInstance().addSocket(ReturnValue);
240
241 INFO_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT "do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 243, "IOCTL_SO_ACCEPT " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, BufferIn, BufferInSize, BufferOut, BufferOutSize); } } while
(0)
242 "BufferIn: (%08x, %i), BufferOut: (%08x, %i)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 243, "IOCTL_SO_ACCEPT " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, BufferIn, BufferInSize, BufferOut, BufferOutSize); } } while
(0)
243 BufferIn, BufferInSize, BufferOut, BufferOutSize)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 243, "IOCTL_SO_ACCEPT " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, BufferIn, BufferInSize, BufferOut, BufferOutSize); } } while
(0)
;
244
245 break;
246 }
247 default:
248 break;
249 }
250
251 // Fix blocking error codes
252 if (!nonBlock)
253 {
254 if (it->net_type == IOCTL_SO_CONNECT
255 && ReturnValue == -SO_EISCONN)
256 {
257 ReturnValue = SO_SUCCESS;
258 }
259 }
260 }
261 else if (ct == COMMAND_IOCTLV)
262 {
263 SIOCtlVBuffer CommandBuffer(it->_CommandAddress);
264 u32 BufferIn = 0, BufferIn2 = 0;
265 u32 BufferInSize = 0, BufferInSize2 = 0;
266 u32 BufferOut = 0, BufferOut2 = 0;
267 u32 BufferOutSize = 0, BufferOutSize2 = 0;
268
269 if (CommandBuffer.InBuffer.size() > 0)
270 {
271 BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
272 BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
273 }
274
275 if (CommandBuffer.PayloadBuffer.size() > 0)
276 {
277 BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
278 BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
279 }
280
281 if (CommandBuffer.PayloadBuffer.size() > 1)
282 {
283 BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
284 BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
285 }
286
287 if (CommandBuffer.InBuffer.size() > 1)
288 {
289 BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
290 BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
291 }
292
293 if (it->is_ssl)
294 {
295 int sslID = Memory::Read_U32(BufferOut) - 1;
296 if (SSLID_VALID(sslID)(sslID >= 0 && sslID < 4 && CWII_IPC_HLE_Device_net_ssl
::_SSL[sslID].active)
)
297 {
298 switch(it->ssl_type)
299 {
300 case IOCTLV_NET_SSL_DOHANDSHAKE:
301 {
302
303 int ret = ssl_handshake(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx);
304 switch (ret)
305 {
306 case 0:
307 Memory::Write_U32(SSL_OK, BufferIn);
308 break;
309 case POLARSSL_ERR_NET_WANT_READ-0x0052:
310 Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
311 if (!nonBlock)
312 ReturnValue = SSL_ERR_RAGAIN;
313 break;
314 case POLARSSL_ERR_NET_WANT_WRITE-0x0054:
315 Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
316 if (!nonBlock)
317 ReturnValue = SSL_ERR_WAGAIN;
318 break;
319 default:
320 Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
321 break;
322 }
323
324 INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) "do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
325 "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
326 "BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
327 ret,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
328 BufferIn, BufferInSize, BufferIn2, BufferInSize2,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
329 BufferOut, BufferOutSize, BufferOut2, BufferOutSize2)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_SSL, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 329, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)", ret, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
;
330 break;
331 }
332 case IOCTLV_NET_SSL_WRITE:
333 {
334 int ret = ssl_write(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx, Memory::GetPointer(BufferOut2), BufferOutSize2);
335
336#ifdef DEBUG_SSL
337 File::IOFile("ssl_write.bin", "ab").WriteBytes(Memory::GetPointer(BufferOut2), BufferOutSize2);
338#endif
339 if (ret >= 0)
340 {
341 // Return bytes written or SSL_ERR_ZERO if none
342 Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
343 }
344 else
345 {
346 switch (ret)
347 {
348 case POLARSSL_ERR_NET_WANT_READ-0x0052:
349 Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
350 if (!nonBlock)
351 ReturnValue = SSL_ERR_RAGAIN;
352 break;
353 case POLARSSL_ERR_NET_WANT_WRITE-0x0054:
354 Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
355 if (!nonBlock)
356 ReturnValue = SSL_ERR_WAGAIN;
357 break;
358 default:
359 Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
360 break;
361 }
362 }
363 break;
364 }
365 case IOCTLV_NET_SSL_READ:
366 {
367 int ret = ssl_read(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx, Memory::GetPointer(BufferIn2), BufferInSize2);
368#ifdef DEBUG_SSL
369 if (ret > 0)
370 {
371 File::IOFile("ssl_read.bin", "ab").WriteBytes(Memory::GetPointer(BufferIn2), ret);
372 }
373#endif
374 if (ret >= 0)
375 {
376 // Return bytes read or SSL_ERR_ZERO if none
377 Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
378 }
379 else
380 {
381 switch (ret)
382 {
383 case POLARSSL_ERR_NET_WANT_READ-0x0052:
384 Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
385 if (!nonBlock)
386 ReturnValue = SSL_ERR_RAGAIN;
387 break;
388 case POLARSSL_ERR_NET_WANT_WRITE-0x0054:
389 Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
390 if (!nonBlock)
391 ReturnValue = SSL_ERR_WAGAIN;
392 break;
393 default:
394 Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
395 break;
396 }
397 }
398 break;
399 }
400 default:
401 break;
402 }
403 }
404 else
405 {
406 Memory::Write_U32(SSL_ERR_ID, BufferIn);
407 }
408 }
409 else
410 {
411 switch (it->net_type)
412 {
413 case IOCTLV_SO_SENDTO:
414 {
415
416 char * data = (char*)Memory::GetPointer(BufferIn);
417 u32 flags = Common::swap32(BufferIn2 + 0x04);
418 u32 has_destaddr = Common::swap32(BufferIn2 + 0x08);
419 // Act as non blocking when SO_MSG_NONBLOCK is specified
420 forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK);
421
422 // send/sendto only handles MSG_OOB
423 flags &= SO_MSG_OOB;
424
425 u8 destaddr[28];
426 struct sockaddr_in* addr = (struct sockaddr_in*)&destaddr;
427 if (has_destaddr)
428 {
429 Memory::ReadBigEData((u8*)&destaddr, BufferIn2 + 0x0C, BufferInSize2 - 0x0C);
430 addr->sin_family = addr->sin_family >> 8;
431 }
432
433 int ret = sendto(fd, data, BufferInSize, flags,
434 has_destaddr ? (struct sockaddr*)addr : NULL__null,
435 has_destaddr ? sizeof(sockaddr) : 0);
436 ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_SENDTO", true);
437
438 INFO_LOG(WII_IPC_NET,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
439 "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
440 has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
441 ReturnValue, fd, BufferIn, BufferInSize,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
442 BufferIn2, BufferInSize2,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
443 addr->sin_addr.s_addr & 0xFF,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
444 (addr->sin_addr.s_addr >> 8) & 0xFF,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
445 (addr->sin_addr.s_addr >> 16) & 0xFF,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
446 (addr->sin_addr.s_addr >> 24) & 0xFFdo { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
447 )do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 447, "%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u"
, has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ", ReturnValue
, fd, 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); } } while
(0)
;
448 break;
449 }
450 case IOCTLV_SO_RECVFROM:
451 {
452 u32 sock = Memory::Read_U32(BufferIn);
453 u32 flags = Memory::Read_U32(BufferIn + 4);
454
455 char *buf = (char *)Memory::GetPointer(BufferOut);
456 int len = BufferOutSize;
457 struct sockaddr_in addr;
458 memset(&addr, 0, sizeof(sockaddr_in));
459 socklen_t fromlen = 0;
460
461 if (BufferOutSize2 != 0)
462 {
463 fromlen = BufferOutSize2 >= sizeof(struct sockaddr) ? BufferOutSize2 : sizeof(struct sockaddr);
464 }
465
466 // Act as non blocking when SO_MSG_NONBLOCK is specified
467 forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK);
468
469 // recv/recvfrom only handles PEEK
470 flags &= SO_MSG_PEEK | SO_MSG_OOB;
471#ifdef _WIN32
472 if (flags & MSG_PEEKMSG_PEEK){
473 unsigned long totallen = 0;
474 ioctlsocket(sock, FIONREAD0x541B, &totallen);
475 ReturnValue = totallen;
476 break;
477 }
478#endif
479 int ret = recvfrom(sock, buf, len, flags,
480 fromlen ? (struct sockaddr*) &addr : NULL__null,
481 fromlen ? &fromlen : 0);
482 ReturnValue = WiiSockMan::getNetErrorCode(ret, fromlen ? "SO_RECVFROM" : "SO_RECV", true);
483
484
485 INFO_LOG(WII_IPC_NET, "%s(%d, %p) Socket: %08X, Flags: %08X, "do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
486 "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
487 "BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
488 fromlen ? "IOCTLV_SO_RECVFROM " : "IOCTLV_SO_RECV ",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
489 ReturnValue, buf, sock, flags,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
490 BufferIn, BufferInSize, BufferIn2, BufferInSize2,do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
491 BufferOut, BufferOutSize, BufferOut2, BufferOutSize2)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 491, "%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, sock, flags, BufferIn
, BufferInSize, BufferIn2, BufferInSize2, BufferOut, BufferOutSize
, BufferOut2, BufferOutSize2); } } while (0)
;
492
493 if (BufferOutSize2 != 0)
494 {
495 addr.sin_family = (addr.sin_family << 8) | (BufferOutSize2&0xFF);
496 Memory::WriteBigEData((u8*)&addr, BufferOut2, BufferOutSize2);
497 }
498 break;
499 }
500 default:
501 break;
502 }
503 }
504
505 }
506
507 if ( nonBlock || forceNonBlock
508 || (!it->is_ssl && ReturnValue != -SO_EAGAIN && ReturnValue != -SO_EINPROGRESS && ReturnValue != -SO_EALREADY)
509 || (it->is_ssl && ReturnValue != SSL_ERR_WAGAIN && ReturnValue != SSL_ERR_RAGAIN))
510 {
511 DEBUG_LOG(WII_IPC_NET, "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d",do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 512, "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d"
, fd, it->is_ssl ? it->ssl_type : it->net_type, ReturnValue
, nonBlock, forceNonBlock); } } while (0)
512 fd, it->is_ssl ? it->ssl_type : it->net_type, ReturnValue, nonBlock, forceNonBlock)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp"
, 512, "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d"
, fd, it->is_ssl ? it->ssl_type : it->net_type, ReturnValue
, nonBlock, forceNonBlock); } } while (0)
;
513 WiiSockMan::EnqueueReply(it->_CommandAddress, ReturnValue);
514 it = pending_sockops.erase(it);
515 }
516 else
517 {
518 ++it;
519 }
520 }
521}
522
523void WiiSocket::doSock(u32 _CommandAddress, NET_IOCTL type)
524{
525 sockop so = {_CommandAddress, false};
526 so.net_type = type;
527 pending_sockops.push_back(so);
528}
529
530void WiiSocket::doSock(u32 _CommandAddress, SSL_IOCTL type)
531{
532 sockop so = {_CommandAddress, true};
533 so.ssl_type = type;
534 pending_sockops.push_back(so);
535}
536
537void WiiSockMan::addSocket(s32 fd)
538{
539 if (fd >= 0)
540 {
541 WiiSocket& sock = WiiSockets[fd];
542 sock.setFd(fd);
543 }
544}
545
546s32 WiiSockMan::newSocket(s32 af, s32 type, s32 protocol)
547{
548 if (NetPlay::IsNetPlayRunning()
549 || Movie::IsRecordingInput()
550 || Movie::IsPlayingInput())
551 {
552 return SO_ENOMEM;
553 }
554
555 s32 fd = (s32)socket(af, type, protocol);
556 s32 ret = getNetErrorCode(fd, "newSocket", false);
557 addSocket(ret);
558 return ret;
559}
560
561s32 WiiSockMan::delSocket(s32 s)
562{
563 s32 ReturnValue = WiiSockets[s].closeFd();
564 WiiSockets.erase(s);
565 return ReturnValue;
566}
567
568void WiiSockMan::Update()
569{
570 s32 nfds = 0;
571 fd_set read_fds, write_fds, except_fds;
572 struct timeval t = {0,0};
573 FD_ZERO(&read_fds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&read_fds)->fds_bits
)[0]) : "memory"); } while (0)
;
574 FD_ZERO(&write_fds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&write_fds)->fds_bits
)[0]) : "memory"); } while (0)
;
575 FD_ZERO(&except_fds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&except_fds)->fds_bits
)[0]) : "memory"); } while (0)
;
576 for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
577 {
578 WiiSocket& sock = it->second;
579 if (sock.valid())
580 {
581 FD_SET(sock.fd, &read_fds)((void) (((&read_fds)->fds_bits)[((sock.fd) / (8 * (int
) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((sock.fd)
% (8 * (int) sizeof (__fd_mask))))))
;
582 FD_SET(sock.fd, &write_fds)((void) (((&write_fds)->fds_bits)[((sock.fd) / (8 * (int
) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((sock.fd)
% (8 * (int) sizeof (__fd_mask))))))
;
583 FD_SET(sock.fd, &except_fds)((void) (((&except_fds)->fds_bits)[((sock.fd) / (8 * (
int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((sock.
fd) % (8 * (int) sizeof (__fd_mask))))))
;
584 nfds = max(nfds, sock.fd+1);
585 }
586 else
587 {
588 // Good time to clean up invalid sockets.
589 WiiSockets.erase(sock.fd);
590 }
591 }
592 s32 ret = select(nfds, &read_fds, &write_fds, &except_fds, &t);
593
594 if (ret >= 0)
595 {
596 for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
597 {
598 WiiSocket& sock = it->second;
599 sock.update(
600 FD_ISSET(sock.fd, &read_fds)((((&read_fds)->fds_bits)[((sock.fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((sock.fd) % (8
* (int) sizeof (__fd_mask))))) != 0)
!= 0,
601 FD_ISSET(sock.fd, &write_fds)((((&write_fds)->fds_bits)[((sock.fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((sock.fd) % (8
* (int) sizeof (__fd_mask))))) != 0)
!= 0,
602 FD_ISSET(sock.fd, &except_fds)((((&except_fds)->fds_bits)[((sock.fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((sock.fd) % (8
* (int) sizeof (__fd_mask))))) != 0)
!= 0
603 );
604 }
605 }
606 else
607 {
608 for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
609 {
610 it->second.update(false, false, false);
611 }
612 }
613}
614
615void WiiSockMan::EnqueueReply(u32 CommandAddress, s32 ReturnValue)
616{
617 Memory::Write_U32(8, CommandAddress);
618 // IOS seems to write back the command that was responded to
619 Memory::Write_U32(Memory::Read_U32(CommandAddress), CommandAddress + 8);
620
621 // Return value
622 Memory::Write_U32(ReturnValue, CommandAddress + 4);
623
624 WII_IPC_HLE_Interface::EnqReply(CommandAddress);
625}
626
627
628void WiiSockMan::Convert(WiiSockAddrIn const & from, sockaddr_in& to)
629{
630 to.sin_addr.s_addr = from.addr.addr;
631 to.sin_family = from.family;
632 to.sin_port = from.port;
633}
634
635void WiiSockMan::Convert(sockaddr_in const & from, WiiSockAddrIn& to, s32 addrlen)
636{
637 to.addr.addr = from.sin_addr.s_addr;
638 to.family = from.sin_family & 0xFF;
639 to.port = from.sin_port;
640 if (addrlen < 0 || addrlen > sizeof(WiiSockAddrIn))
641 to.len = sizeof(WiiSockAddrIn);
642 else
643 to.len = addrlen;
644}
645
646#undef ERRORCODE
647#undef EITHER