From 2e8c34377fc0ced2fa35953be8d3f2f1d82461b6 Mon Sep 17 00:00:00 2001 From: gibbed Date: Mon, 9 Jan 2017 06:56:35 -0600 Subject: [PATCH] Implemented NetDll_shutdown. De-borked LoadFdset/StoreFdset in regards to handling of correct counts and invalid sockets. --- src/xenia/kernel/util/shim_utils.h | 1 + src/xenia/kernel/xam/xam_net.cc | 55 ++++++++++++++++++++++-------- src/xenia/kernel/xsocket.cc | 2 ++ src/xenia/kernel/xsocket.h | 1 + 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index c29345756..d85f868b6 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -317,6 +317,7 @@ using lpunknown_t = const shim::PointerParam&; template using pointer_t = const shim::TypedPointerParam&; +using int_result_t = shim::Result; using dword_result_t = shim::Result; using pointer_result_t = shim::Result; diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index ff64b42bb..87dda45cb 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -577,6 +577,25 @@ dword_result_t NetDll_closesocket(dword_t caller, dword_t socket_handle) { DECLARE_XAM_EXPORT(NetDll_closesocket, ExportTag::kImplemented | ExportTag::kNetworking); +int_result_t NetDll_shutdown(dword_t caller, dword_t socket_handle, int_t how) { + auto socket = + kernel_state()->object_table()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + auto ret = socket->Shutdown(how); + if (ret == SOCKET_ERROR) { + uint32_t error_code = WSAGetLastError(); + XThread::SetLastError(error_code); + } + return ret; +} +DECLARE_XAM_EXPORT(NetDll_shutdown, + ExportTag::kImplemented | ExportTag::kNetworking); + dword_result_t NetDll_setsockopt(dword_t caller, dword_t socket_handle, dword_t level, dword_t optname, lpvoid_t optval_ptr, dword_t optlen) { @@ -710,32 +729,38 @@ DECLARE_XAM_EXPORT(NetDll_accept, void LoadFdset(const uint8_t* src, fd_set* dest) { dest->fd_count = xe::load_and_swap(src); - for (int i = 0; i < 64; ++i) { - auto socket_handle = - static_cast(xe::load_and_swap(src + 4 + i * 4)); - if (!socket_handle) { - break; + for (u_int i = 0; i < 64; ++i) { + SOCKET native_handle = INVALID_SOCKET; + if (i < dest->fd_count) { + auto socket_handle = + static_cast(xe::load_and_swap(src + 4 + i * 4)); + if (socket_handle) { + // Convert from Xenia -> native + auto socket = kernel_state()->object_table()->LookupObject( + socket_handle); + assert_not_null(socket); + auto native_handle = socket->native_handle(); + dest->fd_array[i] = native_handle; + } } - - // Convert from Xenia -> native - auto socket = - kernel_state()->object_table()->LookupObject(socket_handle); - auto native_handle = socket->native_handle(); - dest->fd_array[i] = native_handle; } } void StoreFdset(const fd_set& src, uint8_t* dest) { xe::store_and_swap(dest, src.fd_count); - for (int i = 0; i < 64; ++i) { + for (u_int i = 0; i < src.fd_count; ++i) { SOCKET socket_handle = src.fd_array[i]; // TODO: Native -> Xenia - assert_true(socket_handle >> 32 == 0); - xe::store_and_swap(dest + 4 + i * 4, - static_cast(socket_handle)); + if (socket_handle != INVALID_SOCKET) { + assert_true(socket_handle >> 32 == 0); + xe::store_and_swap(dest + 4 + i * 4, + static_cast(socket_handle)); + } else { + xe::store_and_swap(dest + 4 + i * 4, -1); + } } } diff --git a/src/xenia/kernel/xsocket.cc b/src/xenia/kernel/xsocket.cc index f18cd064d..515a88b53 100644 --- a/src/xenia/kernel/xsocket.cc +++ b/src/xenia/kernel/xsocket.cc @@ -150,6 +150,8 @@ object_ref XSocket::Accept(N_XSOCKADDR* name, int* name_len) { return socket; } +int XSocket::Shutdown(int how) { return shutdown(native_handle_, how); } + int XSocket::Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags) { return recv(native_handle_, reinterpret_cast(buf), buf_len, flags); } diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index 18328ef03..282001b07 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -104,6 +104,7 @@ class XSocket : public XObject { X_STATUS Bind(N_XSOCKADDR_IN* name, int name_len); X_STATUS Listen(int backlog); object_ref Accept(N_XSOCKADDR* name, int* name_len); + int Shutdown(int how); int Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags); int Send(const uint8_t* buf, uint32_t buf_len, uint32_t flags);