From 0b90d5edf91751440b04c6d54bc6b3fdf17b4476 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 17 Nov 2021 12:30:39 +0100 Subject: [PATCH 1/5] [XAM/Net] Implemented NetDll_getsockname --- src/xenia/kernel/xam/xam_net.cc | 23 +++++++++++++++++++++++ src/xenia/kernel/xsocket.cc | 12 ++++++++++++ src/xenia/kernel/xsocket.h | 1 + 3 files changed, 36 insertions(+) diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index a331f139d..5feb4a5a3 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -1031,6 +1031,29 @@ void NetDll_WSASetLastError_entry(dword_t error_code) { } DECLARE_XAM_EXPORT1(NetDll_WSASetLastError, kNetworking, kImplemented); +dword_result_t NetDll_getsockname_entry(dword_t caller, dword_t socket_handle, + lpvoid_t buf_ptr, lpdword_t len_ptr) { + auto socket = + kernel_state()->object_table()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + int buffer_len = *len_ptr; + + X_STATUS status = socket->GetSockName(buf_ptr, &buffer_len); + if (XFAILED(status)) { + XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + return -1; + } + + *len_ptr = buffer_len; + return 0; +} +DECLARE_XAM_EXPORT1(NetDll_getsockname, kNetworking, kImplemented); + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xsocket.cc b/src/xenia/kernel/xsocket.cc index 8bbc0375e..5c4649a87 100644 --- a/src/xenia/kernel/xsocket.cc +++ b/src/xenia/kernel/xsocket.cc @@ -257,5 +257,17 @@ bool XSocket::QueuePacket(uint32_t src_ip, uint16_t src_port, return true; } +X_STATUS XSocket::GetSockName(uint8_t* buf, int* buf_len) { + struct sockaddr sa = {}; + + int ret = getsockname(native_handle_, &sa, (socklen_t*)buf_len); + if (ret < 0) { + return X_STATUS_UNSUCCESSFUL; + } + + std::memcpy(buf, &sa, *buf_len); + return X_STATUS_SUCCESS; +} + } // namespace kernel } // namespace xe \ No newline at end of file diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index f77e2d8eb..984f0a6e5 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -106,6 +106,7 @@ class XSocket : public XObject { X_STATUS Connect(N_XSOCKADDR* name, int name_len); X_STATUS Bind(N_XSOCKADDR_IN* name, int name_len); X_STATUS Listen(int backlog); + X_STATUS GetSockName(uint8_t* buf, int* buf_len); object_ref Accept(N_XSOCKADDR* name, int* name_len); int Shutdown(int how); From d4e5ecb93ba94d8a227f952dd4d3899542ea08ae Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 17 Nov 2021 13:05:24 +0100 Subject: [PATCH 2/5] [XAM/Net] Added unified method of returning WSA error codes --- src/xenia/kernel/xam/xam_net.cc | 28 ++++++++-------------------- src/xenia/kernel/xsocket.cc | 9 +++++++++ src/xenia/kernel/xsocket.h | 2 ++ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 5feb4a5a3..3a40880e7 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -633,8 +633,7 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type, if (XFAILED(result)) { socket->Release(); - uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); - XThread::SetLastError(error); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } @@ -671,12 +670,7 @@ int_result_t NetDll_shutdown_entry(dword_t caller, dword_t socket_handle, auto ret = socket->Shutdown(how); if (ret == -1) { -#ifdef XE_PLATFORM_WIN32 - uint32_t error_code = WSAGetLastError(); - XThread::SetLastError(error_code); -#else - XThread::SetLastError(0x0); -#endif + XThread::SetLastError(socket->GetLastWSAError()); } return ret; } @@ -710,7 +704,7 @@ dword_result_t NetDll_ioctlsocket_entry(dword_t caller, dword_t socket_handle, X_STATUS status = socket->IOControl(cmd, arg_ptr); if (XFAILED(status)) { - XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } @@ -733,7 +727,7 @@ dword_result_t NetDll_bind_entry(dword_t caller, dword_t socket_handle, N_XSOCKADDR_IN native_name(name); X_STATUS status = socket->Bind(&native_name, namelen); if (XFAILED(status)) { - XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } @@ -755,7 +749,7 @@ dword_result_t NetDll_connect_entry(dword_t caller, dword_t socket_handle, N_XSOCKADDR native_name(name); X_STATUS status = socket->Connect(&native_name, namelen); if (XFAILED(status)) { - XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } @@ -775,7 +769,7 @@ dword_result_t NetDll_listen_entry(dword_t caller, dword_t socket_handle, X_STATUS status = socket->Listen(backlog); if (XFAILED(status)) { - XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } @@ -969,13 +963,7 @@ dword_result_t NetDll_recvfrom_entry(dword_t caller, dword_t socket_handle, } if (ret == -1) { -// TODO: Better way of getting the error code -#ifdef XE_PLATFORM_WIN32 - uint32_t error_code = WSAGetLastError(); - XThread::SetLastError(error_code); -#else - XThread::SetLastError(0x0); -#endif + XThread::SetLastError(socket->GetLastWSAError()); } return ret; @@ -1045,7 +1033,7 @@ dword_result_t NetDll_getsockname_entry(dword_t caller, dword_t socket_handle, X_STATUS status = socket->GetSockName(buf_ptr, &buffer_len); if (XFAILED(status)) { - XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + XThread::SetLastError(socket->GetLastWSAError()); return -1; } diff --git a/src/xenia/kernel/xsocket.cc b/src/xenia/kernel/xsocket.cc index 5c4649a87..080feb163 100644 --- a/src/xenia/kernel/xsocket.cc +++ b/src/xenia/kernel/xsocket.cc @@ -269,5 +269,14 @@ X_STATUS XSocket::GetSockName(uint8_t* buf, int* buf_len) { return X_STATUS_SUCCESS; } +uint32_t XSocket::GetLastWSAError() const { + // Todo(Gliniak): Provide error mapping table + // Xbox error codes might not match with what we receive from OS +#ifdef XE_PLATFORM_WIN32 + return WSAGetLastError(); +#endif + return errno; +} + } // namespace kernel } // namespace xe \ No newline at end of file diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index 984f0a6e5..6185e3338 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -118,6 +118,8 @@ class XSocket : public XObject { int SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* to, uint32_t to_len); + uint32_t GetLastWSAError() const; + struct packet { // These values are in network byte order. xe::be src_port; From 2d514ef222e9c20d633e6b86796de1041c7ab164 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 17 Nov 2021 13:10:06 +0100 Subject: [PATCH 3/5] [XAM/Net] Changed parameters type for NetDll_select --- src/xenia/kernel/xam/xam_net.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 3a40880e7..014c61533 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -862,7 +862,7 @@ struct host_set { } }; -int_result_t NetDll_select_entry(int_t caller, int_t nfds, +int_result_t NetDll_select_entry(dword_t caller, dword_t nfds, pointer_t readfds, pointer_t writefds, pointer_t exceptfds, From fa332e13deca32ef5bb636127b8b5aee538419fb Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 17 Nov 2021 22:00:34 +0100 Subject: [PATCH 4/5] [XAM/Net] Removed hardcoded WSA error codes --- src/xenia/kernel/xam/xam_net.cc | 51 ++++++++++++--------------------- src/xenia/kernel/xsocket.h | 8 ++++++ 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 014c61533..6fc3db0cc 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -211,13 +211,13 @@ dword_result_t NetDll_XNetGetOpt_entry(dword_t one, dword_t option_id, case 1: if (*buffer_size < sizeof(XNetStartupParams)) { *buffer_size = sizeof(XNetStartupParams); - return 0x2738; // WSAEMSGSIZE + return uint32_t(X_WSAError::X_WSAEMSGSIZE); } std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams)); return 0; default: XELOGE("NetDll_XNetGetOpt: option {} unimplemented", option_id); - return 0x2726; // WSAEINVAL + return uint32_t(X_WSAError::X_WSAEINVAL); } } DECLARE_XAM_EXPORT1(NetDll_XNetGetOpt, kNetworking, kSketchy); @@ -326,8 +326,7 @@ dword_result_t NetDll_WSASendTo_entry( auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -363,7 +362,7 @@ dword_result_t NetDll_WSAWaitForMultipleEvents_entry(dword_t num_events, dword_t timeout, dword_t alertable) { if (num_events > 64) { - XThread::SetLastError(87); // ERROR_INVALID_PARAMETER + XThread::SetLastError(uint32_t(X_WSAError::X_WSA_INVALID_PARAMETER)); return ~0u; } @@ -645,8 +644,7 @@ dword_result_t NetDll_closesocket_entry(dword_t caller, dword_t socket_handle) { auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -663,8 +661,7 @@ int_result_t NetDll_shutdown_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -682,8 +679,7 @@ dword_result_t NetDll_setsockopt_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -697,8 +693,7 @@ dword_result_t NetDll_ioctlsocket_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -719,8 +714,7 @@ dword_result_t NetDll_bind_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -741,8 +735,7 @@ dword_result_t NetDll_connect_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -762,8 +755,7 @@ dword_result_t NetDll_listen_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -781,16 +773,14 @@ dword_result_t NetDll_accept_entry(dword_t caller, dword_t socket_handle, pointer_t addr_ptr, lpdword_t addrlen_ptr) { if (!addr_ptr) { - // WSAEFAULT - XThread::SetLastError(0x271E); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAEFAULT)); return -1; } auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -922,8 +912,7 @@ dword_result_t NetDll_recv_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -939,8 +928,7 @@ dword_result_t NetDll_recvfrom_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -976,8 +964,7 @@ dword_result_t NetDll_send_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -993,8 +980,7 @@ dword_result_t NetDll_sendto_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } @@ -1024,8 +1010,7 @@ dword_result_t NetDll_getsockname_entry(dword_t caller, dword_t socket_handle, auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { - // WSAENOTSOCK - XThread::SetLastError(0x2736); + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); return -1; } diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index 6185e3338..b0b528847 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -19,6 +19,14 @@ namespace xe { namespace kernel { +enum class X_WSAError : uint32_t { + X_WSA_INVALID_PARAMETER = 0x0057, + X_WSAEFAULT = 0x271E, + X_WSAEINVAL = 0x2726, + X_WSAENOTSOCK = 0x2736, + X_WSAEMSGSIZE = 0x2738, +}; + struct XSOCKADDR { xe::be address_family; char sa_data[14]; From ad6aff001b7674242b3eeba60d5144d66df36d07 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 17 Nov 2021 22:07:35 +0100 Subject: [PATCH 5/5] [XAM/Net] Added note about sharing storage between Rtl and WSA errors --- src/xenia/kernel/xam/xam_net.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 6fc3db0cc..6c4fed539 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -288,6 +288,9 @@ dword_result_t NetDll_WSACleanup_entry(dword_t caller) { } DECLARE_XAM_EXPORT1(NetDll_WSACleanup, kNetworking, kImplemented); +// Instead of using dedicated storage for WSA error like on OS. +// Xbox shares space between normal error codes and WSA errors. +// This under the hood returns directly value received from RtlGetLastError. dword_result_t NetDll_WSAGetLastError_entry() { return XThread::GetLastError(); }