[Kernel] Add Linux socket support and ensure binding low ports is remapped.
Remapping ports on both Linux and Windows to ensure games boot under wine as well.
This commit is contained in:
committed by
Radosław Gliński
parent
344e8538e0
commit
4af2fd6513
@@ -248,38 +248,42 @@ DECLARE_XAM_EXPORT1(NetDll_XNetRandom, kNetworking, kStub);
|
||||
|
||||
dword_result_t NetDll_WSAStartup_entry(dword_t caller, word_t version,
|
||||
pointer_t<X_WSADATA> data_ptr) {
|
||||
// TODO(benvanik): abstraction layer needed.
|
||||
// TODO(benvanik): abstraction layer needed.
|
||||
int ret = 0;
|
||||
|
||||
#ifdef XE_PLATFORM_WIN32
|
||||
WSADATA wsaData;
|
||||
ZeroMemory(&wsaData, sizeof(WSADATA));
|
||||
int ret = WSAStartup(version, &wsaData);
|
||||
|
||||
auto data_out = kernel_state()->memory()->TranslateVirtual(data_ptr);
|
||||
ret = WSAStartup(version, &wsaData);
|
||||
#endif
|
||||
|
||||
if (data_ptr) {
|
||||
auto data_out = kernel_state()->memory()->TranslateVirtual(data_ptr);
|
||||
|
||||
#ifdef XE_PLATFORM_WIN32
|
||||
data_ptr->version = wsaData.wVersion;
|
||||
data_ptr->version_high = wsaData.wHighVersion;
|
||||
std::memcpy(&data_ptr->description, wsaData.szDescription, 0x100);
|
||||
std::memcpy(&data_ptr->system_status, wsaData.szSystemStatus, 0x80);
|
||||
data_ptr->max_sockets = wsaData.iMaxSockets;
|
||||
data_ptr->max_udpdg = wsaData.iMaxUdpDg;
|
||||
std::memcpy(&data_ptr->description, wsaData.szDescription, 0x100);
|
||||
std::memcpy(&data_ptr->system_status, wsaData.szSystemStatus, 0x80);
|
||||
#else
|
||||
// Match Windows behavior with reasonable values
|
||||
data_ptr->version = version.value();
|
||||
data_ptr->version_high = version.value();
|
||||
data_ptr->max_sockets = 100;
|
||||
data_ptr->max_udpdg = 1024;
|
||||
// WinSock 2.2 typically returns empty strings for these fields
|
||||
std::memset(&data_ptr->description, 0, 0x100);
|
||||
std::memset(&data_ptr->system_status, 0, 0x80);
|
||||
#endif
|
||||
|
||||
// Some games (5841099F) want this value round-tripped - they'll compare if
|
||||
// it changes and bugcheck if it does.
|
||||
uint32_t vendor_ptr = xe::load_and_swap<uint32_t>(data_out + 0x190);
|
||||
xe::store_and_swap<uint32_t>(data_out + 0x190, vendor_ptr);
|
||||
// vendor_info_ptr is at offset 0x18A (after max_udpdg at 0x188)
|
||||
uint32_t vendor_ptr = xe::load_and_swap<uint32_t>(data_out + 0x18A);
|
||||
xe::store_and_swap<uint32_t>(data_out + 0x18A, vendor_ptr);
|
||||
}
|
||||
#else
|
||||
int ret = 0;
|
||||
if (data_ptr) {
|
||||
// Guess these values!
|
||||
data_ptr->version = version.value();
|
||||
data_ptr->description[0] = '\0';
|
||||
data_ptr->system_status[0] = '\0';
|
||||
data_ptr->max_sockets = 100;
|
||||
data_ptr->max_udpdg = 1024;
|
||||
}
|
||||
#endif
|
||||
|
||||
// DEBUG
|
||||
/*
|
||||
@@ -659,6 +663,8 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type,
|
||||
socket->Release();
|
||||
|
||||
XThread::SetLastError(socket->GetLastWSAError());
|
||||
XELOGE("NetDll_socket: failed with error {:08X}",
|
||||
socket->GetLastWSAError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -742,6 +748,8 @@ 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(socket->GetLastWSAError());
|
||||
XELOGE("NetDll_ioctlsocket: failed with error {:08X}",
|
||||
socket->GetLastWSAError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -757,6 +765,7 @@ dword_result_t NetDll_bind_entry(dword_t caller, dword_t socket_handle,
|
||||
kernel_state()->object_table()->LookupObject<XSocket>(socket_handle);
|
||||
if (!socket) {
|
||||
XThread::SetLastError(uint32_t(X_WSAError::X_WSAENOTSOCK));
|
||||
XELOGE("NetDll_bind: failed - invalid socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -764,6 +773,7 @@ dword_result_t NetDll_bind_entry(dword_t caller, dword_t socket_handle,
|
||||
X_STATUS status = socket->Bind(&native_name, namelen);
|
||||
if (XFAILED(status)) {
|
||||
XThread::SetLastError(socket->GetLastWSAError());
|
||||
XELOGE("NetDll_bind: failed with status {:08X}", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1027,7 +1037,8 @@ dword_result_t NetDll_sendto_entry(dword_t caller, dword_t socket_handle,
|
||||
}
|
||||
|
||||
N_XSOCKADDR_IN native_to(to_ptr);
|
||||
return socket->SendTo(buf_ptr, buf_len, flags, &native_to, to_len);
|
||||
int ret = socket->SendTo(buf_ptr, buf_len, flags, &native_to, to_len);
|
||||
return ret;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(NetDll_sendto, kNetworking, kImplemented);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user