Implement IOCtlV 3 (ReadConfig) for /dev/net/ncd/manage.

This fixes an error message when trying to play Mario Kart Wii over WFC, although it still fails when trying to connect now.
Also fix some cosmetic issues (double include and indentation).<NeoBrain Patch>

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5222 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Sonicadvance1 2010-03-22 18:19:41 +00:00
parent cac8fa8afc
commit 744167f561
2 changed files with 198 additions and 39 deletions

View File

@ -46,12 +46,13 @@ it failed)
#endif
#include "WII_IPC_HLE_Device_net.h"
#include "FileUtil.h"
#include <stdio.h>
#include <string>
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
@ -161,6 +162,37 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
{
// store network configuration
std::string filename(File::GetUserPath(D_WIIUSER_IDX));
filename.append("shared2/sys/net/02/config.dat");
FILE *file = fopen(filename.c_str(), "rb");
if (file == NULL || fread(&m_Ifconfig, sizeof(network_config_t), 1, file) != 1)
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Failed to load /shared2/sys/net/02/config.dat, using dummy configuration");
// wired connection on IP 192.168.1.1 using gateway 192.168.1.2
memset(&m_Ifconfig, 0, sizeof(m_Ifconfig));
m_Ifconfig.header4 = 1; // got one "valid" connection
m_Ifconfig.header6 = 7; // this is always 7?
m_Ifconfig.connection[0].flags = 167;
m_Ifconfig.connection[0].ip[0] = 192;
m_Ifconfig.connection[0].ip[1] = 168;
m_Ifconfig.connection[0].ip[2] = 1;
m_Ifconfig.connection[0].ip[3] = 1;
m_Ifconfig.connection[0].netmask[0] = 255;
m_Ifconfig.connection[0].netmask[1] = 255;
m_Ifconfig.connection[0].netmask[2] = 255;
m_Ifconfig.connection[0].netmask[3] = 255;
m_Ifconfig.connection[0].gateway[0] = 192;
m_Ifconfig.connection[0].gateway[1] = 168;
m_Ifconfig.connection[0].gateway[2] = 1;
m_Ifconfig.connection[0].gateway[3] = 2;
}
if (file)
{
fclose(file);
}
}
CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
@ -169,7 +201,7 @@ CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open");
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
@ -177,37 +209,77 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 _CommandAddress, bool _bForce)
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close");
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close");
if (!_bForce)
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}
bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
{
bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
{
u32 ReturnValue = 0;
SIOCtlVBuffer CommandBuffer(_CommandAddress);
switch (CommandBuffer.Parameter)
{
// WiiMenu
case IOCTL_NCD_GETLINKSTATUS: // 32 Out. 5th
case IOCTL_NCD_SETIFCONFIG3: // ??? It seems that is related to Write and Read information
case IOCTL_NCD_SETIFCONFIG4: // 7004 In, 32 Out. 4th
case 0x05: // 7004 Out, 32 Out. 2nd, 3rd
case 0x06:
case 0x08: // 32 Out, 6 Out. 1st
//break;
case IOCTLV_NCD_READCONFIG: // 7004 out, 32 out
// first out buffer gets filled with contents of /shared2/sys/net/02/config.dat
// TODO: What's the second output buffer for?
{
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETIFCONFIG");
default:
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %i", CommandBuffer.Parameter);
// fill output buffer, taking care of endianness
u32 addr = CommandBuffer.PayloadBuffer.at(0).m_Address;
Memory::WriteBigEData((const u8*)&m_Ifconfig, addr, 8);
addr += 8;
for (unsigned int i = 0;i < 3; i++)
{
netcfg_connection_t *conn = &m_Ifconfig.connection[i];
Memory::WriteBigEData((const u8*)conn, addr, 26);
Memory::Write_U16(Common::swap16(conn->mtu), addr+26);
Memory::WriteBigEData((const u8*)conn->padding_3, addr+28, 8);
Memory::WriteBigEData((const u8*)&conn->proxy_settings, addr+36, 260);
Memory::Write_U16(Common::swap16(conn->proxy_settings.proxy_port), addr+296);
Memory::WriteBigEData((const u8*)&conn->proxy_settings.proxy_username, addr+298, 65);
Memory::Write_U8(conn->padding_4, addr+363);
Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy, addr+364, 260);
Memory::Write_U16(Common::swap16(conn->proxy_settings_copy.proxy_port), addr+624);
Memory::WriteBigEData((const u8*)&conn->proxy_settings_copy.proxy_username, addr+626, 65);
Memory::WriteBigEData((const u8*)conn->padding_5, addr+691, 1641);
addr += sizeof(netcfg_connection_t);
}
ReturnValue = 0;
break;
}
Memory::Write_U32(ReturnValue, _CommandAddress+4);
return true;
case IOCTLV_NCD_SETIFCONFIG4: // 7004 In, 32 Out. 4th
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_SETIFCONFIG4");
break;
case 0x05: // 7004 Out, 32 Out. 2nd, 3rd
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCtlV 0x5");
break;
case IOCTLV_NCD_GETLINKSTATUS: // 32 Out. 5th
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS");
break;
case 0x08: // 32 Out, 6 Out. 1st
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCtlV 0x8");
break;
default:
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter);
break;
}
Memory::Write_U32(ReturnValue, _CommandAddress+4);
return true;
}
// **********************************************************************************
@ -221,7 +293,7 @@ CWII_IPC_HLE_Device_net_ip_top::~CWII_IPC_HLE_Device_net_ip_top()
bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
{
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open");
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
@ -229,7 +301,7 @@ bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_net_ip_top::Close(u32 _CommandAddress, bool _bForce)
{
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close");
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close");
if (!_bForce)
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
@ -240,16 +312,16 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
{
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
u32 Command = Memory::Read_U32(_CommandAddress + 0x0C);
// 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);
u32 ReturnValue = ExecuteCommand(Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
return true;
return true;
}
struct bind_params {
u32 socket;
@ -257,19 +329,19 @@ struct bind_params {
u8 name[28];
};
struct GC_sockaddr {
u8 sa_len;
u8 sa_family;
s8 sa_data[14];
u8 sa_len;
u8 sa_family;
s8 sa_data[14];
};
struct GC_in_addr {
u32 s_addr_; // this cannot be named s_addr under windows - collides with some crazy define.
u32 s_addr_; // this cannot be named s_addr under windows - collides with some crazy define.
};
struct GC_sockaddr_in {
u8 sin_len;
u8 sin_family;
u16 sin_port;
struct GC_in_addr sin_addr;
s8 sin_zero[8];
u8 sin_len;
u8 sin_family;
u16 sin_port;
struct GC_in_addr sin_addr;
s8 sin_zero[8];
};
u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn, u32 BufferInSize, u32 BufferOut, u32 BufferOutSize)
{
@ -286,7 +358,7 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn,
u32 AF = Memory::Read_U32(_BufferIn);
u32 TYPE = Memory::Read_U32(_BufferIn + 0x04);
u32 PROT = Memory::Read_U32(_BufferIn + 0x04 * 2);
u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3);
// u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3);
u32 Socket = (u32)socket(AF, TYPE, PROT);
return Common::swap32(Socket); // So it doesn't get mangled later on
}

View File

@ -20,6 +20,91 @@
#include "WII_IPC_HLE_Device.h"
// data layout of the network configuration file (/shared2/sys/net/02/config.dat)
// needed for /dev/net/ncd/manage
#pragma pack(1)
typedef struct
{
u8 use_proxy; // 0x00 -> no proxy; 0x01 -> proxy
u8 use_proxy_userandpass; // 0x00 -> don't use username and password; 0x01 -> use username and password
u8 padding_1[2];
u8 proxy_name[255];
u8 padding_2;
u16 proxy_port; // 0-34463
u8 proxy_username[32];
u8 padding_3;
u8 proxy_password[32];
} netcfg_proxy_t;
typedef struct
{
// settings common to both wired and wireless connections
u8 flags; // Connection selected
// | ?
// | | Internet test passed
// | | | Use Proxy (1 -> on; 0 -> off)
// | | | |
// 1 0 1 0 0 1 1 0
// | | | |
// | | | Interface (0 -> Internal wireless; 1 -> Wired LAN adapter)
// | | DNS source (0 -> Manual; 1 -> DHCP)
// | IP source (0 -> Manual; 1 -> DHCP)
// ?
u8 padding_1[3];
u8 ip[4];
u8 netmask[4];
u8 gateway[4];
u8 dns1[4];
u8 dns2[4];
u8 padding_2[2];
u16 mtu; // 0 or 576-1500
u8 padding_3[8];
netcfg_proxy_t proxy_settings;
u8 padding_4;
netcfg_proxy_t proxy_settings_copy; // seems to be a duplicate of proxy_settings
u8 padding_5[1297];
// wireless specific settings
u8 ssid[32]; // access Point name.
u8 padding_6;
u8 ssid_length; // length of ssid in bytes.
u8 padding_7[2];
u8 padding_8;
u8 encryption; // (probably) encryption. OPN: 0x00, WEP64: 0x01, WEP128: 0x02 WPA-PSK (TKIP): 0x04, WPA2-PSK (AES): 0x05, WPA-PSK (AES): 0x06
u8 padding_9[2];
u8 padding_10;
u8 key_length; // length of key in bytes. 0x00 for WEP64 and WEP128.
u8 unknown; // 0x00 or 0x01 toogled with a WPA-PSK (TKIP) and with a WEP entered with hex instead of ascii.
u8 padding_11;
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
u8 padding_12[236];
} netcfg_connection_t;
typedef struct
{
u8 header0; // 0x00
u8 header1; // 0x00
u8 header2; // 0x00
u8 header3; // 0x00
u8 header4; // 0x01 if there's at least one valid connection to the Internet.
u8 header5; // 0x00
u8 header6; // always 0x07?
u8 header7; // 0x00
netcfg_connection_t connection[3];
} network_config_t;
#pragma pack()
// **********************************************************************************
// KD is the IOS module responsible for implementing WiiConnect24 functionality. It
// can perform HTTPS downloads, send and receive mail via SMTP, and execute a
@ -205,7 +290,7 @@ private:
};
// **********************************************************************************
// Seems like just wireless stuff?
// Interface for reading and changing network configuration (probably some other stuff as well)
class CWII_IPC_HLE_Device_net_ncd_manage : public IWII_IPC_HLE_Device
{
public:
@ -219,12 +304,14 @@ public:
private:
enum {
IOCTL_NCD_UNK1 = 1, // NCDLockWirelessDriver
IOCTL_NCD_UNK2 = 2, // NCDUnlockWirelessDriver
IOCTL_NCD_SETIFCONFIG3 = 3,
IOCTL_NCD_SETIFCONFIG4 = 4, // NCDGetWirelessMacAddress
IOCTL_NCD_GETLINKSTATUS = 7 // NCDGetLinkStatus
IOCTLV_NCD_UNK1 = 1, // NCDLockWirelessDriver
IOCTLV_NCD_UNK2 = 2, // NCDUnlockWirelessDriver
IOCTLV_NCD_READCONFIG = 3,
IOCTLV_NCD_SETIFCONFIG4 = 4, // NCDGetWirelessMacAddress
IOCTLV_NCD_GETLINKSTATUS = 7 // NCDGetLinkStatus
};
network_config_t m_Ifconfig;
};
#endif