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>
|
template <typename T>
|
||||||
using pointer_t = const shim::TypedPointerParam<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 dword_result_t = shim::Result<uint32_t>;
|
||||||
using pointer_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,
|
DECLARE_XAM_EXPORT(NetDll_closesocket,
|
||||||
ExportTag::kImplemented | ExportTag::kNetworking);
|
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_result_t NetDll_setsockopt(dword_t caller, dword_t socket_handle,
|
||||||
dword_t level, dword_t optname,
|
dword_t level, dword_t optname,
|
||||||
lpvoid_t optval_ptr, dword_t optlen) {
|
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) {
|
void LoadFdset(const uint8_t* src, fd_set* dest) {
|
||||||
dest->fd_count = xe::load_and_swap<uint32_t>(src);
|
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 =
|
auto socket_handle =
|
||||||
static_cast<X_HANDLE>(xe::load_and_swap<uint32_t>(src + 4 + i * 4));
|
static_cast<X_HANDLE>(xe::load_and_swap<uint32_t>(src + 4 + i * 4));
|
||||||
if (!socket_handle) {
|
if (socket_handle) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert from Xenia -> native
|
// Convert from Xenia -> native
|
||||||
auto socket =
|
auto socket = kernel_state()->object_table()->LookupObject<XSocket>(
|
||||||
kernel_state()->object_table()->LookupObject<XSocket>(socket_handle);
|
socket_handle);
|
||||||
|
assert_not_null(socket);
|
||||||
auto native_handle = socket->native_handle();
|
auto native_handle = socket->native_handle();
|
||||||
|
dest->fd_array[i] = native_handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
dest->fd_array[i] = native_handle;
|
dest->fd_array[i] = native_handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoreFdset(const fd_set& src, uint8_t* dest) {
|
void StoreFdset(const fd_set& src, uint8_t* dest) {
|
||||||
xe::store_and_swap<uint32_t>(dest, src.fd_count);
|
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];
|
SOCKET socket_handle = src.fd_array[i];
|
||||||
|
|
||||||
// TODO: Native -> Xenia
|
// TODO: Native -> Xenia
|
||||||
|
|
||||||
|
if (socket_handle != INVALID_SOCKET) {
|
||||||
assert_true(socket_handle >> 32 == 0);
|
assert_true(socket_handle >> 32 == 0);
|
||||||
xe::store_and_swap<uint32_t>(dest + 4 + i * 4,
|
xe::store_and_swap<uint32_t>(dest + 4 + i * 4,
|
||||||
static_cast<uint32_t>(socket_handle));
|
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;
|
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) {
|
int XSocket::Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags) {
|
||||||
return recv(native_handle_, reinterpret_cast<char*>(buf), buf_len, 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 Bind(N_XSOCKADDR_IN* name, int name_len);
|
||||||
X_STATUS Listen(int backlog);
|
X_STATUS Listen(int backlog);
|
||||||
object_ref<XSocket> Accept(N_XSOCKADDR* name, int* name_len);
|
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 Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags);
|
||||||
int Send(const 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