| File: | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h |
| Location: | line 480, column 7 |
| Description: | Value stored to 'BufferOutSize' during its initialization is never read |
| 1 | // Copyright 2013 Dolphin Emulator Project |
| 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. |
| 4 | |
| 5 | #ifndef _WII_IPC_HLE_DEVICE_NET_H_ |
| 6 | #define _WII_IPC_HLE_DEVICE_NET_H_ |
| 7 | |
| 8 | #include "WII_IPC_HLE_Device.h" |
| 9 | |
| 10 | #ifdef _WIN32 |
| 11 | #include <ws2tcpip.h> |
| 12 | #endif |
| 13 | #include "Timer.h" |
| 14 | #include "FileUtil.h" |
| 15 | |
| 16 | // data layout of the network configuration file (/shared2/sys/net/02/config.dat) |
| 17 | // needed for /dev/net/ncd/manage |
| 18 | #pragma pack(push, 1) |
| 19 | struct netcfg_proxy_t |
| 20 | { |
| 21 | u8 use_proxy; |
| 22 | u8 use_proxy_userandpass; |
| 23 | u8 padding_1[2]; |
| 24 | u8 proxy_name[255]; |
| 25 | u8 padding_2; |
| 26 | u16 proxy_port; // 0-34463 |
| 27 | u8 proxy_username[32]; |
| 28 | u8 padding_3; |
| 29 | u8 proxy_password[32]; |
| 30 | }; |
| 31 | |
| 32 | struct netcfg_connection_t |
| 33 | { |
| 34 | enum |
| 35 | { |
| 36 | WIRED_IF = 1, // 0: wifi 1: wired |
| 37 | DNS_DHCP = 2, // 0: manual 1: DHCP |
| 38 | IP_DHCP = 4, // 0: manual 1: DHCP |
| 39 | USE_PROXY = 16, |
| 40 | CONNECTION_TEST_OK = 32, |
| 41 | CONNECTION_SELECTED = 128 |
| 42 | }; |
| 43 | |
| 44 | enum |
| 45 | { |
| 46 | OPEN = 0, |
| 47 | WEP64 = 1, |
| 48 | WEP128 = 2, |
| 49 | WPA_TKIP = 4, |
| 50 | WPA2_AES = 5, |
| 51 | WPA_AES = 6 |
| 52 | }; |
| 53 | |
| 54 | enum status |
| 55 | { |
| 56 | LINK_BUSY = 1, |
| 57 | LINK_NONE, |
| 58 | LINK_WIRED, |
| 59 | LINK_WIFI_DOWN, |
| 60 | LINK_WIFI_UP |
| 61 | }; |
| 62 | |
| 63 | enum |
| 64 | { |
| 65 | PERM_NONE = 0, |
| 66 | PERM_SEND_MAIL = 1, |
| 67 | PERM_RECV_MAIL = 2, |
| 68 | PERM_DOWNLOAD = 4, |
| 69 | PERM_ALL = PERM_SEND_MAIL | PERM_RECV_MAIL | PERM_DOWNLOAD |
| 70 | }; |
| 71 | |
| 72 | // settings common to both wired and wireless connections |
| 73 | u8 flags; |
| 74 | u8 padding_1[3]; |
| 75 | u8 ip[4]; |
| 76 | u8 netmask[4]; |
| 77 | u8 gateway[4]; |
| 78 | u8 dns1[4]; |
| 79 | u8 dns2[4]; |
| 80 | u8 padding_2[2]; |
| 81 | u16 mtu; |
| 82 | u8 padding_3[8]; |
| 83 | netcfg_proxy_t proxy_settings; |
| 84 | u8 padding_4; |
| 85 | netcfg_proxy_t proxy_settings_copy; |
| 86 | u8 padding_5[1297]; |
| 87 | |
| 88 | // wireless specific settings |
| 89 | u8 ssid[32]; |
| 90 | u8 padding_6; |
| 91 | u8 ssid_length; // length of ssid in bytes. |
| 92 | u8 padding_7[3]; |
| 93 | u8 encryption; |
| 94 | u8 padding_8[3]; |
| 95 | u8 key_length; // length of key in bytes. 0x00 for WEP64 and WEP128. |
| 96 | u8 unknown; // 0x00 or 0x01 toggled with a WPA-PSK (TKIP) and with a WEP entered with hex instead of ascii. |
| 97 | u8 padding_9; |
| 98 | u8 key[64]; // encryption key; for WEP, key is stored 4 times (20 bytes for WEP64 and 52 bytes for WEP128) then padded with 0x00 |
| 99 | u8 padding_10[236]; |
| 100 | }; |
| 101 | |
| 102 | struct network_config_t |
| 103 | { |
| 104 | enum |
| 105 | { |
| 106 | IF_NONE, |
| 107 | IF_WIFI, |
| 108 | IF_WIRED |
| 109 | }; |
| 110 | |
| 111 | u32 version; |
| 112 | u8 connType; |
| 113 | u8 linkTimeout; |
| 114 | u8 nwc24Permission; |
| 115 | u8 padding; |
| 116 | |
| 117 | netcfg_connection_t connection[3]; |
| 118 | }; |
| 119 | |
| 120 | enum nwc24_err_t |
| 121 | { |
| 122 | WC24_OK = 0, |
| 123 | WC24_ERR_FATAL = -1, |
| 124 | WC24_ERR_ID_NONEXISTANCE = -34, |
| 125 | WC24_ERR_ID_GENERATED = -35, |
| 126 | WC24_ERR_ID_REGISTERED = -36, |
| 127 | WC24_ERR_ID_NOT_REGISTERED = -44, |
| 128 | }; |
| 129 | |
| 130 | struct nwc24_config_t |
| 131 | { |
| 132 | enum |
| 133 | { |
| 134 | NWC24_IDCS_INITIAL = 0, |
| 135 | NWC24_IDCS_GENERATED = 1, |
| 136 | NWC24_IDCS_REGISTERED = 2 |
| 137 | }; |
| 138 | |
| 139 | enum |
| 140 | { |
| 141 | URL_COUNT = 0x05, |
| 142 | MAX_URL_LENGTH = 0x80, |
| 143 | MAX_EMAIL_LENGTH = 0x40, |
| 144 | MAX_PASSWORD_LENGTH = 0x20, |
| 145 | }; |
| 146 | |
| 147 | u32 magic; /* 'WcCf' 0x57634366 */ |
| 148 | u32 _unk_04; /* must be 8 */ |
| 149 | u64 nwc24_id; |
| 150 | u32 id_generation; |
| 151 | u32 creation_stage; /* 0==not_generated;1==generated;2==registered; */ |
| 152 | char email[MAX_EMAIL_LENGTH]; |
| 153 | char paswd[MAX_PASSWORD_LENGTH]; |
| 154 | char mlchkid[0x24]; |
| 155 | char http_urls[URL_COUNT][MAX_URL_LENGTH]; |
| 156 | u8 reserved[0xDC]; |
| 157 | u32 enable_booting; |
| 158 | u32 checksum; |
| 159 | }; |
| 160 | |
| 161 | #pragma pack(pop) |
| 162 | |
| 163 | |
| 164 | |
| 165 | class NWC24Config |
| 166 | { |
| 167 | private: |
| 168 | std::string path; |
| 169 | nwc24_config_t config; |
| 170 | |
| 171 | public: |
| 172 | NWC24Config() |
| 173 | { |
| 174 | path = File::GetUserPath(D_WIIWC24_IDX) + "nwc24msg.cfg"; |
| 175 | ReadConfig(); |
| 176 | } |
| 177 | |
| 178 | void ResetConfig() |
| 179 | { |
| 180 | int i; |
| 181 | |
| 182 | if (File::Exists(path)) |
| 183 | File::Delete(path); |
| 184 | |
| 185 | const char* urls[5] = { |
| 186 | "https://amw.wc24.wii.com/cgi-bin/account.cgi", |
| 187 | "http://rcw.wc24.wii.com/cgi-bin/check.cgi", |
| 188 | "http://mtw.wc24.wii.com/cgi-bin/receive.cgi", |
| 189 | "http://mtw.wc24.wii.com/cgi-bin/delete.cgi", |
| 190 | "http://mtw.wc24.wii.com/cgi-bin/send.cgi", |
| 191 | }; |
| 192 | |
| 193 | memset(&config, 0, sizeof(config)); |
| 194 | |
| 195 | SetMagic(0x57634366); |
| 196 | SetUnk(8); |
| 197 | SetCreationStage(nwc24_config_t::NWC24_IDCS_INITIAL); |
| 198 | SetEnableBooting(0); |
| 199 | SetEmail("@wii.com"); |
| 200 | |
| 201 | for(i=0; i<nwc24_config_t::URL_COUNT; i++) |
| 202 | { |
| 203 | strncpy(config.http_urls[i], urls[i], nwc24_config_t::MAX_URL_LENGTH); |
| 204 | } |
| 205 | |
| 206 | SetChecksum(CalculateNwc24ConfigChecksum()); |
| 207 | |
| 208 | WriteConfig(); |
| 209 | } |
| 210 | |
| 211 | void WriteConfig() |
| 212 | { |
| 213 | if (!File::Exists(path)) |
| 214 | { |
| 215 | if (!File::CreateFullPath(File::GetUserPath(D_WIIWC24_IDX))) |
| 216 | { |
| 217 | ERROR_LOG(WII_IPC_WC24, "Failed to create directory for WC24")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 217, "Failed to create directory for WC24"); } } while (0); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | File::IOFile(path, "wb").WriteBytes((void*)&config, sizeof(config)); |
| 222 | } |
| 223 | |
| 224 | |
| 225 | void ReadConfig() |
| 226 | { |
| 227 | if (File::Exists(path)) |
| 228 | { |
| 229 | if (!File::IOFile(path, "rb").ReadBytes((void *)&config, sizeof(config))) |
| 230 | ResetConfig(); |
| 231 | else |
| 232 | { |
| 233 | s32 config_error = CheckNwc24Config(); |
| 234 | if(config_error) |
| 235 | ERROR_LOG(WII_IPC_WC24, "There is an error in the config for for WC24: %d", config_error)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 235, "There is an error in the config for for WC24: %d", config_error ); } } while (0); |
| 236 | } |
| 237 | } |
| 238 | else |
| 239 | { |
| 240 | ResetConfig(); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | u32 CalculateNwc24ConfigChecksum(void) |
| 245 | { |
| 246 | u32* ptr = (u32*)&config; |
| 247 | u32 sum = 0; |
| 248 | int i; |
| 249 | for (i=0; i<0xFF; i++) |
| 250 | { |
| 251 | sum += Common::swap32(*ptr++); |
| 252 | } |
| 253 | return sum; |
| 254 | } |
| 255 | |
| 256 | s32 CheckNwc24Config(void) |
| 257 | { |
| 258 | if (Magic() != 0x57634366) /* 'WcCf' magic */ |
| 259 | { |
| 260 | ERROR_LOG(WII_IPC_WC24, "Magic mismatch")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 260, "Magic mismatch"); } } while (0); |
| 261 | return -14; |
| 262 | } |
| 263 | u32 checksum = CalculateNwc24ConfigChecksum(); |
| 264 | DEBUG_LOG(WII_IPC_WC24, "Checksum: %X", checksum)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 264, "Checksum: %X", checksum); } } while (0); |
| 265 | if (Checksum() != checksum) |
| 266 | { |
| 267 | ERROR_LOG(WII_IPC_WC24, "Checksum mismatch expected %X and got %X", checksum, Checksum())do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 267, "Checksum mismatch expected %X and got %X", checksum, Checksum ()); } } while (0); |
| 268 | return -14; |
| 269 | } |
| 270 | if (IdGen() > 0x1F) |
| 271 | { |
| 272 | ERROR_LOG(WII_IPC_WC24, "Id gen error")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_WC24, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 272, "Id gen error"); } } while (0); |
| 273 | return -14; |
| 274 | } |
| 275 | if (Unk() != 8) |
| 276 | return -27; |
| 277 | |
| 278 | return 0; |
| 279 | } |
| 280 | |
| 281 | u32 Magic(){return Common::swap32(config.magic);} |
| 282 | void SetMagic(u32 magic){config.magic = Common::swap32(magic);} |
| 283 | |
| 284 | u32 Unk(){return Common::swap32(config._unk_04);} |
| 285 | void SetUnk(u32 _unk_04){config._unk_04 = Common::swap32(_unk_04);} |
| 286 | |
| 287 | u32 IdGen(){return Common::swap32(config.id_generation);} |
| 288 | void SetIdGen(u32 id_generation){config.id_generation = Common::swap32(id_generation);} |
| 289 | void IncrementIdGen(){ |
| 290 | u32 id_ctr = IdGen(); |
| 291 | id_ctr++; |
| 292 | id_ctr &= 0x1F; |
| 293 | SetIdGen(id_ctr); |
| 294 | } |
| 295 | |
| 296 | u32 Checksum(){return Common::swap32(config.checksum);} |
| 297 | void SetChecksum(u32 checksum){config.checksum = Common::swap32(checksum);} |
| 298 | |
| 299 | u32 CreationStage(){return Common::swap32(config.creation_stage);} |
| 300 | void SetCreationStage(u32 creation_stage){config.creation_stage = Common::swap32(creation_stage);} |
| 301 | |
| 302 | u32 EnableBooting(){return Common::swap32(config.enable_booting);} |
| 303 | void SetEnableBooting(u32 enable_booting){config.enable_booting = Common::swap32(enable_booting);} |
| 304 | |
| 305 | u64 Id(){return Common::swap64(config.nwc24_id);} |
| 306 | void SetId(u64 nwc24_id){config.nwc24_id = Common::swap64(nwc24_id);} |
| 307 | |
| 308 | const char * Email(){return config.email;} |
| 309 | void SetEmail(const char * email) |
| 310 | { |
| 311 | strncpy(config.email, email, nwc24_config_t::MAX_EMAIL_LENGTH); |
| 312 | config.email[nwc24_config_t::MAX_EMAIL_LENGTH-1] = '\0'; |
| 313 | } |
| 314 | |
| 315 | }; |
| 316 | |
| 317 | class WiiNetConfig |
| 318 | { |
| 319 | std::string path; |
| 320 | network_config_t config; |
| 321 | |
| 322 | public: |
| 323 | WiiNetConfig() |
| 324 | { |
| 325 | path = File::GetUserPath(D_WIISYSCONF_IDX) + "net/02/config.dat"; |
| 326 | |
| 327 | ReadConfig(); |
| 328 | } |
| 329 | |
| 330 | void ResetConfig() |
| 331 | { |
| 332 | if (File::Exists(path)) |
| 333 | File::Delete(path); |
| 334 | |
| 335 | memset(&config, 0, sizeof(config)); |
| 336 | config.connType = network_config_t::IF_WIRED; |
| 337 | config.connection[0].flags = |
| 338 | netcfg_connection_t::WIRED_IF | |
| 339 | netcfg_connection_t::DNS_DHCP | |
| 340 | netcfg_connection_t::IP_DHCP | |
| 341 | netcfg_connection_t::CONNECTION_TEST_OK | |
| 342 | netcfg_connection_t::CONNECTION_SELECTED; |
| 343 | |
| 344 | WriteConfig(); |
| 345 | } |
| 346 | |
| 347 | void WriteConfig() |
| 348 | { |
| 349 | if (!File::Exists(path)) |
| 350 | { |
| 351 | if (!File::CreateFullPath( |
| 352 | std::string(File::GetUserPath(D_WIISYSCONF_IDX) + "net/02/"))) |
| 353 | { |
| 354 | ERROR_LOG(WII_IPC_NET, "Failed to create directory for network config file")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 354, "Failed to create directory for network config file"); } } while (0); |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | File::IOFile(path, "wb").WriteBytes((void*)&config, sizeof(config)); |
| 359 | } |
| 360 | |
| 361 | void WriteToMem(const u32 address) |
| 362 | { |
| 363 | Memory::WriteBigEData((const u8 *)&config, address, sizeof(config)); |
| 364 | } |
| 365 | |
| 366 | void ReadFromMem(const u32 address) |
| 367 | { |
| 368 | Memory::ReadBigEData((u8 *)&config, address, sizeof(config)); |
| 369 | } |
| 370 | |
| 371 | void ReadConfig() |
| 372 | { |
| 373 | if (File::Exists(path)) |
| 374 | { |
| 375 | if (!File::IOFile(path, "rb").ReadBytes((void *)&config, sizeof(config))) |
| 376 | ResetConfig(); |
| 377 | } |
| 378 | else |
| 379 | { |
| 380 | ResetConfig(); |
| 381 | } |
| 382 | } |
| 383 | }; |
| 384 | |
| 385 | |
| 386 | ////////////////////////////////////////////////////////////////////////// |
| 387 | // KD is the IOS module responsible for implementing WiiConnect24 functionality. |
| 388 | // It can perform HTTPS downloads, send and receive mail via SMTP, and execute a |
| 389 | // JavaScript-like language while the Wii is in standby mode. |
| 390 | class CWII_IPC_HLE_Device_net_kd_request : public IWII_IPC_HLE_Device |
| 391 | { |
| 392 | public: |
| 393 | CWII_IPC_HLE_Device_net_kd_request(u32 _DeviceID, const std::string& _rDeviceName); |
| 394 | |
| 395 | virtual ~CWII_IPC_HLE_Device_net_kd_request(); |
| 396 | |
| 397 | virtual bool Open(u32 _CommandAddress, u32 _Mode); |
| 398 | virtual bool Close(u32 _CommandAddress, bool _bForce); |
| 399 | virtual bool IOCtl(u32 _CommandAddress); |
| 400 | |
| 401 | private: |
| 402 | enum |
| 403 | { |
| 404 | IOCTL_NWC24_SUSPEND_SCHEDULAR = 0x01, |
| 405 | IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR = 0x02, |
| 406 | IOCTL_NWC24_EXEC_RESUME_SCHEDULAR = 0x03, |
| 407 | IOCTL_NWC24_KD_GET_TIME_TRIGGERS = 0x04, |
| 408 | IOCTL_NWC24_SET_SCHEDULE_SPAN = 0x05, |
| 409 | IOCTL_NWC24_STARTUP_SOCKET = 0x06, |
| 410 | IOCTL_NWC24_CLEANUP_SOCKET = 0x07, |
| 411 | IOCTL_NWC24_LOCK_SOCKET = 0x08, |
| 412 | IOCTL_NWC24_UNLOCK_SOCKET = 0x09, |
| 413 | IOCTL_NWC24_CHECK_MAIL_NOW = 0x0A, |
| 414 | IOCTL_NWC24_SEND_MAIL_NOW = 0x0B, |
| 415 | IOCTL_NWC24_RECEIVE_MAIL_NOW = 0x0C, |
| 416 | IOCTL_NWC24_SAVE_MAIL_NOW = 0x0D, |
| 417 | IOCTL_NWC24_DOWNLOAD_NOW_EX = 0x0E, |
| 418 | IOCTL_NWC24_REQUEST_GENERATED_USER_ID = 0x0F, |
| 419 | IOCTL_NWC24_REQUEST_REGISTER_USER_ID = 0x10, |
| 420 | IOCTL_NWC24_GET_SCHEDULAR_STAT = 0x1E, |
| 421 | IOCTL_NWC24_SET_FILTER_MODE = 0x1F, |
| 422 | IOCTL_NWC24_SET_DEBUG_MODE = 0x20, |
| 423 | IOCTL_NWC24_KD_SET_NEXT_WAKEUP = 0x21, |
| 424 | IOCTL_NWC24_SET_SCRIPT_MODE = 0x22, |
| 425 | IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28, |
| 426 | }; |
| 427 | |
| 428 | enum { |
| 429 | MODEL_RVT = 0, |
| 430 | MODEL_RVV = 0, |
| 431 | MODEL_RVL = 1, |
| 432 | MODEL_RVD = 2, |
| 433 | MODEL_ELSE = 7 |
| 434 | }; |
| 435 | |
| 436 | u8 GetAreaCode(const char * area); |
| 437 | u8 GetHardwareModel(const char * model); |
| 438 | |
| 439 | s32 NWC24MakeUserID(u64* nwc24_id, u32 hollywood_id, u16 id_ctr, u8 hardware_model, u8 area_code); |
| 440 | |
| 441 | NWC24Config config; |
| 442 | }; |
| 443 | |
| 444 | |
| 445 | ////////////////////////////////////////////////////////////////////////// |
| 446 | class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device |
| 447 | { |
| 448 | public: |
| 449 | CWII_IPC_HLE_Device_net_kd_time(u32 _DeviceID, const std::string& _rDeviceName) |
| 450 | : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) |
| 451 | , rtc() |
| 452 | , utcdiff() |
| 453 | { |
| 454 | } |
| 455 | |
| 456 | virtual ~CWII_IPC_HLE_Device_net_kd_time() |
| 457 | {} |
| 458 | |
| 459 | virtual bool Open(u32 _CommandAddress, u32 _Mode) |
| 460 | { |
| 461 | INFO_LOG(WII_IPC_NET, "NET_KD_TIME: 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.h" , 461, "NET_KD_TIME: Open"); } } while (0); |
| 462 | Memory::Write_U32(GetDeviceID(), _CommandAddress+4); |
| 463 | return true; |
| 464 | } |
| 465 | |
| 466 | virtual bool Close(u32 _CommandAddress, bool _bForce) |
| 467 | { |
| 468 | INFO_LOG(WII_IPC_NET, "NET_KD_TIME: 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.h" , 468, "NET_KD_TIME: Close"); } } while (0); |
| 469 | if (!_bForce) |
| 470 | Memory::Write_U32(0, _CommandAddress + 4); |
| 471 | return true; |
| 472 | } |
| 473 | |
| 474 | virtual bool IOCtl(u32 _CommandAddress) |
| 475 | { |
| 476 | u32 Parameter = Memory::Read_U32(_CommandAddress + 0x0C); |
| 477 | u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); |
| 478 | u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); |
| 479 | u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); |
| 480 | u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); |
Value stored to 'BufferOutSize' during its initialization is never read | |
| 481 | |
| 482 | u32 result = 0; |
| 483 | u32 common_result = 0; |
| 484 | // TODO Writes stuff to /shared2/nwc24/misc.bin |
| 485 | u32 update_misc = 0; |
| 486 | |
| 487 | switch (Parameter) |
| 488 | { |
| 489 | case IOCTL_NW24_GET_UNIVERSAL_TIME: |
| 490 | Memory::Write_U64(GetAdjustedUTC(), BufferOut + 4); |
| 491 | break; |
| 492 | |
| 493 | case IOCTL_NW24_SET_UNIVERSAL_TIME: |
| 494 | SetAdjustedUTC(Memory::Read_U64(BufferIn)); |
| 495 | update_misc = Memory::Read_U32(BufferIn + 8); |
| 496 | break; |
| 497 | |
| 498 | case IOCTL_NW24_SET_RTC_COUNTER: |
| 499 | rtc = Memory::Read_U32(BufferIn); |
| 500 | update_misc = Memory::Read_U32(BufferIn + 4); |
| 501 | break; |
| 502 | |
| 503 | case IOCTL_NW24_GET_TIME_DIFF: |
| 504 | Memory::Write_U64(GetAdjustedUTC() - rtc, BufferOut + 4); |
| 505 | break; |
| 506 | |
| 507 | case IOCTL_NW24_UNIMPLEMENTED: |
| 508 | result = -9; |
| 509 | break; |
| 510 | |
| 511 | default: |
| 512 | ERROR_LOG(WII_IPC_NET, "%s - unknown IOCtl: %x\n",do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 513, "%s - unknown IOCtl: %x\n", GetDeviceName().c_str(), Parameter ); } } while (0) |
| 513 | GetDeviceName().c_str(), Parameter)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_NET, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h" , 513, "%s - unknown IOCtl: %x\n", GetDeviceName().c_str(), Parameter ); } } while (0); |
| 514 | break; |
| 515 | } |
| 516 | |
| 517 | // write return values |
| 518 | Memory::Write_U32(common_result, BufferOut); |
| 519 | Memory::Write_U32(result, _CommandAddress + 4); |
| 520 | return true; |
| 521 | } |
| 522 | |
| 523 | private: |
| 524 | enum |
| 525 | { |
| 526 | IOCTL_NW24_GET_UNIVERSAL_TIME = 0x14, |
| 527 | IOCTL_NW24_SET_UNIVERSAL_TIME = 0x15, |
| 528 | IOCTL_NW24_UNIMPLEMENTED = 0x16, |
| 529 | IOCTL_NW24_SET_RTC_COUNTER = 0x17, |
| 530 | IOCTL_NW24_GET_TIME_DIFF = 0x18, |
| 531 | }; |
| 532 | |
| 533 | u64 rtc; |
| 534 | s64 utcdiff; |
| 535 | |
| 536 | // Seconds between 1.1.1970 and 4.1.2008 16:00:38 |
| 537 | static const u64 wii_bias = 0x477E5826; |
| 538 | |
| 539 | // Returns seconds since wii epoch |
| 540 | // +/- any bias set from IOCTL_NW24_SET_UNIVERSAL_TIME |
| 541 | u64 GetAdjustedUTC() const |
| 542 | { |
| 543 | return Common::Timer::GetTimeSinceJan1970() - wii_bias + utcdiff; |
| 544 | } |
| 545 | |
| 546 | // Store the difference between what the wii thinks is UTC and |
| 547 | // what the host OS thinks |
| 548 | void SetAdjustedUTC(u64 wii_utc) |
| 549 | { |
| 550 | utcdiff = Common::Timer::GetTimeSinceJan1970() - wii_bias - wii_utc; |
| 551 | } |
| 552 | }; |
| 553 | |
| 554 | enum NET_IOCTL |
| 555 | { |
| 556 | IOCTL_SO_ACCEPT = 1, |
| 557 | IOCTL_SO_BIND, |
| 558 | IOCTL_SO_CLOSE, |
| 559 | IOCTL_SO_CONNECT, |
| 560 | IOCTL_SO_FCNTL, |
| 561 | IOCTL_SO_GETPEERNAME, |
| 562 | IOCTL_SO_GETSOCKNAME, |
| 563 | IOCTL_SO_GETSOCKOPT, |
| 564 | IOCTL_SO_SETSOCKOPT, |
| 565 | IOCTL_SO_LISTEN, |
| 566 | IOCTL_SO_POLL, |
| 567 | IOCTLV_SO_RECVFROM, |
| 568 | IOCTLV_SO_SENDTO, |
| 569 | IOCTL_SO_SHUTDOWN, |
| 570 | IOCTL_SO_SOCKET, |
| 571 | IOCTL_SO_GETHOSTID, |
| 572 | IOCTL_SO_GETHOSTBYNAME, |
| 573 | IOCTL_SO_GETHOSTBYADDR, |
| 574 | IOCTLV_SO_GETNAMEINFO, |
| 575 | IOCTL_SO_UNK14, |
| 576 | IOCTL_SO_INETATON, |
| 577 | IOCTL_SO_INETPTON, |
| 578 | IOCTL_SO_INETNTOP, |
| 579 | IOCTLV_SO_GETADDRINFO, |
| 580 | IOCTL_SO_SOCKATMARK, |
| 581 | IOCTLV_SO_UNK1A, |
| 582 | IOCTLV_SO_UNK1B, |
| 583 | IOCTLV_SO_GETINTERFACEOPT, |
| 584 | IOCTLV_SO_SETINTERFACEOPT, |
| 585 | IOCTL_SO_SETINTERFACE, |
| 586 | IOCTL_SO_STARTUP, |
| 587 | IOCTL_SO_ICMPSOCKET = 0x30, |
| 588 | IOCTLV_SO_ICMPPING, |
| 589 | IOCTL_SO_ICMPCANCEL, |
| 590 | IOCTL_SO_ICMPCLOSE |
| 591 | }; |
| 592 | |
| 593 | ////////////////////////////////////////////////////////////////////////// |
| 594 | class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device |
| 595 | { |
| 596 | public: |
| 597 | CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName); |
| 598 | |
| 599 | virtual ~CWII_IPC_HLE_Device_net_ip_top(); |
| 600 | |
| 601 | virtual bool Open(u32 _CommandAddress, u32 _Mode); |
| 602 | virtual bool Close(u32 _CommandAddress, bool _bForce); |
| 603 | virtual bool IOCtl(u32 _CommandAddress); |
| 604 | virtual bool IOCtlV(u32 _CommandAddress); |
| 605 | |
| 606 | virtual u32 Update(); |
| 607 | |
| 608 | private: |
| 609 | #ifdef _WIN32 |
| 610 | WSADATA InitData; |
| 611 | #endif |
| 612 | u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize); |
| 613 | u32 ExecuteCommandV(SIOCtlVBuffer& CommandBuffer); |
| 614 | }; |
| 615 | |
| 616 | // ********************************************************************************** |
| 617 | // Interface for reading and changing network configuration (probably some other stuff as well) |
| 618 | class CWII_IPC_HLE_Device_net_ncd_manage : public IWII_IPC_HLE_Device |
| 619 | { |
| 620 | public: |
| 621 | CWII_IPC_HLE_Device_net_ncd_manage(u32 _DeviceID, const std::string& _rDeviceName); |
| 622 | |
| 623 | virtual ~CWII_IPC_HLE_Device_net_ncd_manage(); |
| 624 | |
| 625 | virtual bool Open(u32 _CommandAddress, u32 _Mode); |
| 626 | virtual bool Close(u32 _CommandAddress, bool _bForce); |
| 627 | virtual bool IOCtlV(u32 _CommandAddress); |
| 628 | |
| 629 | private: |
| 630 | enum |
| 631 | { |
| 632 | IOCTLV_NCD_LOCKWIRELESSDRIVER = 0x1, // NCDLockWirelessDriver |
| 633 | IOCTLV_NCD_UNLOCKWIRELESSDRIVER = 0x2, // NCDUnlockWirelessDriver |
| 634 | IOCTLV_NCD_GETCONFIG = 0x3, // NCDiGetConfig |
| 635 | IOCTLV_NCD_SETCONFIG = 0x4, // NCDiSetConfig |
| 636 | IOCTLV_NCD_READCONFIG = 0x5, |
| 637 | IOCTLV_NCD_WRITECONFIG = 0x6, |
| 638 | IOCTLV_NCD_GETLINKSTATUS = 0x7, // NCDGetLinkStatus |
| 639 | IOCTLV_NCD_GETWIRELESSMACADDRESS = 0x8, // NCDGetWirelessMacAddress |
| 640 | }; |
| 641 | |
| 642 | WiiNetConfig config; |
| 643 | }; |
| 644 | |
| 645 | ////////////////////////////////////////////////////////////////////////// |
| 646 | class CWII_IPC_HLE_Device_net_wd_command : public IWII_IPC_HLE_Device |
| 647 | { |
| 648 | public: |
| 649 | CWII_IPC_HLE_Device_net_wd_command(u32 DeviceID, const std::string& DeviceName); |
| 650 | |
| 651 | virtual ~CWII_IPC_HLE_Device_net_wd_command(); |
| 652 | |
| 653 | virtual bool Open(u32 CommandAddress, u32 Mode); |
| 654 | virtual bool Close(u32 CommandAddress, bool Force); |
| 655 | virtual bool IOCtlV(u32 CommandAddress); |
| 656 | |
| 657 | private: |
| 658 | enum |
| 659 | { |
| 660 | IOCTLV_WD_GET_MODE = 0x1001, // WD_GetMode |
| 661 | IOCTLV_WD_SET_LINKSTATE = 0x1002, // WD_SetLinkState |
| 662 | IOCTLV_WD_GET_LINKSTATE = 0x1003, // WD_GetLinkState |
| 663 | IOCTLV_WD_SET_CONFIG = 0x1004, // WD_SetConfig |
| 664 | IOCTLV_WD_GET_CONFIG = 0x1005, // WD_GetConfig |
| 665 | IOCTLV_WD_CHANGE_BEACON = 0x1006, // WD_ChangeBeacon |
| 666 | IOCTLV_WD_DISASSOC = 0x1007, // WD_DisAssoc |
| 667 | IOCTLV_WD_MP_SEND_FRAME = 0x1008, // WD_MpSendFrame |
| 668 | IOCTLV_WD_SEND_FRAME = 0x1009, // WD_SendFrame |
| 669 | IOCTLV_WD_SCAN = 0x100a, // WD_Scan |
| 670 | IOCTLV_WD_CALL_WL = 0x100c, // WD_CallWL |
| 671 | IOCTLV_WD_MEASURE_CHANNEL = 0x100b, // WD_MeasureChannel |
| 672 | IOCTLV_WD_GET_LASTERROR = 0x100d, // WD_GetLastError |
| 673 | IOCTLV_WD_GET_INFO = 0x100e, // WD_GetInfo |
| 674 | IOCTLV_WD_CHANGE_GAMEINFO = 0x100f, // WD_ChangeGameInfo |
| 675 | IOCTLV_WD_CHANGE_VTSF = 0x1010, // WD_ChangeVTSF |
| 676 | IOCTLV_WD_RECV_FRAME = 0x8000, // WD_ReceiveFrame |
| 677 | IOCTLV_WD_RECV_NOTIFICATION = 0x8001 // WD_ReceiveNotification |
| 678 | }; |
| 679 | |
| 680 | enum |
| 681 | { |
| 682 | BSSID_SIZE = 6, |
| 683 | SSID_SIZE = 32 |
| 684 | }; |
| 685 | |
| 686 | enum |
| 687 | { |
| 688 | SCAN_ACTIVE, |
| 689 | SCAN_PASSIVE |
| 690 | }; |
| 691 | |
| 692 | #pragma pack(push, 1) |
| 693 | struct ScanInfo |
| 694 | { |
| 695 | u16 channel_bitmap; |
| 696 | u16 max_channel_time; |
| 697 | u8 bssid[BSSID_SIZE]; |
| 698 | u16 scan_type; |
| 699 | u16 ssid_length; |
| 700 | u8 ssid[SSID_SIZE]; |
| 701 | u8 ssid_match_mask[SSID_SIZE]; |
| 702 | }; |
| 703 | |
| 704 | struct BSSInfo |
| 705 | { |
| 706 | u16 length; |
| 707 | u16 rssi; |
| 708 | u8 bssid[BSSID_SIZE]; |
| 709 | u16 ssid_length; |
| 710 | u8 ssid[SSID_SIZE]; |
| 711 | u16 capabilities; |
| 712 | struct rate |
| 713 | { |
| 714 | u16 basic; |
| 715 | u16 support; |
| 716 | }; |
| 717 | u16 beacon_period; |
| 718 | u16 DTIM_period; |
| 719 | u16 channel; |
| 720 | u16 CF_period; |
| 721 | u16 CF_max_duration; |
| 722 | u16 element_info_length; |
| 723 | u16 element_info[1]; |
| 724 | }; |
| 725 | |
| 726 | struct Info |
| 727 | { |
| 728 | u8 mac[6]; |
| 729 | u16 ntr_allowed_channels; |
| 730 | u16 unk8; |
| 731 | char country[2]; |
| 732 | u32 unkc; |
| 733 | char wlversion[0x50]; |
| 734 | u8 unk[0x30]; |
| 735 | }; |
| 736 | #pragma pack(pop) |
| 737 | }; |
| 738 | |
| 739 | #endif |