summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2026-02-05 20:08:57 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2026-02-15 20:14:15 -0600
commit587c825a9e2a42617142d3814f6d28180d2347aa (patch)
treea857f67f50b576d1aa0fa33da22dc3cb8ca4a48c
parent5f6cd84ad73afd7f54523b633af6d27cc86a9a38 (diff)
AMMediaboard: Clean up and make a function for AMMBCommandAccept.
-rw-r--r--Source/Core/Core/HW/DVD/AMMediaboard.cpp92
1 files changed, 49 insertions, 43 deletions
diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp
index 0d44d13db5..1a13ddddc7 100644
--- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp
+++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp
@@ -485,7 +485,8 @@ static int PlatformPoll(std::span<WSAPOLLFD> pfds, std::chrono::milliseconds tim
static GuestSocket NetDIMMAccept(GuestSocket guest_socket, sockaddr* addr, socklen_t* len)
{
- WSAPOLLFD pfds[1]{{.fd = GetHostSocket(guest_socket), .events = POLLIN}};
+ const auto host_socket = GetHostSocket(guest_socket);
+ WSAPOLLFD pfds[1]{{.fd = host_socket, .events = POLLIN}};
constexpr auto timeout = std::chrono::milliseconds{10};
@@ -493,7 +494,7 @@ static GuestSocket NetDIMMAccept(GuestSocket guest_socket, sockaddr* addr, sockl
if (result > 0 && (pfds[0].revents & POLLIN) != 0)
{
- const auto client_sock = accept_(GetHostSocket(guest_socket), addr, len);
+ const auto client_sock = accept_(host_socket, addr, len);
if (client_sock == INVALID_GUEST_SOCKET)
{
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: accept() failed in NetDIMMAccept ({})",
@@ -756,6 +757,51 @@ static void AMMBCommandConnect(u32 parameter_offset, u32 network_buffer_base)
s_media_buffer_32[1] = ret;
}
+static void AMMBCommandAccept(u32 parameter_offset, u32 network_buffer_base)
+{
+ const auto guest_socket = GuestSocket(s_media_buffer_32[parameter_offset]);
+ const u32 addr_off = s_media_buffer_32[parameter_offset + 1];
+ const u32 addrlen_off = s_media_buffer_32[parameter_offset + 2];
+
+ u32 ret{};
+
+ // Either both parameters should be provided, or neither.
+ if ((addr_off != 0) != (addrlen_off != 0))
+ {
+ WARN_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandAccept: Unexpected parameters: {}, {}, {}",
+ u32(guest_socket), addr_off, addrlen_off);
+
+ // TODO: Not hardware tested.
+ s_last_error = SSC_EFAULT;
+ ret = SOCKET_ERROR;
+ }
+ else
+ {
+ sockaddr addr;
+ socklen_t addrlen = sizeof(addr);
+ ret = u32(NetDIMMAccept(guest_socket, &addr, &addrlen));
+
+ NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: accept( {} ):{}", u32(guest_socket), u32(ret));
+
+ auto* const addrlen_ptr =
+ GetSafePtr(s_network_command_buffer, network_buffer_base, addrlen_off, sizeof(u32));
+ if (addrlen_ptr != nullptr)
+ {
+ // Read the buffer size.
+ addrlen = std::min<socklen_t>(addrlen, Common::BitCastPtr<u32>(addrlen_ptr));
+ // Write out the proper length.
+ Common::BitCastPtr<u32>(addrlen_ptr) = sizeof(addr);
+
+ auto* const addr_ptr =
+ GetSafePtr(s_network_command_buffer, network_buffer_base, addr_off, addrlen);
+ if (addr_ptr != nullptr)
+ memcpy(addr_ptr, &addr, addrlen);
+ }
+ }
+
+ s_media_buffer_32[1] = ret;
+}
+
// Expects a pointer to a GuestFdSet or nullptr.
static void FillPollFdsFromGuestFdSet(std::span<WSAPOLLFD> pfds, const void* guest_fds_ptr,
short requested_events)
@@ -1160,48 +1206,8 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
s_media_buffer[4] = 1;
break;
case AMMBCommand::Accept:
- {
- const auto guest_socket = GuestSocket(s_media_buffer_32[2]);
- GuestSocket ret = INVALID_GUEST_SOCKET;
- sockaddr addr;
- socklen_t len = 0;
-
- // Handle optional parameters
- if (s_media_buffer_32[3] == 0 || s_media_buffer_32[4] == 0)
- {
- ret = NetDIMMAccept(guest_socket, nullptr, nullptr);
- }
- else
- {
- const u32 addr_off = s_media_buffer_32[3] - NetworkCommandAddress2;
- const u32 len_off = s_media_buffer_32[4] - NetworkCommandAddress2;
-
- if (!NetworkCMDBufferCheck(addr_off, sizeof(sockaddr)) ||
- !NetworkCMDBufferCheck(len_off, sizeof(u32)))
- {
- break;
- }
-
- // TODO: Check that the current implementation is correct. Currently, `len=0`,
- // so `accept()` might not write to `addr` properly. It might be missing the
- // following (assuming the code, address and endianness are correct):
- //
- // // socklen_t might be larger than u32
- // const u32 addr_len = Common::BitCastPtr<u32>(s_network_command_buffer + len_off);
- // len = addr_len;
- ret = NetDIMMAccept(guest_socket, &addr, &len);
- if (len)
- {
- memcpy(s_network_command_buffer + addr_off, &addr, sizeof(sockaddr));
- memcpy(s_network_command_buffer + len_off, &len, sizeof(u32));
- }
- }
-
- NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: accept( {}({}) ):{}", u32(guest_socket),
- u32(guest_socket), u32(ret));
- s_media_buffer_32[1] = u32(ret);
+ AMMBCommandAccept(2, NetworkCommandAddress2);
break;
- }
case AMMBCommand::Bind:
{
const auto fd = GetHostSocket(GuestSocket(s_media_buffer_32[2]));