Implemented NetDll_shutdown.
De-borked LoadFdset/StoreFdset in regards to handling of correct counts and invalid sockets.
This commit is contained in:
parent
f3ed9ab91b
commit
2e8c34377f
|
@ -317,6 +317,7 @@ using lpunknown_t = const shim::PointerParam&;
|
|||
template <typename T>
|
||||
using pointer_t = const shim::TypedPointerParam<T>&;
|
||||
|
||||
using int_result_t = shim::Result<int32_t>;
|
||||
using dword_result_t = shim::Result<uint32_t>;
|
||||
using pointer_result_t = shim::Result<uint32_t>;
|
||||
|
||||
|
|
|
@ -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<XSocket>(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<uint32_t>(src);
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
for (u_int i = 0; i < 64; ++i) {
|
||||
SOCKET native_handle = INVALID_SOCKET;
|
||||
if (i < dest->fd_count) {
|
||||
auto socket_handle =
|
||||
static_cast<X_HANDLE>(xe::load_and_swap<uint32_t>(src + 4 + i * 4));
|
||||
if (!socket_handle) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (socket_handle) {
|
||||
// Convert from Xenia -> native
|
||||
auto socket =
|
||||
kernel_state()->object_table()->LookupObject<XSocket>(socket_handle);
|
||||
auto socket = kernel_state()->object_table()->LookupObject<XSocket>(
|
||||
socket_handle);
|
||||
assert_not_null(socket);
|
||||
auto native_handle = socket->native_handle();
|
||||
|
||||
dest->fd_array[i] = native_handle;
|
||||
}
|
||||
}
|
||||
dest->fd_array[i] = native_handle;
|
||||
}
|
||||
}
|
||||
|
||||
void StoreFdset(const fd_set& src, uint8_t* dest) {
|
||||
xe::store_and_swap<uint32_t>(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
|
||||
|
||||
if (socket_handle != INVALID_SOCKET) {
|
||||
assert_true(socket_handle >> 32 == 0);
|
||||
xe::store_and_swap<uint32_t>(dest + 4 + i * 4,
|
||||
static_cast<uint32_t>(socket_handle));
|
||||
} else {
|
||||
xe::store_and_swap<uint32_t>(dest + 4 + i * 4, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ object_ref<XSocket> 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<char*>(buf), buf_len, flags);
|
||||
}
|
||||
|
|
|
@ -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<XSocket> 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);
|
||||
|
|
Loading…
Reference in New Issue