diff --git a/src/xenia/kernel/util/object_table.h b/src/xenia/kernel/util/object_table.h index 93306d942..6ac67d1b7 100644 --- a/src/xenia/kernel/util/object_table.h +++ b/src/xenia/kernel/util/object_table.h @@ -50,6 +50,9 @@ class ObjectTable { template object_ref LookupObject(X_HANDLE handle) { auto object = LookupObject(handle, false); + if (T::kObjectType == XObject::Type::Socket) { + object = LookupObject((handle | 0xF8000000), false); + } if (object) { assert_true(object->type() == T::kObjectType); } diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 52c47da29..dd5879754 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -639,7 +639,7 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type, return -1; } - return socket->handle(); + return (socket->handle() & 0x00FFFFFF); } DECLARE_XAM_EXPORT1(NetDll_socket, kNetworking, kImplemented); @@ -691,6 +691,22 @@ dword_result_t NetDll_setsockopt_entry(dword_t caller, dword_t socket_handle, } DECLARE_XAM_EXPORT1(NetDll_setsockopt, kNetworking, kImplemented); +dword_result_t NetDll_getsockopt_entry(dword_t caller, dword_t socket_handle, + dword_t level, dword_t optname, + lpvoid_t optval_ptr, lpdword_t optlen) { + auto socket = + kernel_state()->object_table()->LookupObject(socket_handle); + if (!socket) { + XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK)); + return -1; + } + + int native_len = *optlen; + X_STATUS status = socket->GetOption(level, optname, optval_ptr, &native_len); + return XSUCCEEDED(status) ? 0 : -1; +} +DECLARE_XAM_EXPORT1(NetDll_getsockopt, kNetworking, kImplemented); + dword_result_t NetDll_ioctlsocket_entry(dword_t caller, dword_t socket_handle, dword_t cmd, lpvoid_t arg_ptr) { auto socket = @@ -1044,6 +1060,12 @@ dword_result_t NetDll_XNetRegisterKey_entry(dword_t caller, lpdword_t key_id, } DECLARE_XAM_EXPORT1(NetDll_XNetRegisterKey, kNetworking, kStub); +dword_result_t NetDll_XNetUnregisterKey_entry(dword_t caller, lpdword_t key_id, + lpdword_t exchange_key) { + return 0; +} +DECLARE_XAM_EXPORT1(NetDll_XNetUnregisterKey, kNetworking, kStub); + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xsocket.cc b/src/xenia/kernel/xsocket.cc index 080feb163..3e8f754b8 100644 --- a/src/xenia/kernel/xsocket.cc +++ b/src/xenia/kernel/xsocket.cc @@ -73,6 +73,16 @@ X_STATUS XSocket::Close() { return X_STATUS_SUCCESS; } +X_STATUS XSocket::GetOption(uint32_t level, uint32_t optname, void* optval_ptr, + int* optlen) { + int ret = + getsockopt(native_handle_, level, optname, (char*)optval_ptr, optlen); + if (ret < 0) { + // TODO: WSAGetLastError() + return X_STATUS_UNSUCCESSFUL; + } + return X_STATUS_SUCCESS; +} X_STATUS XSocket::SetOption(uint32_t level, uint32_t optname, void* optval_ptr, uint32_t optlen) { if (level == 0xFFFF && (optname == 0x5801 || optname == 0x5802)) { diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index b0b528847..a1e4dd367 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -107,6 +107,8 @@ class XSocket : public XObject { X_STATUS Initialize(AddressFamily af, Type type, Protocol proto); X_STATUS Close(); + X_STATUS GetOption(uint32_t level, uint32_t optname, void* optval_ptr, + int* optlen); X_STATUS SetOption(uint32_t level, uint32_t optname, void* optval_ptr, uint32_t optlen); X_STATUS IOControl(uint32_t cmd, uint8_t* arg_ptr);