Bug Summary

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