diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 91eb46505..3c8e50fd5 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -54,13 +54,29 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) { } } +//typedef struct { +// BYTE cfgSizeOfStruct; +// BYTE cfgFlags; +// BYTE cfgSockMaxDgramSockets; +// BYTE cfgSockMaxStreamSockets; +// BYTE cfgSockDefaultRecvBufsizeInK; +// BYTE cfgSockDefaultSendBufsizeInK; +// BYTE cfgKeyRegMax; +// BYTE cfgSecRegMax; +// BYTE cfgQosDataLimitDiv4; +// BYTE cfgQosProbeTimeoutInSeconds; +// BYTE cfgQosProbeRetries; +// BYTE cfgQosSrvMaxSimultaneousResponses; +// BYTE cfgQosPairWaitTimeInSeconds; +//} XNetStartupParams; + SHIM_CALL NetDll_XNetStartup_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t params_ptr = SHIM_GET_ARG_32(1); XELOGD("NetDll_XNetStartup(%d, %.8X)", arg0, params_ptr); - SHIM_SET_RETURN_64(0); + SHIM_SET_RETURN_32(0); } SHIM_CALL NetDll_XNetCleanup_shim(PPCContext* ppc_state, KernelState* state) { @@ -69,7 +85,7 @@ SHIM_CALL NetDll_XNetCleanup_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("NetDll_XNetCleanup(%d, %.8X)", arg0, params_ptr); - SHIM_SET_RETURN_64(0); + SHIM_SET_RETURN_32(0); } SHIM_CALL NetDll_XNetRandom_shim(PPCContext* ppc_state, KernelState* state) { @@ -83,53 +99,81 @@ SHIM_CALL NetDll_XNetRandom_shim(PPCContext* ppc_state, KernelState* state) { // This makes replicating things easier. memset(SHIM_MEM_ADDR(buffer_ptr), 0xBB, length); - SHIM_SET_RETURN_64(0); + SHIM_SET_RETURN_32(0); } SHIM_CALL NetDll_WSAStartup_shim(PPCContext* ppc_state, KernelState* state) { - uint32_t arg0 = SHIM_GET_ARG_32(0); + uint32_t arg0 = SHIM_GET_ARG_32(0); // always 1? uint32_t version = SHIM_GET_ARG_16(1); uint32_t data_ptr = SHIM_GET_ARG_32(2); XELOGD("NetDll_WSAStartup(%d, %.4X, %.8X)", arg0, version, data_ptr); + // TODO: Abstraction layer needed + WSADATA wsaData; + ZeroMemory(&wsaData, sizeof(WSADATA)); + int ret = WSAStartup(version, &wsaData); + + auto data_out = state->memory()->TranslateVirtual(data_ptr); + if (data_ptr) { - SHIM_SET_MEM_16(data_ptr + 0x000, version); - SHIM_SET_MEM_16(data_ptr + 0x002, version); - SHIM_SET_MEM_32(data_ptr + 0x004, 0); - SHIM_SET_MEM_32(data_ptr + 0x105, 0); - SHIM_SET_MEM_16(data_ptr + 0x186, 0); - SHIM_SET_MEM_16(data_ptr + 0x188, 0); + xe::store_and_swap(data_out + 0x000, wsaData.wVersion); + xe::store_and_swap(data_out + 0x002, wsaData.wHighVersion); + std::memcpy(data_out + 0x004, wsaData.szDescription, 0x100); + std::memcpy(data_out + 0x105, wsaData.szSystemStatus, 0x80); + xe::store_and_swap(data_out + 0x186, wsaData.iMaxSockets); + xe::store_and_swap(data_out + 0x188, wsaData.iMaxUdpDg); + // Some games (PoG) want this value round-tripped - they'll compare if it // changes and bugcheck if it does. uint32_t vendor_ptr = SHIM_MEM_32(data_ptr + 0x190); SHIM_SET_MEM_32(data_ptr + 0x190, vendor_ptr); } - SHIM_SET_RETURN_64(0); + SHIM_SET_RETURN_32(ret); } SHIM_CALL NetDll_WSACleanup_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); + XELOGD("NetDll_WSACleanup(%d)", arg0); int ret = WSACleanup(); + SHIM_SET_RETURN_32(ret); } SHIM_CALL NetDll_WSAGetLastError_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("NetDll_WSAGetLastError()"); + int err = WSAGetLastError(); SHIM_SET_RETURN_32(err); } +// typedef struct { +// IN_ADDR ina; // IP address (zero if not static/DHCP) +// IN_ADDR inaOnline; // Online IP address (zero if not online) +// WORD wPortOnline; // Online port +// BYTE abEnet[6]; // Ethernet MAC address +// BYTE abOnline[20]; // Online identification +// } XNADDR; + SHIM_CALL NetDll_XNetGetTitleXnAddr_shim(PPCContext* ppc_state, KernelState* state) { - uint32_t arg0 = SHIM_GET_ARG_32(0); - uint32_t addr_ptr = SHIM_GET_ARG_32(1); + uint32_t arg0 = SHIM_GET_ARG_32(0); // constant 1? + uint32_t addr_ptr = SHIM_GET_ARG_32(1); // XNADDR + XELOGD("NetDll_XNetGetTitleXnAddr(%d, %.8X)", arg0, addr_ptr); - // TODO(benvanik): set addr info. - SHIM_SET_RETURN_32(0x00000002); + + auto addr = state->memory()->TranslateVirtual(addr_ptr); + + xe::store(addr + 0x0, htonl(INADDR_LOOPBACK)); + xe::store_and_swap(addr + 0x4, 0); + xe::store_and_swap(addr + 0x8, 0); + std::memset(addr + 0xA, 0, 6); + std::memset(addr + 0x10, 0, 20); + + SHIM_SET_RETURN_32(0x00000004); // XNET_GET_XNADDR_STATIC } SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim(PPCContext* ppc_state, @@ -137,15 +181,19 @@ SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim(PPCContext* ppc_state, // Games seem to call this before *Startup. If we return 0, they don't even // try. uint32_t arg0 = SHIM_GET_ARG_32(0); + XELOGD("NetDll_XNetGetEthernetLinkStatus(%d)", arg0); + SHIM_SET_RETURN_32(0); } SHIM_CALL NetDll_inet_addr_shim(PPCContext* ppc_state, KernelState* state) { uint32_t cp_ptr = SHIM_GET_ARG_32(0); + auto cp = reinterpret_cast(SHIM_MEM_ADDR(cp_ptr)); XELOGD("NetDll_inet_addr(%.8X(%s))", cp_ptr, cp); uint32_t addr = inet_addr(cp); + SHIM_SET_RETURN_32(addr); } @@ -154,20 +202,25 @@ SHIM_CALL NetDll_socket_shim(PPCContext* ppc_state, KernelState* state) { uint32_t af = SHIM_GET_ARG_32(1); uint32_t type = SHIM_GET_ARG_32(2); uint32_t protocol = SHIM_GET_ARG_32(3); + XELOGD("NetDll_socket(%d, %d, %d, %d)", arg0, af, type, protocol); if (protocol == 0xFE) { protocol = IPPROTO_UDP; } + SOCKET socket_handle = socket(af, type, protocol); assert_true(socket_handle >> 32 == 0); + SHIM_SET_RETURN_32(static_cast(socket_handle)); } SHIM_CALL NetDll_closesocket_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_handle = SHIM_GET_ARG_32(1); + XELOGD("NetDll_closesocket(%d, %.8X)", arg0, socket_handle); int ret = closesocket(socket_handle); + SHIM_SET_RETURN_32(ret); } @@ -178,10 +231,13 @@ SHIM_CALL NetDll_setsockopt_shim(PPCContext* ppc_state, KernelState* state) { uint32_t optname = SHIM_GET_ARG_32(3); uint32_t optval_ptr = SHIM_GET_ARG_32(4); uint32_t optlen = SHIM_GET_ARG_32(5); + XELOGD("NetDll_setsockopt(%d, %.8X, %d, %d, %.8X, %d)", arg0, socket_handle, level, optname, optval_ptr, optlen); + char* optval = reinterpret_cast(SHIM_MEM_ADDR(optval_ptr)); int ret = setsockopt(socket_handle, level, optname, optval, optlen); + SHIM_SET_RETURN_32(ret); } @@ -190,10 +246,13 @@ SHIM_CALL NetDll_ioctlsocket_shim(PPCContext* ppc_state, KernelState* state) { uint32_t socket_handle = SHIM_GET_ARG_32(1); uint32_t cmd = SHIM_GET_ARG_32(2); uint32_t arg_ptr = SHIM_GET_ARG_32(3); + XELOGD("NetDll_ioctlsocket(%d, %.8X, %.8X, %.8X)", arg0, socket_handle, cmd, arg_ptr); + u_long arg = SHIM_MEM_32(arg_ptr); int ret = ioctlsocket(socket_handle, cmd, &arg); + SHIM_SET_MEM_32(arg_ptr, arg); SHIM_SET_RETURN_32(ret); } @@ -203,11 +262,14 @@ SHIM_CALL NetDll_bind_shim(PPCContext* ppc_state, KernelState* state) { uint32_t socket_handle = SHIM_GET_ARG_32(1); uint32_t name_ptr = SHIM_GET_ARG_32(2); uint32_t namelen = SHIM_GET_ARG_32(3); + XELOGD("NetDll_bind(%d, %.8X, %.8X, %d)", arg0, socket_handle, name_ptr, namelen); + sockaddr name; LoadSockaddr(SHIM_MEM_ADDR(name_ptr), &name); int ret = bind(socket_handle, &name, namelen); + SHIM_SET_RETURN_32(ret); } @@ -216,11 +278,14 @@ SHIM_CALL NetDll_connect_shim(PPCContext* ppc_state, KernelState* state) { uint32_t socket_handle = SHIM_GET_ARG_32(1); uint32_t name_ptr = SHIM_GET_ARG_32(2); uint32_t namelen = SHIM_GET_ARG_32(3); + XELOGD("NetDll_connect(%d, %.8X, %.8X, %d)", arg0, socket_handle, name_ptr, namelen); + sockaddr name; LoadSockaddr(SHIM_MEM_ADDR(name_ptr), &name); int ret = connect(socket_handle, &name, namelen); + SHIM_SET_RETURN_32(ret); } @@ -228,8 +293,11 @@ SHIM_CALL NetDll_listen_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_handle = SHIM_GET_ARG_32(1); int32_t backlog = SHIM_GET_ARG_32(2); + XELOGD("NetDll_listen(%d, %.8X, %d)", arg0, socket_handle, backlog); + int ret = listen(socket_handle, backlog); + SHIM_SET_RETURN_32(ret); } @@ -238,11 +306,14 @@ SHIM_CALL NetDll_accept_shim(PPCContext* ppc_state, KernelState* state) { uint32_t socket_handle = SHIM_GET_ARG_32(1); uint32_t addr_ptr = SHIM_GET_ARG_32(2); uint32_t addrlen_ptr = SHIM_GET_ARG_32(3); + XELOGD("NetDll_accept(%d, %.8X, %d)", arg0, socket_handle, addr_ptr, addrlen_ptr); + sockaddr addr; int addrlen; SOCKET ret_socket = accept(socket_handle, &addr, &addrlen); + if (ret_socket == INVALID_SOCKET) { memset(SHIM_MEM_ADDR(addr_ptr), 0, sizeof(addr)); SHIM_SET_MEM_32(addrlen_ptr, sizeof(addr)); @@ -281,8 +352,10 @@ SHIM_CALL NetDll_select_shim(PPCContext* ppc_state, KernelState* state) { uint32_t writefds_ptr = SHIM_GET_ARG_32(3); uint32_t exceptfds_ptr = SHIM_GET_ARG_32(4); uint32_t timeout_ptr = SHIM_GET_ARG_32(5); + XELOGD("NetDll_select(%d, %d, %.8X, %.8X, %.8X, %.8X)", arg0, nfds, readfds_ptr, writefds_ptr, exceptfds_ptr, timeout_ptr); + fd_set readfds = {0}; if (readfds_ptr) { LoadFdset(SHIM_MEM_ADDR(readfds_ptr), &readfds); @@ -314,6 +387,7 @@ SHIM_CALL NetDll_select_shim(PPCContext* ppc_state, KernelState* state) { if (exceptfds_ptr) { StoreFdset(exceptfds, SHIM_MEM_ADDR(exceptfds_ptr)); } + SHIM_SET_RETURN_32(ret); } @@ -323,10 +397,13 @@ SHIM_CALL NetDll_recv_shim(PPCContext* ppc_state, KernelState* state) { uint32_t buf_ptr = SHIM_GET_ARG_32(2); uint32_t len = SHIM_GET_ARG_32(3); uint32_t flags = SHIM_GET_ARG_32(4); + XELOGD("NetDll_recv(%d, %.8X, %.8X, %d, %d)", arg0, socket_handle, buf_ptr, len, flags); + int ret = recv(socket_handle, reinterpret_cast(SHIM_MEM_ADDR(buf_ptr)), len, flags); + SHIM_SET_RETURN_32(ret); } @@ -338,8 +415,10 @@ SHIM_CALL NetDll_recvfrom_shim(PPCContext* ppc_state, KernelState* state) { uint32_t flags = SHIM_GET_ARG_32(4); uint32_t from_ptr = SHIM_GET_ARG_32(5); uint32_t fromlen_ptr = SHIM_GET_ARG_32(6); + XELOGD("NetDll_recvfrom(%d, %.8X, %.8X, %d, %d, %.8X, %.8X)", arg0, socket_handle, buf_ptr, len, flags, from_ptr, fromlen_ptr); + sockaddr from; int fromlen = sizeof(from); int ret = @@ -352,6 +431,7 @@ SHIM_CALL NetDll_recvfrom_shim(PPCContext* ppc_state, KernelState* state) { StoreSockaddr(from, SHIM_MEM_ADDR(from_ptr)); SHIM_SET_MEM_32(fromlen_ptr, fromlen); } + SHIM_SET_RETURN_32(ret); } @@ -361,10 +441,13 @@ SHIM_CALL NetDll_send_shim(PPCContext* ppc_state, KernelState* state) { uint32_t buf_ptr = SHIM_GET_ARG_32(2); uint32_t len = SHIM_GET_ARG_32(3); uint32_t flags = SHIM_GET_ARG_32(4); + XELOGD("NetDll_send(%d, %.8X, %.8X, %d, %d)", arg0, socket_handle, buf_ptr, len, flags); + int ret = send(socket_handle, reinterpret_cast(SHIM_MEM_ADDR(buf_ptr)), len, flags); + SHIM_SET_RETURN_32(ret); } @@ -376,13 +459,16 @@ SHIM_CALL NetDll_sendto_shim(PPCContext* ppc_state, KernelState* state) { uint32_t flags = SHIM_GET_ARG_32(4); uint32_t to_ptr = SHIM_GET_ARG_32(5); uint32_t tolen = SHIM_GET_ARG_32(6); + XELOGD("NetDll_sendto(%d, %.8X, %.8X, %d, %d, %.8X, %d)", arg0, socket_handle, buf_ptr, len, flags, to_ptr, tolen); + sockaddr to; LoadSockaddr(SHIM_MEM_ADDR(to_ptr), &to); int ret = sendto(socket_handle, reinterpret_cast(SHIM_MEM_ADDR(buf_ptr)), len, flags, &to, tolen); + SHIM_SET_RETURN_32(ret); }