Bug Summary

File:Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp
Location:line 93, column 6
Description:Value stored to 'BufferOutSize' 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
6/*
7The /dev/net/kd/request requests are part of what is called WiiConnect24,
8it's used by for example SSBB, Mario Kart, Metroid Prime 3
9
100x01 SuspendScheduler (Input: none, Output: 32 bytes)
110x02 ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes) // Sounds like it will
12 check if it should suspend the updates scheduler or not. If I returned
13 (OutBuffer: 0, Ret: -1) to Metroid Prime 3 it got stuck in an endless loops of
14 requests, probably harmless but I changed it to (OutBuffer: 1, Ret: 0) to stop
15 the calls. However then it also calls 0x3 and then changes its error message
16 to a Wii Memory error message from just a general Error message.
17
180x03 ? (Input: none, Output: 32 bytes) // This is only called if 0x02
19 does not return -1
200x0f NWC24iRequestGenerateUserId (Input: none, Output: 32 bytes)
21
22Requests are made in this order by these games
23 Mario Kart: 2, 1, f, 3
24 SSBB: 2, 3
25
26For Mario Kart I had to return -1 from at least 2, f and 3 to convince it that the network
27was unavailable and prevent if from looking for shared2/wc24 files (and do a PPCHalt when
28it failed)
29*/
30
31#ifdef _MSC_VER
32#pragma warning(disable : 4065) // switch statement contains 'default' but no 'case' labels
33#endif
34
35#include "WII_IPC_HLE_Device_net.h"
36#include "../ConfigManager.h"
37#include "FileUtil.h"
38#include <stdio.h>
39#include <string>
40#ifdef _WIN32
41#include <ws2tcpip.h>
42#include <iphlpapi.h>
43#elif defined(__linux__1)
44#include <sys/types.h>
45#include <sys/socket.h>
46#include <sys/ioctl.h>
47#include <netinet/in.h>
48#include <net/if.h>
49#else
50#include <sys/types.h>
51#include <sys/socket.h>
52#include <netinet/in.h>
53#endif
54
55extern std::queue<std::pair<u32,std::string> > g_ReplyQueueLater;
56
57// **********************************************************************************
58// Handle /dev/net/kd/request requests
59CWII_IPC_HLE_Device_net_kd_request::CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName)
60 : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
61 , m_UserID("Dolphin-EMU")
62 // TODO: Dump the true ID from real Wii
63{
64}
65
66CWII_IPC_HLE_Device_net_kd_request::~CWII_IPC_HLE_Device_net_kd_request()
67{
68}
69
70bool CWII_IPC_HLE_Device_net_kd_request::Open(u32 _CommandAddress, u32 _Mode)
71{
72 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Open")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 72, "NET_KD_REQ: Open"); } } while (0)
;
73 Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
74 m_Active = true;
75 return true;
76}
77
78bool CWII_IPC_HLE_Device_net_kd_request::Close(u32 _CommandAddress, bool _bForce)
79{
80 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Close")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 80, "NET_KD_REQ: Close"); } } while (0)
;
81 if (!_bForce)
82 Memory::Write_U32(0, _CommandAddress + 4);
83 m_Active = false;
84 return true;
85}
86
87bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
88{
89 u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
90 u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
91 u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
92 u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
93 u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
Value stored to 'BufferOutSize' during its initialization is never read
94
95 u32 ReturnValue = 0;
96 switch (Parameter)
97 {
98 case IOCTL_NWC24_SUSPEND_SCHEDULAR:
99 // NWC24iResumeForCloseLib from NWC24SuspendScheduler (Input: none, Output: 32 bytes)
100 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 100, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI"); } }
while (0)
;
101 break;
102
103 case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib
104 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 104, "NET_KD_REQ: IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR - NI"
); } } while (0)
;
105 break;
106
107 case IOCTL_NWC24_UNK_3: // NWC24iResumeForCloseLib
108 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_UNK_3 - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 108, "NET_KD_REQ: IOCTL_NWC24_UNK_3 - NI"); } } while (0)
;
109 break;
110
111 case IOCTL_NWC24_STARTUP_SOCKET: // NWC24iStartupSocket
112 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 112, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI"); } } while
(0)
;
113 break;
114
115 case IOCTL_NWC24_LOCK_SOCKET: // WiiMenu
116 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_LOCK_SOCKET - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 116, "NET_KD_REQ: IOCTL_NWC24_LOCK_SOCKET - NI"); } } while
(0)
;
117 break;
118
119 case IOCTL_NWC24_UNLOCK_SOCKET:
120 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_UNLOCK_SOCKET - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 120, "NET_KD_REQ: IOCTL_NWC24_UNLOCK_SOCKET - NI"); } } while
(0)
;
121 break;
122
123 case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes)
124 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 124, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID"); }
} while (0)
;
125 memcpy(Memory::GetPointer(BufferOut), m_UserID.c_str(), m_UserID.length() + 1);
126 break;
127
128 case IOCTL_NWC24_GET_SCHEDULAR_STAT:
129 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_GET_SCHEDULAR_STAT - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 129, "NET_KD_REQ: IOCTL_NWC24_GET_SCHEDULAR_STAT - NI"); } }
while (0)
;
130 break;
131
132 case IOCTL_NWC24_SAVE_MAIL_NOW:
133 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_SAVE_MAIL_NOW - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 133, "NET_KD_REQ: IOCTL_NWC24_SAVE_MAIL_NOW - NI"); } } while
(0)
;
134 break;
135
136 case IOCTL_NWC24_REQUEST_SHUTDOWN:
137 // if ya set the IOS version to a very high value this happens ...
138 INFO_LOG(WII_IPC_NET, "NET_KD_REQ: IOCTL_NWC24_REQUEST_SHUTDOWN - NI")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 138, "NET_KD_REQ: IOCTL_NWC24_REQUEST_SHUTDOWN - NI"); } } while
(0)
;
139 break;
140
141 default:
142 INFO_LOG(WII_IPC_NET, "/dev/net/kd/request::IOCtl request 0x%x (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_IPC_HLE_Device_net.cpp"
, 143, "/dev/net/kd/request::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize
); } } while (0)
143 Parameter, 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_IPC_HLE_Device_net.cpp"
, 143, "/dev/net/kd/request::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize
); } } while (0)
;
144 break;
145 }
146
147 // g_ReplyQueueLater.push(std::pair<u32, std::string>(_CommandAddress, GetDeviceName()));
148 Memory::Write_U32(ReturnValue, _CommandAddress + 4);
149
150 return true;
151}
152
153
154// **********************************************************************************
155// Handle /dev/net/ncd/manage requests
156CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _DeviceID, const std::string& _rDeviceName)
157 : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
158{
159 // store network configuration
160 const std::string filename(File::GetUserPath(D_WIIUSER_IDX) + "shared2/sys/net/02/config.dat");
161
162 File::IOFile file(filename, "rb");
163 if (!file.ReadBytes(&m_Ifconfig, 1))
164 {
165 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Failed to load /shared2/sys/net/02/config.dat, using dummy configuration")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 165, "NET_NCD_MANAGE: Failed to load /shared2/sys/net/02/config.dat, using dummy configuration"
); } } while (0)
;
166
167 // wired connection on IP 192.168.1.1 using gateway 192.168.1.2
168 memset(&m_Ifconfig, 0, sizeof(m_Ifconfig));
169 m_Ifconfig.header4 = 1; // got one "valid" connection
170 m_Ifconfig.header6 = 7; // this is always 7?
171 m_Ifconfig.connection[0].flags = 167;
172 m_Ifconfig.connection[0].ip[0] = 192;
173 m_Ifconfig.connection[0].ip[1] = 168;
174 m_Ifconfig.connection[0].ip[2] = 1;
175 m_Ifconfig.connection[0].ip[3] = 1;
176 m_Ifconfig.connection[0].netmask[0] = 255;
177 m_Ifconfig.connection[0].netmask[1] = 255;
178 m_Ifconfig.connection[0].netmask[2] = 255;
179 m_Ifconfig.connection[0].netmask[3] = 255;
180 m_Ifconfig.connection[0].gateway[0] = 192;
181 m_Ifconfig.connection[0].gateway[1] = 168;
182 m_Ifconfig.connection[0].gateway[2] = 1;
183 m_Ifconfig.connection[0].gateway[3] = 2;
184 }
185}
186
187CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
188{
189}
190
191bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
192{
193 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 193, "NET_NCD_MANAGE: Open"); } } while (0)
;
194 Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
195 m_Active = true;
196 return true;
197}
198
199bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 _CommandAddress, bool _bForce)
200{
201 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 201, "NET_NCD_MANAGE: Close"); } } while (0)
;
202 if (!_bForce)
203 Memory::Write_U32(0, _CommandAddress + 4);
204 m_Active = false;
205 return true;
206}
207
208bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
209{
210 u32 ReturnValue = 0;
211
212 SIOCtlVBuffer CommandBuffer(_CommandAddress);
213
214 switch (CommandBuffer.Parameter)
215 {
216 case IOCTLV_NCD_READCONFIG: // 7004 out, 32 out
217 // first out buffer gets filled with contents of /shared2/sys/net/02/config.dat
218 // TODO: What's the second output buffer for?
219 {
220 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETIFCONFIG")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 220, "NET_NCD_MANAGE: IOCTLV_NCD_GETIFCONFIG"); } } while (
0)
;
221
222 // fill output buffer, taking care of endianness
223 u32 addr = CommandBuffer.PayloadBuffer.at(0).m_Address;
224 Memory::WriteBigEData((const u8*)&m_Ifconfig, addr, 8);
225 addr += 8;
226 for (unsigned int i = 0; i < 3; i++)
227 {
228 netcfg_connection_t *conn = &m_Ifconfig.connection[i];
229
230 Memory::WriteBigEData((const u8*)conn, addr, 26);
231 Memory::Write_U16(Common::swap16(conn->mtu), addr+26);
232 Memory::WriteBigEData((const u8*)conn->padding_3, addr+28, 8);
233
234 Memory::WriteBigEData((const u8*)&conn->proxy_settings, addr+36, 260);
235 Memory::Write_U16(Common::swap16(conn->proxy_settings.proxy_port), addr+296);
236 Memory::WriteBigEData((const u8*)&conn->proxy_settings.proxy_username, addr+298, 65);
237 Memory::Write_U8(conn->padding_4, addr+363);
238
239 Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy, addr+364, 260);
240 Memory::Write_U16(Common::swap16(conn->proxy_settings_copy.proxy_port), addr+624);
241 Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy.proxy_username, addr+626, 65);
242 Memory::WriteBigEData((const u8*)conn->padding_5, addr+691, 1641);
243 addr += sizeof(netcfg_connection_t);
244 }
245 ReturnValue = 0;
246 break;
247 }
248
249 case IOCTLV_NCD_UNK4: // 7004 In, 32 Out. 4th
250 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_UNK4")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 250, "NET_NCD_MANAGE: IOCTLV_NCD_UNK4"); } } while (0)
;
251 break;
252
253 case 0x05: // 7004 Out, 32 Out. 2nd, 3rd
254 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCtlV 0x5")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 254, "NET_NCD_MANAGE: IOCtlV 0x5"); } } while (0)
;
255 break;
256
257 case IOCTLV_NCD_GETLINKSTATUS: // 32 Out. 5th
258 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 258, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS"); } } while
(0)
;
259 break;
260
261 case IOCTLV_NCD_GETWIRELESSMACADDRESS: // 32 Out, 6 Out. 1st
262 // TODO: What's the first output buffer for?
263 // second out buffer gets filled with first four bytes of the wireless MAC address.
264 // No idea why the fifth and sixth bytes are left untouched.
265 {
266 // hardcoded address as a fallback
267 const u8 default_address[] = { 0x00, 0x19, 0x1e, 0xfd, 0x71, 0x84 };
268
269 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 269, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS"); }
} while (0)
;
270
271 if (!SConfig::GetInstance().m_WirelessMac.empty())
272 {
273 int x = 0;
274 int tmpaddress[6];
275 for (unsigned int i = 0; i < SConfig::GetInstance().m_WirelessMac.length() && x < 6; i++)
276 {
277 if (SConfig::GetInstance().m_WirelessMac[i] == ':' || SConfig::GetInstance().m_WirelessMac[i] == '-')
278 continue;
279
280 std::stringstream ss;
281 ss << std::hex << SConfig::GetInstance().m_WirelessMac[i];
282 if (SConfig::GetInstance().m_WirelessMac[i+1] != ':' && SConfig::GetInstance().m_WirelessMac[i+1] != '-')
283 {
284 ss << std::hex << SConfig::GetInstance().m_WirelessMac[i+1];
285 i++;
286 }
287 ss >> tmpaddress[x];
288 x++;
289 }
290 u8 address[6];
291 for (int i = 0; i < 6;i++)
292 address[i] = tmpaddress[i];
293 Memory::WriteBigEData(address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
294 break;
295 }
296
297#if defined(__linux__1)
298 const char *check_devices[3] = { "wlan0", "ath0", "eth0" };
299 int fd, ret;
300 struct ifreq ifr;
301
302 fd = socket(AF_INET2, SOCK_DGRAMSOCK_DGRAM, 0);
303 ifr.ifr_addrifr_ifru.ifru_addr.sa_family = AF_INET2;
304
305 for (unsigned int dev = 0; dev < 3; dev++ )
306 {
307 strncpy(ifr.ifr_nameifr_ifrn.ifrn_name, check_devices[dev], IFNAMSIZ16-1);
308 ret = ioctl(fd, SIOCGIFHWADDR0x8927, &ifr);
309 if (ret == 0)
310 {
311 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS returning local MAC address of %s", check_devices[dev])do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 311, "NET_NCD_MANAGE: IOCTLV_NCD_GETWIRELESSMACADDRESS returning local MAC address of %s"
, check_devices[dev]); } } while (0)
;
312 Memory::WriteBigEData((const u8*)ifr.ifr_hwaddrifr_ifru.ifru_hwaddr.sa_data, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
313 break;
314 }
315 }
316 if (ret != 0)
317 {
318 // fall back to the hardcoded address
319 Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
320 }
321 close(fd);
322
323#elif defined(_WIN32)
324 IP_ADAPTER_INFO *adapter_info = NULL__null;
325 DWORD len = 0;
326
327 DWORD ret = GetAdaptersInfo(adapter_info, &len);
328 if (ret != ERROR_BUFFER_OVERFLOW || !len)
329 {
330 Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
331 break;
332 }
333
334 // LPFaint99: len is sizeof(IP_ADAPTER_INFO) * nics - 0x20
335 adapter_info = new IP_ADAPTER_INFO[(len / sizeof(IP_ADAPTER_INFO)) + 1];
336 ret = GetAdaptersInfo(adapter_info, &len);
337
338 if (SUCCEEDED(ret)) Memory::WriteBigEData(adapter_info->Address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
339 else Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
340 delete[] adapter_info;
341#else
342 Memory::WriteBigEData(default_address, CommandBuffer.PayloadBuffer.at(1).m_Address, 4);
343#endif
344 break;
345 }
346
347 default:
348 INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 348, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter)
; } } while (0)
;
349 break;
350 }
351
352 Memory::Write_U32(ReturnValue, _CommandAddress+4);
353 return true;
354}
355
356// **********************************************************************************
357// Handle /dev/net/ip/top requests
358CWII_IPC_HLE_Device_net_ip_top::CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName)
359 : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
360{
361}
362
363CWII_IPC_HLE_Device_net_ip_top::~CWII_IPC_HLE_Device_net_ip_top()
364{
365}
366
367bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
368{
369 INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 369, "NET_IP_TOP: Open"); } } while (0)
;
370 Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
371 m_Active = true;
372 return true;
373}
374
375bool CWII_IPC_HLE_Device_net_ip_top::Close(u32 _CommandAddress, bool _bForce)
376{
377 INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 377, "NET_IP_TOP: Close"); } } while (0)
;
378 if (!_bForce)
379 Memory::Write_U32(0, _CommandAddress + 4);
380 m_Active = false;
381 return true;
382}
383
384bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
385{
386 u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
387 u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
388 u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
389 u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
390 u32 Command = Memory::Read_U32(_CommandAddress + 0x0C);
391
392// INFO_LOG(WII_IPC_NET,"%s - Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)\n", GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
393
394 u32 ReturnValue = ExecuteCommand(Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
395 Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
396
397 return true;
398}
399struct bind_params
400{
401 u32 socket;
402 u32 has_name;
403 u8 name[28];
404};
405
406struct GC_sockaddr
407{
408 u8 sa_len;
409 u8 sa_family;
410 s8 sa_data[14];
411};
412
413struct GC_in_addr
414{
415 u32 s_addr_; // this cannot be named s_addr under windows - collides with some crazy define.
416};
417
418struct GC_sockaddr_in
419{
420 u8 sin_len;
421 u8 sin_family;
422 u16 sin_port;
423 struct GC_in_addr sin_addr;
424 s8 sin_zero[8];
425};
426
427u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn, u32 BufferInSize, u32 BufferOut, u32 BufferOutSize)
428{
429 // Clean the location of the output buffer to zeros as a safety precaution */
430 Memory::Memset(BufferOut, 0, BufferOutSize);
431
432 switch (_Command)
433 {
434 case IOCTL_SO_STARTUP:
435 break;
436
437 case IOCTL_SO_SOCKET:
438 {
439 u32 AF = Memory::Read_U32(_BufferIn);
440 u32 TYPE = Memory::Read_U32(_BufferIn + 0x04);
441 u32 PROT = Memory::Read_U32(_BufferIn + 0x04 * 2);
442// u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3);
443 u32 Socket = (u32)socket(AF, TYPE, PROT);
444 return Common::swap32(Socket); // So it doesn't get mangled later on
445 break;
446 }
447
448 case IOCTL_SO_BIND:
449 {
450 bind_params *addr = (bind_params*)Memory::GetPointer(_BufferIn);
451 GC_sockaddr_in addrPC;
452 memcpy(&addrPC, addr->name, sizeof(GC_sockaddr_in));
453 sockaddr_in address;
454 address.sin_family = addrPC.sin_family;
455 address.sin_addr.s_addr = addrPC.sin_addr.s_addr_;
456 address.sin_port = htons(addrPC.sin_port);
457 int Return = bind(addr->socket, (sockaddr*)&address, sizeof(address));
458 return Return;
459 //int bind(int s, struct sockaddr *addr, int addrlen);
460 break;
461 }
462
463 case IOCTL_SO_LISTEN:
464 {
465 u32 S = Memory::Read_U32(_BufferIn);
466 u32 BACKLOG = Memory::Read_U32(_BufferIn + 0x04);
467 u32 Return = listen(S, BACKLOG);
468 return Return;
469 break;
470 }
471
472 case IOCTL_SO_ACCEPT:
473 {
474 //TODO: (Sonic)Check if this is correct
475 u32 S = Memory::Read_U32(_BufferIn);
476 socklen_t addrlen;
477 struct sockaddr_in address;
478 u32 Return = (u32)accept(S, (struct sockaddr *)&address, &addrlen);
479 GC_sockaddr_in *addr = (GC_sockaddr_in*)Memory::GetPointer(BufferOut);
480 addr->sin_family = (u8)address.sin_family;
481 addr->sin_addr.s_addr_ = address.sin_addr.s_addr;
482 addr->sin_port = address.sin_port;
483 socklen_t *Len = (socklen_t *)Memory::GetPointer(BufferOut + 0x04);
484 *Len = addrlen;
485 return Return;
486 //int accept(int s, struct sockaddr *addr, int *addrlen);
487 ///dev/net/ip/top::IOCtl request 0x1 (BufferIn: (000318c0, 4), BufferOut: (00058a4c, 8)
488 }
489
490 case IOCTL_SO_GETHOSTID:
491 return 127 << 24 | 1;
492 break;
493
494 default:
495 INFO_LOG(WII_IPC_NET,"/dev/net/ip/top::IOCtl request 0x%x (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_IPC_HLE_Device_net.cpp"
, 496, "/dev/net/ip/top::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, _Command, _BufferIn, BufferInSize, BufferOut, BufferOutSize
); } } while (0)
496 _Command, _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_IPC_HLE_Device_net.cpp"
, 496, "/dev/net/ip/top::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
, _Command, _BufferIn, BufferInSize, BufferOut, BufferOutSize
); } } while (0)
;
497 break;
498 }
499
500 // We return a success for any potential unknown requests
501 return 0;
502}
503
504bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 _CommandAddress)
505{
506 u32 ReturnValue = 0;
507
508 SIOCtlVBuffer CommandBuffer(_CommandAddress);
509 switch (CommandBuffer.Parameter)
510 {
511 case IOCTL_SO_BIND:
512 case IOCTLV_SO_RECVFROM:
513 case IOCTL_SO_SOCKET:
514 case IOCTL_SO_GETHOSTID:
515 case IOCTL_SO_STARTUP:
516 //break;
517
518 default:
519 INFO_LOG(WII_IPC_NET, "NET_IP_TOP IOCtlV: 0x%08X\n", CommandBuffer.Parameter)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp"
, 519, "NET_IP_TOP IOCtlV: 0x%08X\n", CommandBuffer.Parameter
); } } while (0)
;
520 break;
521 }
522
523 Memory::Write_U32(ReturnValue, _CommandAddress+4);
524 return true;
525}