diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index fdca1f408c..3b2e33e06e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -180,7 +180,7 @@ void Reset(bool hard) { if (!device) continue; - device->Close(0, true); + device->Close(); device.reset(); } @@ -348,12 +348,10 @@ static std::shared_ptr GetUnusedESDevice() } // Returns the FD for the newly opened device (on success) or an error code. -static s32 OpenDevice(const u32 address) +static s32 OpenDevice(const IOSOpenRequest& request) { - const std::string device_name = Memory::GetString(Memory::Read_U32(address + 0xC)); - const u32 open_mode = Memory::Read_U32(address + 0x10); const s32 new_fd = GetFreeDeviceID(); - INFO_LOG(WII_IPC_HLE, "Opening %s (mode %d, fd %d)", device_name.c_str(), open_mode, new_fd); + INFO_LOG(WII_IPC_HLE, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd); if (new_fd < 0 || new_fd >= IPC_MAX_FDS) { ERROR_LOG(WII_IPC_HLE, "Couldn't get a free fd, too many open files"); @@ -361,80 +359,73 @@ static s32 OpenDevice(const u32 address) } std::shared_ptr device; - if (device_name.find("/dev/es") == 0) + if (request.path == "/dev/es") { device = GetUnusedESDevice(); if (!device) return IPC_EESEXHAUSTED; } - else if (device_name.find("/dev/") == 0) + else if (request.path.find("/dev/") == 0) { - device = GetDeviceByName(device_name); + device = GetDeviceByName(request.path); } - else if (device_name.find('/') == 0) + else if (request.path.find('/') == 0) { - device = std::make_shared(new_fd, device_name); + device = std::make_shared(new_fd, request.path); } if (!device) { - ERROR_LOG(WII_IPC_HLE, "Unknown device: %s", device_name.c_str()); + ERROR_LOG(WII_IPC_HLE, "Unknown device: %s", request.path.c_str()); return IPC_ENOENT; } - Memory::Write_U32(new_fd, address + 4); - device->Open(address, open_mode); - const s32 open_return_code = Memory::Read_U32(address + 4); - if (open_return_code < 0) - return open_return_code; + const IOSReturnCode code = device->Open(request); + if (code < IPC_SUCCESS) + return code; s_fdmap[new_fd] = device; return new_fd; } -static IPCCommandResult HandleCommand(const u32 address) +static IPCCommandResult HandleCommand(const IOSRequest& request) { - const auto command = static_cast(Memory::Read_U32(address)); - if (command == IPC_CMD_OPEN) + if (request.command == IPC_CMD_OPEN) { - const s32 new_fd = OpenDevice(address); - Memory::Write_U32(new_fd, address + 4); - return IWII_IPC_HLE_Device::GetDefaultReply(); + IOSOpenRequest open_request{request.address}; + const s32 new_fd = OpenDevice(open_request); + return IWII_IPC_HLE_Device::GetDefaultReply(new_fd); } - const s32 fd = Memory::Read_U32(address + 8); - const auto device = (fd >= 0 && fd < IPC_MAX_FDS) ? s_fdmap[fd] : nullptr; + const auto device = (request.fd < IPC_MAX_FDS) ? s_fdmap[request.fd] : nullptr; if (!device) - { - Memory::Write_U32(IPC_EINVAL, address + 4); - return IWII_IPC_HLE_Device::GetDefaultReply(); - } + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_EINVAL); - switch (command) + switch (request.command) { case IPC_CMD_CLOSE: - s_fdmap[fd].reset(); - // A close on a valid device returns IPC_SUCCESS. - Memory::Write_U32(IPC_SUCCESS, address + 4); - return device->Close(address); + s_fdmap[request.fd].reset(); + device->Close(); + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_SUCCESS); case IPC_CMD_READ: - return device->Read(address); + return device->Read(IOSReadWriteRequest{request.address}); case IPC_CMD_WRITE: - return device->Write(address); + return device->Write(IOSReadWriteRequest{request.address}); case IPC_CMD_SEEK: - return device->Seek(address); + return device->Seek(IOSSeekRequest{request.address}); case IPC_CMD_IOCTL: - return device->IOCtl(address); + return device->IOCtl(IOSIOCtlRequest{request.address}); case IPC_CMD_IOCTLV: - return device->IOCtlV(address); + return device->IOCtlV(IOSIOCtlVRequest{request.address}); default: - _assert_msg_(WII_IPC_HLE, false, "Unexpected command: %x", command); - return IWII_IPC_HLE_Device::GetDefaultReply(); + _assert_msg_(WII_IPC_HLE, false, "Unexpected command: %x", request.command); + return IWII_IPC_HLE_Device::GetDefaultReply(IPC_EINVAL); } } void ExecuteCommand(const u32 address) { - IPCCommandResult result = HandleCommand(address); + IOSRequest request{address}; + IPCCommandResult result = HandleCommand(request); // Ensure replies happen in order const s64 ticks_until_last_reply = s_last_reply_time - CoreTiming::GetTicks(); @@ -443,7 +434,7 @@ void ExecuteCommand(const u32 address) s_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; if (result.send_reply) - EnqueueReply(address, static_cast(result.reply_delay_ticks)); + EnqueueReply(request, result.return_value, static_cast(result.reply_delay_ticks)); } // Happens AS SOON AS IPC gets a new pointer! @@ -453,13 +444,15 @@ void EnqueueRequest(u32 address) } // Called to send a reply to an IOS syscall -void EnqueueReply(u32 address, int cycles_in_future, CoreTiming::FromThread from) +void EnqueueReply(const IOSRequest& request, const s32 return_value, int cycles_in_future, + CoreTiming::FromThread from) { + Memory::Write_U32(static_cast(return_value), request.address + 4); // IOS writes back the command that was responded to in the FD field. - Memory::Write_U32(Memory::Read_U32(address), address + 8); + Memory::Write_U32(request.command, request.address + 8); // IOS also overwrites the command type with the reply type. - Memory::Write_U32(IPC_REPLY, address); - CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, address, from); + Memory::Write_U32(IPC_REPLY, request.address); + CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from); } void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h index c7b5de812c..11e9abb2a1 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h @@ -12,11 +12,13 @@ #include "Core/CoreTiming.h" #include "Core/HW/SystemTimers.h" +struct IOSRequest; class IWII_IPC_HLE_Device; class PointerWrap; struct IPCCommandResult { + s32 return_value; bool send_reply; u64 reply_delay_ticks; }; @@ -69,7 +71,7 @@ void UpdateDevices(); void ExecuteCommand(u32 address); void EnqueueRequest(u32 address); -void EnqueueReply(u32 address, int cycles_in_future = 0, +void EnqueueReply(const IOSRequest& request, s32 return_value, int cycles_in_future = 0, CoreTiming::FromThread from = CoreTiming::FromThread::CPU); void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future = 0); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp index 0a3d9cf9a3..59d0b1191c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp @@ -2,48 +2,119 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Core/IPC_HLE/WII_IPC_HLE.h" +#include +#include + +#include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Core/HW/Memmap.h" #include "Core/HW/SystemTimers.h" +#include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" -SIOCtlVBuffer::SIOCtlVBuffer(const u32 address) : m_Address(address) +IOSRequest::IOSRequest(const u32 address_) : address(address_) { - // These are the Ioctlv parameters in the IOS communication. The BufferVector - // is a memory address offset at where the in and out buffer addresses are - // stored. - Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0 - NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1 - NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2 - BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3 + command = static_cast(Memory::Read_U32(address)); + fd = Memory::Read_U32(address + 8); +} - // The start of the out buffer - u32 BufferVectorOffset = BufferVector; +IOSOpenRequest::IOSOpenRequest(const u32 address_) : IOSRequest(address_) +{ + path = Memory::GetString(Memory::Read_U32(address + 0xc)); + flags = static_cast(Memory::Read_U32(address + 0x10)); +} - // Write the address and size for all in messages - for (u32 i = 0; i < NumberInBuffer; i++) +IOSReadWriteRequest::IOSReadWriteRequest(const u32 address_) : IOSRequest(address_) +{ + buffer = Memory::Read_U32(address + 0xc); + size = Memory::Read_U32(address + 0x10); +} + +IOSSeekRequest::IOSSeekRequest(const u32 address_) : IOSRequest(address_) +{ + offset = Memory::Read_U32(address + 0xc); + mode = static_cast(Memory::Read_U32(address + 0x10)); +} + +IOSIOCtlRequest::IOSIOCtlRequest(const u32 address_) : IOSRequest(address_) +{ + request = Memory::Read_U32(address + 0x0c); + buffer_in = Memory::Read_U32(address + 0x10); + buffer_in_size = Memory::Read_U32(address + 0x14); + buffer_out = Memory::Read_U32(address + 0x18); + buffer_out_size = Memory::Read_U32(address + 0x1c); +} + +IOSIOCtlVRequest::IOSIOCtlVRequest(const u32 address_) : IOSRequest(address_) +{ + request = Memory::Read_U32(address + 0x0c); + const u32 in_number = Memory::Read_U32(address + 0x10); + const u32 out_number = Memory::Read_U32(address + 0x14); + const u32 vectors_base = Memory::Read_U32(address + 0x18); // address to vectors + + u32 offset = 0; + for (size_t i = 0; i < (in_number + out_number); ++i) { - SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - InBuffer.push_back(Buffer); - DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); + IOVector vector; + vector.address = Memory::Read_U32(vectors_base + offset); + vector.size = Memory::Read_U32(vectors_base + offset + 4); + offset += 8; + if (i < in_number) + in_vectors.emplace_back(vector); + else + io_vectors.emplace_back(vector); } +} - // Write the address and size for all out or in-out messages - for (u32 i = 0; i < NumberPayloadBuffer; i++) - { - SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); - BufferVectorOffset += 4; - PayloadBuffer.push_back(Buffer); - DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); - } +bool IOSIOCtlVRequest::HasInputVectorWithAddress(const u32 vector_address) const +{ + return std::any_of(in_vectors.begin(), in_vectors.end(), + [&](const auto& in_vector) { return in_vector.address == vector_address; }); +} + +void IOSIOCtlRequest::Log(const std::string& device_name, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS verbosity) const +{ + GENERIC_LOG(type, verbosity, "%s (fd %u) - IOCtl 0x%x (in_size=0x%x, out_size=0x%x)", + device_name.c_str(), fd, request, buffer_in_size, buffer_out_size); +} + +void IOSIOCtlRequest::Dump(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Log("===== " + description, type, level); + GENERIC_LOG(type, level, "In buffer\n%s", + HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str()); + GENERIC_LOG(type, level, "Out buffer\n%s", + HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); +} + +void IOSIOCtlRequest::DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Dump("Unknown IOCtl - " + description, type, level); +} + +void IOSIOCtlVRequest::Dump(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + GENERIC_LOG(type, level, "===== %s (fd %u) - IOCtlV 0x%x (%zu in, %zu io)", description.c_str(), + fd, request, in_vectors.size(), io_vectors.size()); + + size_t i = 0; + for (const auto& vector : in_vectors) + GENERIC_LOG(type, level, "in[%zu] (size=0x%x):\n%s", i++, vector.size, + HexDump(Memory::GetPointer(vector.address), vector.size).c_str()); + + i = 0; + for (const auto& vector : io_vectors) + GENERIC_LOG(type, level, "io[%zu] (size=0x%x)", i++, vector.size); +} + +void IOSIOCtlVRequest::DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type, + LogTypes::LOG_LEVELS level) const +{ + Dump("Unknown IOCtlV - " + description, type, level); } IWII_IPC_HLE_Device::IWII_IPC_HLE_Device(const u32 device_id, const std::string& device_name, @@ -66,116 +137,37 @@ void IWII_IPC_HLE_Device::DoStateShared(PointerWrap& p) p.Do(m_is_active); } -IPCCommandResult IWII_IPC_HLE_Device::Open(u32 command_address, u32 mode) +IOSReturnCode IWII_IPC_HLE_Device::Open(const IOSOpenRequest& request) { m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult IWII_IPC_HLE_Device::Close(u32 command_address, bool force) +void IWII_IPC_HLE_Device::Close() { m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult IWII_IPC_HLE_Device::Seek(u32 command_address) +IPCCommandResult IWII_IPC_HLE_Device::Unsupported(const IOSRequest& request) { - WARN_LOG(WII_IPC_HLE, "%s does not support Seek()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::Read(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support Read()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::Write(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support Write()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtl(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support IOCtl()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); -} - -IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(u32 command_address) -{ - WARN_LOG(WII_IPC_HLE, "%s does not support IOCtlV()", m_name.c_str()); - Memory::Write_U32(IPC_EINVAL, command_address); - return GetDefaultReply(); + static std::map names = {{{IPC_CMD_READ, "Read"}, + {IPC_CMD_WRITE, "Write"}, + {IPC_CMD_SEEK, "Seek"}, + {IPC_CMD_IOCTL, "IOCtl"}, + {IPC_CMD_IOCTLV, "IOCtlV"}}}; + WARN_LOG(WII_IPC_HLE, "%s does not support %s()", m_name.c_str(), names[request.command].c_str()); + return GetDefaultReply(IPC_EINVAL); } // Returns an IPCCommandResult for a reply that takes 250 us (arbitrarily chosen value) -IPCCommandResult IWII_IPC_HLE_Device::GetDefaultReply() +IPCCommandResult IWII_IPC_HLE_Device::GetDefaultReply(const s32 return_value) { - return {true, SystemTimers::GetTicksPerSecond() / 4000}; + return {return_value, true, SystemTimers::GetTicksPerSecond() / 4000}; } // Returns an IPCCommandResult with no reply. Useful for async commands that will generate a reply -// later +// later. This takes no return value because it won't be used. IPCCommandResult IWII_IPC_HLE_Device::GetNoReply() { - return {false, 0}; -} - -// Write out the IPC struct from command_address to num_commands numbers -// of 4 byte commands. -void IWII_IPC_HLE_Device::DumpCommands(u32 command_address, size_t num_commands, - LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity) -{ - GENERIC_LOG(log_type, verbosity, "CommandDump of %s", GetDeviceName().c_str()); - for (u32 i = 0; i < num_commands; i++) - { - GENERIC_LOG(log_type, verbosity, " Command%02i: 0x%08x", i, - Memory::Read_U32(command_address + i * 4)); - } -} - -void IWII_IPC_HLE_Device::DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer, - LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity) -{ - GENERIC_LOG(log_type, verbosity, "======= DumpAsync ======"); - - u32 BufferOffset = buffer_vector; - for (u32 i = 0; i < number_in_buffer; i++) - { - u32 InBuffer = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - u32 InBufferSize = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - - GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i); - - std::string Temp; - for (u32 j = 0; j < InBufferSize; j++) - { - Temp += StringFromFormat("%02x ", Memory::Read_U8(InBuffer + j)); - } - - GENERIC_LOG(log_type, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str()); - } - - for (u32 i = 0; i < number_io_buffer; i++) - { - u32 OutBuffer = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - u32 OutBufferSize = Memory::Read_U32(BufferOffset); - BufferOffset += 4; - - GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), - i); - GENERIC_LOG(log_type, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer, - OutBufferSize); - - if (verbosity >= LogTypes::LOG_LEVELS::LINFO) - DumpCommands(OutBuffer, OutBufferSize, log_type, verbosity); - } + return {IPC_SUCCESS, false, 0}; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h index 2894ba2bd3..0112163594 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h @@ -11,7 +11,6 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Common/StringUtil.h" #include "Core/IPC_HLE/WII_IPC_HLE.h" enum IOSReturnCode : s32 @@ -41,22 +40,88 @@ enum IOSReturnCode : s32 IPC_EESEXHAUSTED = -1016, // Max of 2 ES handles exceeded }; -// A struct for IOS ioctlv calls -struct SIOCtlVBuffer +struct IOSRequest { - explicit SIOCtlVBuffer(u32 address); + u32 address = 0; + IPCCommandType command = IPC_CMD_OPEN; + u32 fd = 0; + explicit IOSRequest(u32 address); + virtual ~IOSRequest() = default; +}; - const u32 m_Address; - u32 Parameter; - u32 NumberInBuffer; - u32 NumberPayloadBuffer; - u32 BufferVector; - struct SBuffer +enum IOSOpenMode : s32 +{ + IOS_OPEN_READ = 1, + IOS_OPEN_WRITE = 2, + IOS_OPEN_RW = (IOS_OPEN_READ | IOS_OPEN_WRITE) +}; + +struct IOSOpenRequest final : IOSRequest +{ + std::string path; + IOSOpenMode flags = IOS_OPEN_READ; + explicit IOSOpenRequest(u32 address); +}; + +struct IOSReadWriteRequest final : IOSRequest +{ + u32 buffer = 0; + u32 size = 0; + explicit IOSReadWriteRequest(u32 address); +}; + +struct IOSSeekRequest final : IOSRequest +{ + enum SeekMode { - u32 m_Address, m_Size; + IOS_SEEK_SET = 0, + IOS_SEEK_CUR = 1, + IOS_SEEK_END = 2, }; - std::vector InBuffer; - std::vector PayloadBuffer; + u32 offset = 0; + SeekMode mode = IOS_SEEK_SET; + explicit IOSSeekRequest(u32 address); +}; + +struct IOSIOCtlRequest final : IOSRequest +{ + u32 request = 0; + u32 buffer_in = 0; + u32 buffer_in_size = 0; + // Contrary to the name, the output buffer can also be used for input. + u32 buffer_out = 0; + u32 buffer_out_size = 0; + explicit IOSIOCtlRequest(u32 address); + void Log(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LERROR) const; +}; + +struct IOSIOCtlVRequest final : IOSRequest +{ + struct IOVector + { + u32 address = 0; + u32 size = 0; + }; + u32 request = 0; + // In vectors are *mostly* used for input buffers. Sometimes they are also used as + // output buffers (notably in the network code). + // IO vectors are *mostly* used for output buffers. However, as indicated in the name, + // they're also used as input buffers. + // So both of them are technically IO vectors. But we're keeping them separated because + // merging them into a single std::vector would make using the first out vector more complicated. + std::vector in_vectors; + std::vector io_vectors; + explicit IOSIOCtlVRequest(u32 address); + bool HasInputVectorWithAddress(u32 vector_address) const; + void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LINFO) const; + void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE, + LogTypes::LOG_LEVELS level = LogTypes::LERROR) const; }; class IWII_IPC_HLE_Device @@ -79,18 +144,18 @@ public: const std::string& GetDeviceName() const { return m_name; } u32 GetDeviceID() const { return m_device_id; } - virtual IPCCommandResult Open(u32 command_address, u32 mode); - virtual IPCCommandResult Close(u32 command_address, bool force = false); - virtual IPCCommandResult Seek(u32 command_address); - virtual IPCCommandResult Read(u32 command_address); - virtual IPCCommandResult Write(u32 command_address); - virtual IPCCommandResult IOCtl(u32 command_address); - virtual IPCCommandResult IOCtlV(u32 command_address); - + // Replies to Open and Close requests are sent by WII_IPC_HLE, not by the devices themselves. + virtual IOSReturnCode Open(const IOSOpenRequest& request); + virtual void Close(); + virtual IPCCommandResult Seek(const IOSSeekRequest& seek) { return Unsupported(seek); } + virtual IPCCommandResult Read(const IOSReadWriteRequest& read) { return Unsupported(read); } + virtual IPCCommandResult Write(const IOSReadWriteRequest& write) { return Unsupported(write); } + virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& ioctl) { return Unsupported(ioctl); } + virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& ioctlv) { return Unsupported(ioctlv); } virtual void Update() {} virtual DeviceType GetDeviceType() const { return m_device_type; } virtual bool IsOpened() const { return m_is_active; } - static IPCCommandResult GetDefaultReply(); + static IPCCommandResult GetDefaultReply(s32 return_value); static IPCCommandResult GetNoReply(); protected: @@ -100,13 +165,6 @@ protected: DeviceType m_device_type; bool m_is_active = false; - // Write out the IPC struct from command_address to number_of_commands numbers - // of 4 byte commands. - void DumpCommands(u32 command_address, size_t number_of_commands = 8, - LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE, - LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG); - - void DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer, - LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE, - LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG); +private: + IPCCommandResult Unsupported(const IOSRequest& request); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index 9e4276c792..9f207b4b97 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -32,7 +32,7 @@ void CWII_IPC_HLE_Device_di::DoState(PointerWrap& p) p.Do(m_commands_to_execute); } -IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(const IOSIOCtlRequest& request) { // DI IOCtls are handled in a special way by Dolphin // compared to other WII_IPC_HLE functions. @@ -42,40 +42,25 @@ IPCCommandResult CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) // are queued until DVDInterface is ready to handle them. bool ready_to_execute = m_commands_to_execute.empty(); - m_commands_to_execute.push_back(_CommandAddress); + m_commands_to_execute.push_back(request.address); if (ready_to_execute) - StartIOCtl(_CommandAddress); + StartIOCtl(request); // DVDInterface handles the timing and we handle the reply, // so WII_IPC_HLE shouldn't handle anything. return GetNoReply(); } -void CWII_IPC_HLE_Device_di::StartIOCtl(u32 command_address) +void CWII_IPC_HLE_Device_di::StartIOCtl(const IOSIOCtlRequest& request) { - u32 BufferIn = Memory::Read_U32(command_address + 0x10); - u32 BufferInSize = Memory::Read_U32(command_address + 0x14); - u32 BufferOut = Memory::Read_U32(command_address + 0x18); - u32 BufferOutSize = Memory::Read_U32(command_address + 0x1C); - - u32 command_0 = Memory::Read_U32(BufferIn); - u32 command_1 = Memory::Read_U32(BufferIn + 4); - u32 command_2 = Memory::Read_U32(BufferIn + 8); - - DEBUG_LOG(WII_IPC_DVD, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)", - command_0, BufferIn, BufferInSize, BufferOut, BufferOutSize); - - // TATSUNOKO VS CAPCOM: Gets here with BufferOut == 0!!! - if (BufferOut != 0) - { - // Set out buffer to zeroes as a safety precaution - // to avoid answering nonsense values - Memory::Memset(BufferOut, 0, BufferOutSize); - } + const u32 command_0 = Memory::Read_U32(request.buffer_in); + const u32 command_1 = Memory::Read_U32(request.buffer_in + 4); + const u32 command_2 = Memory::Read_U32(request.buffer_in + 8); // DVDInterface's ExecuteCommand handles most of the work. // The IOCtl callback is used to generate a reply afterwards. - DVDInterface::ExecuteCommand(command_0, command_1, command_2, BufferOut, BufferOutSize, true); + DVDInterface::ExecuteCommand(command_0, command_1, command_2, request.buffer_out, + request.buffer_out_size, true); } void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt_type) @@ -89,58 +74,46 @@ void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt // This command has been executed, so it's removed from the queue u32 command_address = m_commands_to_execute.front(); m_commands_to_execute.pop_front(); - - // The DI interrupt type is used as a return value - Memory::Write_U32(interrupt_type, command_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(command_address); + WII_IPC_HLE_Interface::EnqueueReply(IOSIOCtlRequest{command_address}, interrupt_type); // DVDInterface is now ready to execute another command, // so we start executing a command from the queue if there is one if (!m_commands_to_execute.empty()) - StartIOCtl(m_commands_to_execute.front()); + { + IOSIOCtlRequest next_request{m_commands_to_execute.front()}; + StartIOCtl(next_request); + } } -IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - u32 ReturnValue = 0; - switch (CommandBuffer.Parameter) + for (const auto& vector : request.io_vectors) + Memory::Memset(vector.address, 0, vector.size); + s32 return_value = IPC_SUCCESS; + switch (request.request) { case DVDInterface::DVDLowOpenPartition: { - _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, + _dbg_assert_msg_(WII_IPC_DVD, request.in_vectors[1].address == 0, "DVDLowOpenPartition with ticket"); - _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, + _dbg_assert_msg_(WII_IPC_DVD, request.in_vectors[2].address == 0, "DVDLowOpenPartition with cert chain"); - u64 const partition_offset = - ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2); + u64 const partition_offset = ((u64)Memory::Read_U32(request.in_vectors[0].address + 4) << 2); DVDInterface::ChangePartition(partition_offset); INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset); // Read TMD to the buffer std::vector tmd_buffer = DVDInterface::GetVolume().GetTMD(); - Memory::CopyToEmu(CommandBuffer.PayloadBuffer[0].m_Address, tmd_buffer.data(), - tmd_buffer.size()); + Memory::CopyToEmu(request.io_vectors[0].address, tmd_buffer.data(), tmd_buffer.size()); WII_IPC_HLE_Interface::ES_DIVerify(tmd_buffer); - ReturnValue = 1; - } - break; - - default: - ERROR_LOG(WII_IPC_DVD, "IOCtlV: %i", CommandBuffer.Parameter); - _dbg_assert_msg_(WII_IPC_DVD, 0, "IOCtlV: %i", CommandBuffer.Parameter); + return_value = 1; break; } - - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - return GetDefaultReply(); + default: + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_DVD); + } + return GetDefaultReply(return_value); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h index f7af22998b..2e72c59c68 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_DI.h @@ -27,13 +27,13 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void FinishIOCtl(DVDInterface::DIInterruptType interrupt_type); private: - void StartIOCtl(u32 command_address); + void StartIOCtl(const IOSIOCtlRequest& request); std::deque m_commands_to_execute; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 8cd1f853a4..bf76810a96 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include @@ -70,11 +71,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 device_id, { } -CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO() -{ -} - -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_FileIO::Close() { INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_name.c_str(), m_device_id); m_Mode = 0; @@ -84,12 +81,11 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bF m_file.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_FileIO::Open(const IOSOpenRequest& request) { - m_Mode = mode; + m_Mode = request.flags; static const char* const Modes[] = {"Unk Mode", "Read only", "Write only", "Read and Write"}; @@ -97,21 +93,18 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 command_address, u32 mode) // The file must exist before we can open it // It should be created by ISFS_CreateFile, not here - if (File::Exists(m_filepath) && !File::IsDirectory(m_filepath)) + if (!File::Exists(m_filepath) || File::IsDirectory(m_filepath)) { - INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[mode], mode); - OpenFile(); - } - else - { - WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[mode], + WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[m_Mode], m_filepath.c_str()); - if (command_address) - Memory::Write_U32(FS_ENOENT, command_address + 4); + return FS_ENOENT; } + INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[m_Mode], m_Mode); + OpenFile(); + m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } // This isn't theadsafe, but it's only called from the CPU thread. @@ -158,98 +151,90 @@ void CWII_IPC_HLE_Device_FileIO::OpenFile() } } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(const IOSSeekRequest& request) { - u32 ReturnValue = FS_EINVAL; - const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); - const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10); + u32 return_value = FS_EINVAL; if (m_file->IsOpen()) { - ReturnValue = FS_EINVAL; - - const s32 fileSize = (s32)m_file->GetSize(); + const u32 file_size = static_cast(m_file->GetSize()); DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)", - SeekPosition, Mode, m_name.c_str(), fileSize); + request.offset, request.mode, m_name.c_str(), file_size); - switch (Mode) + switch (request.mode) { - case WII_SEEK_SET: + case IOSSeekRequest::IOS_SEEK_SET: { - if ((SeekPosition >= 0) && (SeekPosition <= fileSize)) + if (request.offset <= file_size) { - m_SeekPos = SeekPosition; - ReturnValue = m_SeekPos; + m_SeekPos = request.offset; + return_value = m_SeekPos; } break; } - case WII_SEEK_CUR: + case IOSSeekRequest::IOS_SEEK_CUR: { - s32 wantedPos = SeekPosition + m_SeekPos; - if (wantedPos >= 0 && wantedPos <= fileSize) + const u32 wanted_pos = request.offset + m_SeekPos; + if (wanted_pos <= file_size) { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; + m_SeekPos = wanted_pos; + return_value = m_SeekPos; } break; } - case WII_SEEK_END: + case IOSSeekRequest::IOS_SEEK_END: { - s32 wantedPos = SeekPosition + fileSize; - if (wantedPos >= 0 && wantedPos <= fileSize) + const u32 wanted_pos = request.offset + file_size; + if (wanted_pos <= file_size) { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; + m_SeekPos = wanted_pos; + return_value = m_SeekPos; } break; } default: { - PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); - ReturnValue = FS_EINVAL; + PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", request.mode); + return_value = FS_EINVAL; break; } } } else { - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(const IOSReadWriteRequest& request) { - u32 ReturnValue = FS_EACCESS; - const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address - const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - + s32 return_value = FS_EACCESS; if (m_file->IsOpen()) { - if (m_Mode == ISFS_OPEN_WRITE) + if (m_Mode == IOS_OPEN_WRITE) { WARN_LOG(WII_IPC_FILEIO, - "FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s", Size, - Address, m_name.c_str()); + "FileIO: Attempted to read 0x%x bytes to 0x%08x on a write-only file %s", + request.size, request.buffer, m_name.c_str()); } else { - DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, - m_name.c_str()); + DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", request.size, + request.buffer, m_name.c_str()); m_file->Seek(m_SeekPos, SEEK_SET); // File might be opened twice, need to seek before we read - ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file->GetHandle()); - if (ReturnValue != Size && ferror(m_file->GetHandle())) + return_value = static_cast( + fread(Memory::GetPointer(request.buffer), 1, request.size, m_file->GetHandle())); + if (static_cast(return_value) != request.size && ferror(m_file->GetHandle())) { - ReturnValue = FS_EACCESS; + return_value = FS_EACCESS; } else { - m_SeekPos += Size; + m_SeekPos += request.size; } } } @@ -257,39 +242,34 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) { ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could " "not be opened or does not exist", - m_name.c_str(), Address, Size); - ReturnValue = FS_ENOENT; + m_name.c_str(), request.buffer, request.size); + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(const IOSReadWriteRequest& request) { - u32 ReturnValue = FS_EACCESS; - const u32 Address = - Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address - const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - + s32 return_value = FS_EACCESS; if (m_file->IsOpen()) { - if (m_Mode == ISFS_OPEN_READ) + if (m_Mode == IOS_OPEN_READ) { WARN_LOG(WII_IPC_FILEIO, - "FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s", Size, - Address, m_name.c_str()); + "FileIO: Attempted to write 0x%x bytes from 0x%08x to a read-only file %s", + request.size, request.buffer, m_name.c_str()); } else { - DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, - m_name.c_str()); + DEBUG_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", request.size, + request.buffer, m_name.c_str()); m_file->Seek(m_SeekPos, SEEK_SET); // File might be opened twice, need to seek before we write - if (m_file->WriteBytes(Memory::GetPointer(Address), Size)) + if (m_file->WriteBytes(Memory::GetPointer(request.buffer), request.size)) { - ReturnValue = Size; - m_SeekPos += Size; + return_value = request.size; + m_SeekPos += request.size; } } } @@ -297,55 +277,41 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) { ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file could " "not be opened or does not exist", - m_name.c_str(), Address, Size); - ReturnValue = FS_ENOENT; + m_name.c_str(), request.buffer, request.size); + return_value = FS_ENOENT; } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(const IOSIOCtlRequest& request) { DEBUG_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_name.c_str()); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpCommands(_CommandAddress); -#endif - const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 ReturnValue = 0; + s32 return_value = IPC_SUCCESS; - switch (Parameter) + switch (request.request) { case ISFS_IOCTL_GETFILESTATS: { if (m_file->IsOpen()) { - u32 m_FileLength = (u32)m_file->GetSize(); - - const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - DEBUG_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_name.c_str(), m_FileLength, - m_SeekPos); - - Memory::Write_U32(m_FileLength, BufferOut); - Memory::Write_U32(m_SeekPos, BufferOut + 4); + DEBUG_LOG(WII_IPC_FILEIO, "File: %s, Length: %" PRIu64 ", Pos: %i", m_name.c_str(), + m_file->GetSize(), m_SeekPos); + Memory::Write_U32(static_cast(m_file->GetSize()), request.buffer_out); + Memory::Write_U32(m_SeekPos, request.buffer_out + 4); } else { - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; } } break; default: - { - PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter); - } - break; + request.Log(GetDeviceName(), LogTypes::WII_IPC_FILEIO, LogTypes::LERROR); } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(return_value); } void CWII_IPC_HLE_Device_FileIO::PrepareForState(PointerWrap::Mode mode) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index 3d49acc04b..84cd6d5a66 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -26,34 +26,18 @@ class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_FileIO(); - - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Seek(u32 _CommandAddress) override; - IPCCommandResult Read(u32 _CommandAddress) override; - IPCCommandResult Write(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + void Close() override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult Seek(const IOSSeekRequest& request) override; + IPCCommandResult Read(const IOSReadWriteRequest& request) override; + IPCCommandResult Write(const IOSReadWriteRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; void PrepareForState(PointerWrap::Mode mode) override; void DoState(PointerWrap& p) override; void OpenFile(); private: - enum - { - ISFS_OPEN_READ = 1, - ISFS_OPEN_WRITE = 2, - ISFS_OPEN_RW = (ISFS_OPEN_READ | ISFS_OPEN_WRITE) - }; - - enum - { - WII_SEEK_SET = 0, - WII_SEEK_CUR = 1, - WII_SEEK_END = 2, - }; - enum { ISFS_FUNCNULL = 0, diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index dd20bbdb7d..3a8bfde24f 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -97,10 +97,6 @@ u8* CWII_IPC_HLE_Device_es::keyTable[11] = { key_empty, // Unknown }; -CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es() -{ -} - void CWII_IPC_HLE_Device_es::LoadWAD(const std::string& _rContentFile) { m_ContentFile = _rContentFile; @@ -195,17 +191,16 @@ void CWII_IPC_HLE_Device_es::DoState(PointerWrap& p) } } -IPCCommandResult CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_es::Open(const IOSOpenRequest& request) { OpenInternal(); if (m_is_active) INFO_LOG(WII_IPC_ES, "Device was re-opened."); - m_is_active = true; - return GetDefaultReply(); + return IWII_IPC_HLE_Device::Open(request); } -IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_es::Close() { m_ContentAccessMap.clear(); m_TitleIDs.clear(); @@ -216,7 +211,6 @@ IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce m_is_active = false; // clear the NAND content cache to make sure nothing remains open. DiscIO::CNANDContentManager::Access().ClearCache(); - return GetDefaultReply(); } u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index) @@ -248,54 +242,43 @@ u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index) return CFD; } -IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer Buffer(_CommandAddress); - - DEBUG_LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), Buffer.Parameter); - - // Prepare the out buffer(s) with zeroes as a safety precaution - // to avoid returning bad values - for (const auto& buffer : Buffer.PayloadBuffer) + DEBUG_LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), request.request); + // Clear the IO buffers. Note that this is unsafe for other ioctlvs. + for (const auto& io_vector : request.io_vectors) { - // Don't zero an out buffer which is also one of the in buffers. - if (std::any_of(Buffer.InBuffer.begin(), Buffer.InBuffer.end(), - [&](const auto& in_buffer) { return in_buffer.m_Address == buffer.m_Address; })) - { - continue; - } - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); + if (!request.HasInputVectorWithAddress(io_vector.address)) + Memory::Memset(io_vector.address, 0, io_vector.size); } - - switch (Buffer.Parameter) + switch (request.request) { case IOCTL_ES_ADDTICKET: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 3, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 3, "IOCTL_ES_ADDTICKET wrong number of inputs"); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDTICKET"); - std::vector ticket(Buffer.InBuffer[0].m_Size); - Memory::CopyFromEmu(ticket.data(), Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size); + std::vector ticket(request.in_vectors[0].size); + Memory::CopyFromEmu(ticket.data(), request.in_vectors[0].address, request.in_vectors[0].size); DiscIO::AddTicket(ticket); break; } case IOCTL_ES_ADDTITLESTART: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 4, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 4, "IOCTL_ES_ADDTITLESTART wrong number of inputs"); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDTITLESTART"); - std::vector tmd(Buffer.InBuffer[0].m_Size); - Memory::CopyFromEmu(tmd.data(), Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size); + std::vector tmd(request.in_vectors[0].size); + Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size); m_addtitle_tmd.SetBytes(tmd); if (!m_addtitle_tmd.IsValid()) { ERROR_LOG(WII_IPC_ES, "Invalid TMD while adding title (size = %zd)", tmd.size()); - Memory::Write_U32(ES_INVALID_TMD, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(ES_INVALID_TMD); } // Write the TMD to title storage. @@ -310,18 +293,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_ADDCONTENTSTART: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_ADDCONTENTSTART wrong number of inputs"); - u64 title_id = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 content_id = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 title_id = Memory::Read_U64(request.in_vectors[0].address); + u32 content_id = Memory::Read_U32(request.in_vectors[1].address); if (m_addtitle_content_id != 0xFFFFFFFF) { ERROR_LOG(WII_IPC_ES, "Trying to add content when we haven't finished adding " "another content. Unsupported."); - Memory::Write_U32(ES_WRITE_FAILURE, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(ES_WRITE_FAILURE); } m_addtitle_content_id = content_id; @@ -343,40 +325,38 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // no known content installer which performs content addition concurrently. // Instead we just log an error (see above) if this condition is detected. s32 content_fd = 0; - Memory::Write_U32(content_fd, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(content_fd); } case IOCTL_ES_ADDCONTENTDATA: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_ADDCONTENTDATA wrong number of inputs"); - u32 content_fd = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 content_fd = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDCONTENTDATA: content fd %08x, " "size %d", - content_fd, Buffer.InBuffer[1].m_Size); + content_fd, request.in_vectors[1].size); - u8* data_start = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* data_end = data_start + Buffer.InBuffer[1].m_Size; + u8* data_start = Memory::GetPointer(request.in_vectors[1].address); + u8* data_end = data_start + request.in_vectors[1].size; m_addtitle_content_buffer.insert(m_addtitle_content_buffer.end(), data_start, data_end); break; } case IOCTL_ES_ADDCONTENTFINISH: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_ADDCONTENTFINISH wrong number of inputs"); - u32 content_fd = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 content_fd = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_ADDCONTENTFINISH: content fd %08x", content_fd); // Try to find the title key from a pre-installed ticket. std::vector ticket = DiscIO::FindSignedTicket(m_addtitle_tmd.GetTitleId()); if (ticket.size() == 0) { - Memory::Write_U32(ES_NO_TICKET_INSTALLED, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(ES_NO_TICKET_INSTALLED); } mbedtls_aes_context aes_ctx; @@ -387,8 +367,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDReader::Content content_info; if (!m_addtitle_tmd.FindContentById(m_addtitle_content_id, &content_info)) { - Memory::Write_U32(ES_INVALID_TMD, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(ES_INVALID_TMD); } u8 iv[16] = {0}; iv[0] = (content_info.index >> 8) & 0xFF; @@ -417,126 +396,122 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETDEVICEID: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, - "IOCTL_ES_GETDEVICEID no out buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, + "IOCTL_ES_GETDEVICEID no io vectors"); EcWii& ec = EcWii::GetInstance(); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID %08X", ec.getNgId()); - Memory::Write_U32(ec.getNgId(), Buffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); + Memory::Write_U32(ec.getNgId(), request.io_vectors[0].address); + return GetDefaultReply(IPC_SUCCESS); } - break; case IOCTL_ES_GETTITLECONTENTSCNT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); u16 NumberOfPrivateContent = 0; + s32 return_value = IPC_SUCCESS; if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check { NumberOfPrivateContent = rNANDContent.GetNumEntries(); if ((u32)(TitleID >> 32) == 0x00010000) - Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(0, request.io_vectors[0].address); else - Memory::Write_U32(NumberOfPrivateContent, Buffer.PayloadBuffer[0].m_Address); - - Memory::Write_U32(0, _CommandAddress + 0x4); + Memory::Write_U32(NumberOfPrivateContent, request.io_vectors[0].address); } else - Memory::Write_U32((u32)rNANDContent.GetContentSize(), _CommandAddress + 0x4); + { + return_value = static_cast(rNANDContent.GetContentSize()); + } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i", (u32)(TitleID >> 32), (u32)TitleID, rNANDContent.IsValid() ? NumberOfPrivateContent : (u32)rNANDContent.GetContentSize()); - return GetDefaultReply(); + return GetDefaultReply(return_value); } break; case IOCTL_ES_GETTITLECONTENTS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETTITLECONTENTS bad in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLECONTENTS bad out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); + s32 return_value = IPC_SUCCESS; if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check { for (u16 i = 0; i < rNANDContent.GetNumEntries(); i++) { Memory::Write_U32(rNANDContent.GetContentByIndex(i)->m_ContentID, - Buffer.PayloadBuffer[0].m_Address + i * 4); + request.io_vectors[0].address + i * 4); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index %d: %08x", i, rNANDContent.GetContentByIndex(i)->m_ContentID); } - Memory::Write_U32(0, _CommandAddress + 0x4); } else { - Memory::Write_U32((u32)rNANDContent.GetContentSize(), _CommandAddress + 0x4); + return_value = static_cast(rNANDContent.GetContentSize()); ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Unable to open content %zu", rNANDContent.GetContentSize()); } - return GetDefaultReply(); + return GetDefaultReply(return_value); } break; case IOCTL_ES_OPENTITLECONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 3); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 3); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 Index = Memory::Read_U32(Buffer.InBuffer[2].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 Index = Memory::Read_U32(request.in_vectors[2].address); - u32 CFD = OpenTitleContent(m_AccessIdentID++, TitleID, Index); - Memory::Write_U32(CFD, _CommandAddress + 0x4); + s32 CFD = OpenTitleContent(m_AccessIdentID++, TitleID, Index); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID >> 32), (u32)TitleID, Index, CFD); - return GetDefaultReply(); + return GetDefaultReply(CFD); } break; case IOCTL_ES_OPENCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); - u32 Index = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); + u32 Index = Memory::Read_U32(request.in_vectors[0].address); - u32 CFD = OpenTitleContent(m_AccessIdentID++, m_TitleID, Index); - Memory::Write_U32(CFD, _CommandAddress + 0x4); + s32 CFD = OpenTitleContent(m_AccessIdentID++, m_TitleID, Index); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD); - return GetDefaultReply(); + return GetDefaultReply(CFD); } break; case IOCTL_ES_READCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u32 Size = Buffer.PayloadBuffer[0].m_Size; - u32 Addr = Buffer.PayloadBuffer[0].m_Address; + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); + u32 Size = request.io_vectors[0].size; + u32 Addr = request.io_vectors[0].address; auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(-1); } SContentAccess& rContent = itr->second; @@ -573,25 +548,23 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) "IOCTL_ES_READCONTENT: CFD %x, Address 0x%x, Size %i -> stream pos %i (Index %i)", CFD, Addr, Size, rContent.m_Position, rContent.m_Index); - Memory::Write_U32(Size, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(Size); } break; case IOCTL_ES_CLOSECONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_CLOSECONTENT: CFD %x", CFD); auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(-1); } const DiscIO::CNANDContentLoader& ContentLoader = AccessContentDevice(itr->second.m_TitleID); @@ -604,25 +577,23 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) m_ContentAccessMap.erase(itr); - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_SEEKCONTENT: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 3); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 3); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 0); - u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u32 Addr = Memory::Read_U32(Buffer.InBuffer[1].m_Address); - u32 Mode = Memory::Read_U32(Buffer.InBuffer[2].m_Address); + u32 CFD = Memory::Read_U32(request.in_vectors[0].address); + u32 Addr = Memory::Read_U32(request.in_vectors[1].address); + u32 Mode = Memory::Read_U32(request.in_vectors[2].address); auto itr = m_ContentAccessMap.find(CFD); if (itr == m_ContentAccessMap.end()) { - Memory::Write_U32(-1, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(-1); } SContentAccess& rContent = itr->second; @@ -644,19 +615,18 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) DEBUG_LOG(WII_IPC_ES, "IOCTL_ES_SEEKCONTENT: CFD %x, Address 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position); - Memory::Write_U32(rContent.m_Position, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(rContent.m_Position); } break; case IOCTL_ES_GETTITLEDIR: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 1); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); - char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + char* Path = (char*)Memory::GetPointer(request.io_vectors[0].address); sprintf(Path, "/title/%08x/%08x/data", (u32)(TitleID >> 32), (u32)TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEDIR: %s", Path); @@ -665,56 +635,55 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETTITLEID: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 0); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 0); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLEID no out buffer"); - Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U64(m_TitleID, request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEID: %08x/%08x", (u32)(m_TitleID >> 32), (u32)m_TitleID); } break; case IOCTL_ES_SETUID: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_SETUID no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_SETUID no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 0, "IOCTL_ES_SETUID has a payload, it shouldn't"); // TODO: fs permissions based on this - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); } break; case IOCTL_ES_GETTITLECNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 0, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 0, "IOCTL_ES_GETTITLECNT has an in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLECNT has no out buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.PayloadBuffer[0].m_Size == 4, + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors[0].size == 4, "IOCTL_ES_GETTITLECNT payload[0].size != 4"); - Memory::Write_U32((u32)m_TitleIDs.size(), Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32((u32)m_TitleIDs.size(), request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECNT: Number of Titles %zu", m_TitleIDs.size()); - Memory::Write_U32(0, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETTITLES: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETTITLES has an in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETTITLES has an in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLES has no out buffer"); - u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[0].m_Address); + u32 MaxCount = Memory::Read_U32(request.in_vectors[0].address); u32 Count = 0; for (int i = 0; i < (int)m_TitleIDs.size(); i++) { - Memory::Write_U64(m_TitleIDs[i], Buffer.PayloadBuffer[0].m_Address + i * 8); + Memory::Write_U64(m_TitleIDs[i], request.io_vectors[0].address + i * 8); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: %08x/%08x", (u32)(m_TitleIDs[i] >> 32), (u32)m_TitleIDs[i]); Count++; @@ -723,18 +692,18 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count); - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETVIEWCNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u32 retVal = 0; const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -774,20 +743,18 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWCNT for titleID: %08x/%08x (View Count = %i)", (u32)(TitleID >> 32), (u32)TitleID, ViewCount); - Memory::Write_U32(ViewCount, Buffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(retVal, _CommandAddress + 0x4); - return GetDefaultReply(); + Memory::Write_U32(ViewCount, request.io_vectors[0].address); + return GetDefaultReply(retVal); } break; case IOCTL_ES_GETVIEWS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETVIEWS no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, - "IOCTL_ES_GETVIEWS no out buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETVIEWS no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWS no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 maxViews = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 maxViews = Memory::Read_U32(request.in_vectors[1].address); u32 retVal = 0; const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -808,9 +775,9 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) pFile.ReadBytes(FileTicket, DiscIO::CNANDContentLoader::TICKET_SIZE); ++View) { - Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8); - Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, - FileTicket + 0x1D0, 212); + Memory::Write_U32(View, request.io_vectors[0].address + View * 0xD8); + Memory::CopyToEmu(request.io_vectors[0].address + 4 + View * 0xD8, FileTicket + 0x1D0, + 212); } } } @@ -820,7 +787,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // SDK or libogc, just passed to LaunchTitle, so this // shouldn't matter at all. Just fill out some fields just // to be on the safe side. - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::Memset(Address, 0, 0xD8); Memory::Write_U64(TitleID, Address + 4 + (0x1dc - 0x1d0)); // title ID Memory::Write_U16(0xffff, Address + 4 + (0x1e4 - 0x1d0)); // unnnown @@ -840,8 +807,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) static_cast(Loader.GetTicket().size()) / DiscIO::CNANDContentLoader::TICKET_SIZE; for (unsigned int view = 0; view != maxViews && view < view_count; ++view) { - Memory::Write_U32(view, Buffer.PayloadBuffer[0].m_Address + view * 0xD8); - Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + view * 0xD8, + Memory::Write_U32(view, request.io_vectors[0].address + view * 0xD8); + Memory::CopyToEmu(request.io_vectors[0].address + 4 + view * 0xD8, &ticket[0x1D0 + (view * DiscIO::CNANDContentLoader::TICKET_SIZE)], 212); } } @@ -849,18 +816,18 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWS for titleID: %08x/%08x (MaxViews = %i)", (u32)(TitleID >> 32), (u32)TitleID, maxViews); - Memory::Write_U32(retVal, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(retVal); } break; case IOCTL_ES_GETTMDVIEWCNT: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETTMDVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, + "IOCTL_ES_GETTMDVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -873,24 +840,23 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDViewCnt += (u32)Loader.GetContentSize() * (4 + 2 + 2 + 8); // content id, index, type, size } - Memory::Write_U32(TMDViewCnt, Buffer.PayloadBuffer[0].m_Address); - - Memory::Write_U32(0, _CommandAddress + 0x4); + Memory::Write_U32(TMDViewCnt, request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETTMDVIEWS: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETTMDVIEWCNT no in buffer"); - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 2, + "IOCTL_ES_GETTMDVIEWCNT no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); @@ -899,7 +865,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) if (Loader.IsValid()) { - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::CopyToEmu(Address, Loader.GetTMDView(), DiscIO::CNANDContentLoader::TMD_VIEW_SIZE); Address += DiscIO::CNANDContentLoader::TMD_VIEW_SIZE; @@ -923,62 +889,50 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } _dbg_assert_(WII_IPC_ES, - (Address - Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size); + (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - Memory::Write_U32(0, _CommandAddress + 0x4); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETCONSUMPTION: // This is at least what crediar's ES module does - Memory::Write_U32(0, Buffer.PayloadBuffer[1].m_Address); - Memory::Write_U32(0, _CommandAddress + 0x4); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION:%d", Memory::Read_U32(_CommandAddress + 4)); - return GetDefaultReply(); + Memory::Write_U32(0, request.io_vectors[1].address); + INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION"); + return GetDefaultReply(IPC_SUCCESS); case IOCTL_ES_DELETETICKET: { - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETICKET: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); - if (File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) - { - Memory::Write_U32(0, _CommandAddress + 0x4); - } - else - { - // Presumably return -1017 when delete fails - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); - } + // Presumably return -1017 when delete fails + if (!File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); + return GetDefaultReply(IPC_SUCCESS); } - break; + case IOCTL_ES_DELETETITLECONTENT: { - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); - if (DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) - { - Memory::Write_U32(0, _CommandAddress + 0x4); - } - else - { - // Presumably return -1017 when title not installed TODO verify - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); - } + // Presumably return -1017 when title not installed TODO verify + if (!DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); + return GetDefaultReply(IPC_SUCCESS); } - break; + case IOCTL_ES_GETSTOREDTMDSIZE: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() == 1, "IOCTL_ES_GETSTOREDTMDSIZE no in buffer"); - // _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE + // _dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE // no out buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); _dbg_assert_(WII_IPC_ES, Loader.IsValid()); @@ -988,40 +942,39 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) TMDCnt += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE; TMDCnt += (u32)Loader.GetContentSize() * DiscIO::CNANDContentLoader::CONTENT_HEADER_SIZE; } - if (Buffer.NumberPayloadBuffer) - Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address); - - Memory::Write_U32(0, _CommandAddress + 0x4); + if (request.io_vectors.size()) + Memory::Write_U32(TMDCnt, request.io_vectors[0].address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_GETSTOREDTMD: { - _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer > 0, "IOCTL_ES_GETSTOREDTMD no in buffer"); + _dbg_assert_msg_(WII_IPC_ES, request.in_vectors.size() > 0, + "IOCTL_ES_GETSTOREDTMD no in buffer"); // requires 1 inbuffer and no outbuffer, presumably outbuffer required when second inbuffer is // used for maxcount (allocated mem?) // called with 1 inbuffer after deleting a titleid - //_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETSTOREDTMD no out + //_dbg_assert_msg_(WII_IPC_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETSTOREDTMD no out // buffer"); - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u32 MaxCount = 0; - if (Buffer.NumberInBuffer > 1) + if (request.in_vectors.size() > 1) { // TODO: actually use this param in when writing to the outbuffer :/ - MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); + MaxCount = Memory::Read_U32(request.in_vectors[1].address); } const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffer size: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - if (Loader.IsValid() && Buffer.NumberPayloadBuffer) + if (Loader.IsValid() && request.io_vectors.size()) { - u32 Address = Buffer.PayloadBuffer[0].m_Address; + u32 Address = request.io_vectors[0].address; Memory::CopyToEmu(Address, Loader.GetTMDHeader(), DiscIO::CNANDContentLoader::TMD_HEADER_SIZE); @@ -1036,24 +989,23 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) } _dbg_assert_(WII_IPC_ES, - (Address - Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size); + (Address - request.io_vectors[0].address) == request.io_vectors[0].size); } - Memory::Write_U32(0, _CommandAddress + 0x4); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } break; case IOCTL_ES_ENCRYPT: { - u32 keyIndex = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u8* IV = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* source = Memory::GetPointer(Buffer.InBuffer[2].m_Address); - u32 size = Buffer.InBuffer[2].m_Size; - u8* newIV = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); + u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address); + u8* IV = Memory::GetPointer(request.in_vectors[1].address); + u8* source = Memory::GetPointer(request.in_vectors[2].address); + u32 size = request.in_vectors[2].size; + u8* newIV = Memory::GetPointer(request.io_vectors[0].address); + u8* destination = Memory::GetPointer(request.io_vectors[1].address); mbedtls_aes_context AES_ctx; mbedtls_aes_setkey_enc(&AES_ctx, keyTable[keyIndex], 128); @@ -1067,12 +1019,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_DECRYPT: { - u32 keyIndex = Memory::Read_U32(Buffer.InBuffer[0].m_Address); - u8* IV = Memory::GetPointer(Buffer.InBuffer[1].m_Address); - u8* source = Memory::GetPointer(Buffer.InBuffer[2].m_Address); - u32 size = Buffer.InBuffer[2].m_Size; - u8* newIV = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); + u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address); + u8* IV = Memory::GetPointer(request.in_vectors[1].address); + u8* source = Memory::GetPointer(request.in_vectors[2].address); + u32 size = request.in_vectors[2].size; + u8* newIV = Memory::GetPointer(request.io_vectors[0].address); + u8* destination = Memory::GetPointer(request.io_vectors[1].address); DecryptContent(keyIndex, IV, source, size, newIV, destination); @@ -1083,17 +1035,17 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_LAUNCH: { - _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2); + _dbg_assert_(WII_IPC_ES, request.in_vectors.size() == 2); bool bSuccess = false; bool bReset = false; u16 IOSv = 0xffff; - u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - u32 view = Memory::Read_U32(Buffer.InBuffer[1].m_Address); - u64 ticketid = Memory::Read_U64(Buffer.InBuffer[1].m_Address + 4); - u32 devicetype = Memory::Read_U32(Buffer.InBuffer[1].m_Address + 12); - u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address + 16); - u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address + 24); + u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); + u32 view = Memory::Read_U32(request.in_vectors[1].address); + u64 ticketid = Memory::Read_U64(request.in_vectors[1].address + 4); + u32 devicetype = Memory::Read_U32(request.in_vectors[1].address + 12); + u64 titleid = Memory::Read_U64(request.in_vectors[1].address + 16); + u16 access = Memory::Read_U16(request.in_vectors[1].address + 24); // ES_LAUNCH should probably reset thw whole state, which at least means closing all open files. // leaving them open through ES_LAUNCH may cause hangs and other funky behavior @@ -1194,13 +1146,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) Memory::Write_U16(0xFFFF, 0x00003142); Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188); - // TODO: provide correct return code when bSuccess= false // Note: If we just reset the PPC, don't write anything to the command buffer. This // could clobber the DOL we just loaded. - if (!bReset) - { - Memory::Write_U32(0, _CommandAddress + 0x4); - } ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x", @@ -1213,14 +1160,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) if (!bReset) { // The command type is overwritten with the reply type. - Memory::Write_U32(IPC_REPLY, _CommandAddress); + Memory::Write_U32(IPC_REPLY, request.address); // IOS also writes back the command that was responded to in the FD field. - Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8); + Memory::Write_U32(IPC_CMD_IOCTLV, request.address + 8); } // Generate a "reply" to the IPC command. ES_LAUNCH is unique because it // involves restarting IOS; IOS generates two acknowledgements in a row. - WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(_CommandAddress, 0); + WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(request.address, 0); return GetNoReply(); } break; @@ -1231,14 +1178,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // -1017 // if the IOS didn't find the Korean keys and 0 if it does. 0 leads to a error 003 INFO_LOG(WII_IPC_ES, "IOCTL_ES_CHECKKOREAREGION: Title checked for Korean keys."); - Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); case IOCTL_ES_GETDEVICECERT: // (Input: none, Output: 384 bytes) { INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICECERT"); - _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); - u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + _dbg_assert_(WII_IPC_ES, request.io_vectors.size() == 1); + u8* destination = Memory::GetPointer(request.io_vectors[0].address); EcWii& ec = EcWii::GetInstance(); get_ng_cert(destination, ec.getNgId(), ec.getNgKeyId(), ec.getNgPriv(), ec.getNgSig()); @@ -1248,10 +1194,10 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_SIGN: { INFO_LOG(WII_IPC_ES, "IOCTL_ES_SIGN"); - u8* ap_cert_out = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); - u8* data = Memory::GetPointer(Buffer.InBuffer[0].m_Address); - u32 data_size = Buffer.InBuffer[0].m_Size; - u8* sig_out = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); + u8* ap_cert_out = Memory::GetPointer(request.io_vectors[1].address); + u8* data = Memory::GetPointer(request.in_vectors[0].address); + u32 data_size = request.in_vectors[0].size; + u8* sig_out = Memory::GetPointer(request.io_vectors[0].address); EcWii& ec = EcWii::GetInstance(); get_ap_sig_and_cert(sig_out, ap_cert_out, m_TitleID, data, data_size, ec.getNgPriv(), @@ -1264,7 +1210,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETBOOT2VERSION"); Memory::Write_U32( - 4, Buffer.PayloadBuffer[0].m_Address); // as of 26/02/2012, this was latest bootmii version + 4, request.io_vectors[0].address); // as of 26/02/2012, this was latest bootmii version } break; @@ -1277,20 +1223,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) case IOCTL_ES_GETOWNEDTITLECNT: INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETOWNEDTITLECNT"); - Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address); + Memory::Write_U32(0, request.io_vectors[0].address); break; default: - INFO_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter); - DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_ES); - INFO_LOG(WII_IPC_ES, "command.Parameter: 0x%08x", Buffer.Parameter); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE); } - // Write return value (0 means OK) - Memory::Write_U32(0, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } const DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 title_id) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h index 9ca52d821e..9f4afe4c91 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -27,8 +27,6 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_es(); - void LoadWAD(const std::string& _rContentFile); // Internal implementation of the ES_DECRYPT ioctlv. @@ -38,10 +36,9 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; static u32 ES_DIVerify(const std::vector& tmd); @@ -116,7 +113,7 @@ private: ES_INVALID_TMD = -106, // or access denied ES_READ_LESS_DATA_THAN_EXPECTED = -1009, ES_WRITE_FAILURE = -1010, - ES_PARAMTER_SIZE_OR_ALIGNMENT = -1017, + ES_PARAMETER_SIZE_OR_ALIGNMENT = -1017, ES_HASH_DOESNT_MATCH = -1022, ES_MEM_ALLOC_FAILED = -1024, ES_INCORRECT_ACCESS_RIGHT = -1026, diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index fa9d4ed332..66397e9edb 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -32,18 +32,14 @@ CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& { } -CWII_IPC_HLE_Device_fs::~CWII_IPC_HLE_Device_fs() -{ -} - // ~1/1000th of a second is too short and causes hangs in Wii Party // Play it safe at 1/500th -IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply() const +IPCCommandResult CWII_IPC_HLE_Device_fs::GetFSReply(const s32 return_value) const { - return {true, SystemTimers::GetTicksPerSecond() / 500}; + return {return_value, true, SystemTimers::GetTicksPerSecond() / 500}; } -IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_fs::Open(const IOSOpenRequest& request) { // clear tmp folder { @@ -53,7 +49,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) } m_is_active = true; - return GetFSReply(); + return IPC_SUCCESS; } // Get total filesize of contents of a directory (recursive) @@ -71,27 +67,20 @@ static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry) return sizeOfFiles; } -IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(const IOSIOCtlVRequest& request) { - u32 ReturnValue = IPC_SUCCESS; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - switch (CommandBuffer.Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTLV_READ_DIR: { const std::string relative_path = - Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); + Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); if (!IsValidWiiPath(relative_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relative_path.c_str()); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } @@ -103,7 +92,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) if (!File::Exists(DirName)) { WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str()); - ReturnValue = FS_ENOENT; + return_value = FS_ENOENT; break; } else if (!File::IsDirectory(DirName)) @@ -112,19 +101,19 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) // Games don't usually seem to care WHICH error they get, as long as it's < // Well the system menu CARES! WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_EINVAL"); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } File::FSTEntry entry = File::ScanDirectoryTree(DirName, false); // it is one - if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1)) + if ((request.in_vectors.size() == 1) && (request.io_vectors.size() == 1)) { size_t numFile = entry.children.size(); INFO_LOG(WII_IPC_FILEIO, "\t%zu files found", numFile); - Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address); + Memory::Write_U32((u32)numFile, request.io_vectors[0].address); } else { @@ -140,13 +129,12 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) return one.virtualName < two.virtualName; }); - u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address); + u32 MaxEntries = Memory::Read_U32(request.in_vectors[0].address); - memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, - CommandBuffer.PayloadBuffer[0].m_Size); + memset(Memory::GetPointer(request.io_vectors[0].address), 0, request.io_vectors[0].size); size_t numFiles = 0; - char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address)); + char* pFilename = (char*)Memory::GetPointer((u32)(request.io_vectors[0].address)); for (size_t i = 0; i < entry.children.size() && i < MaxEntries; i++) { @@ -160,29 +148,29 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str()); } - Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address); + Memory::Write_U32((u32)numFiles, request.io_vectors[1].address); } - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; } break; case IOCTLV_GETUSAGE: { - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2); - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4); - _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors.size() == 2); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors[0].size == 4); + _dbg_assert_(WII_IPC_FILEIO, request.io_vectors[1].size == 4); // this command sucks because it asks of the number of used // fsBlocks and inodes // It should be correct, but don't count on it... std::string relativepath = - Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); + Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); if (!IsValidWiiPath(relativepath)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", relativepath.c_str()); - ReturnValue = FS_EINVAL; + return_value = FS_EINVAL; break; } @@ -214,7 +202,7 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb } - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes); } @@ -222,54 +210,37 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) { fsBlocks = 0; iNodes = 0; - ReturnValue = IPC_SUCCESS; + return_value = IPC_SUCCESS; WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directory: %s", path.c_str()); } - Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address); - Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address); + Memory::Write_U32(fsBlocks, request.io_vectors[0].address); + Memory::Write_U32(iNodes, request.io_vectors[1].address); } break; default: - PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO); break; } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - - return GetFSReply(); + return GetFSReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtl(const IOSIOCtlRequest& request) { - // u32 DeviceID = Memory::Read_U32(_CommandAddress + 8); - - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - /* Prepare the out buffer(s) with zeroes as a safety precaution - to avoid returning bad values. */ - // LOG(WII_IPC_FILEIO, "Cleared %u bytes of the out buffer", _BufferOutSize); - Memory::Memset(BufferOut, 0, BufferOutSize); - - u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - - return GetFSReply(); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + const s32 return_value = ExecuteCommand(request); + return GetFSReply(return_value); } -s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, - u32 _BufferOut, u32 _BufferOutSize) +s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(const IOSIOCtlRequest& request) { - switch (_Parameter) + switch (request.request) { case IOCTL_GET_STATS: { - if (_BufferOutSize < 0x1c) + if (request.buffer_out_size < 0x1c) return -1017; WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now"); @@ -285,7 +256,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B fs.Free_INodes = 0x146B; fs.Used_Inodes = 0x0394; - std::memcpy(Memory::GetPointer(_BufferOut), &fs, sizeof(NANDStat)); + std::memcpy(Memory::GetPointer(request.buffer_out), &fs, sizeof(NANDStat)); return IPC_SUCCESS; } @@ -293,8 +264,8 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_CREATE_DIR: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); - u32 Addr = _BufferIn; + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; @@ -325,7 +296,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_SET_ATTR: { - u32 Addr = _BufferIn; + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; @@ -362,14 +333,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_GET_ATTR: { - _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, + _dbg_assert_msg_(WII_IPC_FILEIO, request.buffer_out_size == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", - _BufferOutSize); + request.buffer_out_size); u32 OwnerID = 0; u16 GroupID = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08 // (0x3038) for MH3 etc - const std::string wii_path = Memory::GetString(_BufferIn, 64); + const std::string wii_path = Memory::GetString(request.buffer_in, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -400,14 +371,14 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B } // write answer to buffer - if (_BufferOutSize == 76) + if (request.buffer_out_size == 76) { - u32 Addr = _BufferOut; + u32 Addr = request.buffer_out; Memory::Write_U32(OwnerID, Addr); Addr += 4; Memory::Write_U16(GroupID, Addr); Addr += 2; - memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64); + memcpy(Memory::GetPointer(Addr), Memory::GetPointer(request.buffer_in), 64); Addr += 64; Memory::Write_U8(OwnerPerm, Addr); Addr += 1; @@ -425,10 +396,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_DELETE_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); int Offset = 0; - const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -455,10 +426,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_RENAME_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); int Offset = 0; - const std::string wii_path = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path.c_str()); @@ -467,7 +438,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B std::string Filename = HLE_IPC_BuildFilename(wii_path); Offset += 64; - const std::string wii_path_rename = Memory::GetString(_BufferIn + Offset, 64); + const std::string wii_path_rename = Memory::GetString(request.buffer_in + Offset, 64); if (!IsValidWiiPath(wii_path_rename)) { WARN_LOG(WII_IPC_FILEIO, "Not a valid path: %s", wii_path_rename.c_str()); @@ -503,9 +474,9 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case IOCTL_CREATE_FILE: { - _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); + _dbg_assert_(WII_IPC_FILEIO, request.buffer_out_size == 0); - u32 Addr = _BufferIn; + u32 Addr = request.buffer_in; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); @@ -563,9 +534,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B } break; default: - ERROR_LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); - PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_FILEIO); } return FS_EINVAL; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h index 50feefa92f..5dd540033e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.h @@ -27,14 +27,12 @@ class CWII_IPC_HLE_Device_fs : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_fs(); void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum @@ -51,7 +49,6 @@ private: IOCTL_SHUTDOWN = 0x0D }; - IPCCommandResult GetFSReply() const; - s32 ExecuteCommand(u32 Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, - u32 _BufferOutSize); + IPCCommandResult GetFSReply(s32 return_value) const; + s32 ExecuteCommand(const IOSIOCtlRequest& request); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index ffb1d08103..6945583f24 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -37,12 +37,9 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) std::lock_guard lk(hid->m_device_list_reply_mutex); if (hid->deviceCommandAddress != 0) { - hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), - Memory::Read_U32(hid->deviceCommandAddress + 0x1C)); - - // Return value - Memory::Write_U32(0, hid->deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(hid->deviceCommandAddress, 0, + IOSIOCtlRequest request{hid->deviceCommandAddress}; + hid->FillOutDevices(request); + WII_IPC_HLE_Interface::EnqueueReply(request, IPC_SUCCESS, 0, CoreTiming::FromThread::NON_CPU); hid->deviceCommandAddress = 0; } @@ -56,16 +53,15 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer* transfer) { - int ret = IPC_EINVAL; + s32 ret = IPC_EINVAL; u32 replyAddress = (u32)(size_t)transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { ret = transfer->length; } - // Return value - Memory::Write_U32(ret, replyAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(replyAddress, 0, CoreTiming::FromThread::NON_CPU); + IOSIOCtlRequest request{replyAddress}; + WII_IPC_HLE_Interface::EnqueueReply(request, ret, 0, CoreTiming::FromThread::NON_CPU); } CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) @@ -105,53 +101,36 @@ CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() libusb_exit(nullptr); } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(IPC_EACCES); } - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_HID_GET_ATTACHED: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - deviceCommandAddress = _CommandAddress; + deviceCommandAddress = request.address; return GetNoReply(); } case IOCTL_HID_OPEN: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - // hid version, apparently - ReturnValue = 0x40001; + return_value = 0x40001; break; } case IOCTL_HID_SET_SUSPEND: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); // not actually implemented in IOS - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CANCEL_INTERRUPT: { - DEBUG_LOG(WII_IPC_HID, - "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CONTROL: @@ -161,15 +140,15 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) -4 Can't find device specified */ - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u8 bmRequestType = Memory::Read_U8(BufferIn + 0x14); - u8 bRequest = Memory::Read_U8(BufferIn + 0x15); - u16 wValue = Memory::Read_U16(BufferIn + 0x16); - u16 wIndex = Memory::Read_U16(BufferIn + 0x18); - u16 wLength = Memory::Read_U16(BufferIn + 0x1A); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u8 bmRequestType = Memory::Read_U8(request.buffer_in + 0x14); + u8 bRequest = Memory::Read_U8(request.buffer_in + 0x15); + u16 wValue = Memory::Read_U16(request.buffer_in + 0x16); + u16 wIndex = Memory::Read_U16(request.buffer_in + 0x18); + u16 wLength = Memory::Read_U16(request.buffer_in + 0x1A); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -185,12 +164,14 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength); Memory::CopyFromEmu(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates, - (void*)(size_t)_CommandAddress, /* no timeout */ 0); + (void*)(size_t)request.address, /* no timeout */ 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: + // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), + // request.buffer_out: // (%08x, %i)", - // bmRequestType, bRequest, BufferIn, BufferInSize, BufferOut, BufferOutSize); + // bmRequestType, bRequest, BufferIn, request.buffer_in_size, request.buffer_out, + // request.buffer_out_size); // It's the async way! return GetNoReply(); @@ -198,13 +179,13 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u32 endpoint = Memory::Read_U32(BufferIn + 0x14); - u32 length = Memory::Read_U32(BufferIn + 0x18); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u32 endpoint = Memory::Read_U32(request.buffer_in + 0x14); + u32 length = Memory::Read_U32(request.buffer_in + 0x18); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -217,14 +198,9 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) struct libusb_transfer* transfer = libusb_alloc_transfer(0); transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, Memory::GetPointer(data), length, - handleUsbUpdates, (void*)(size_t)_CommandAddress, 0); + handleUsbUpdates, (void*)(size_t)request.address, 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) (BufferIn: (%08x, %i), BufferOut: - // (%08x, %i)", - // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, - // BufferIn, BufferInSize, BufferOut, BufferOutSize); - // It's the async way! return GetNoReply(); } @@ -233,28 +209,21 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) std::lock_guard lk(m_device_list_reply_mutex); if (deviceCommandAddress != 0) { - Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18)); - - // Return value - Memory::Write_U32(-1, deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(deviceCommandAddress); + IOSIOCtlRequest pending_request{deviceCommandAddress}; + Memory::Write_U32(0xFFFFFFFF, pending_request.buffer_out); + WII_IPC_HLE_Interface::EnqueueReply(pending_request, -1); deviceCommandAddress = 0; } INFO_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); break; } default: - { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; - } + request.Log(GetDeviceName(), LogTypes::WII_IPC_HID); } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - - return GetDefaultReply(); + return GetDefaultReply(return_value); } bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev) @@ -283,26 +252,11 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev) return true; } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(const IOSIOCtlVRequest& request) { Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); - u32 ReturnValue = 0; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - INFO_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - CommandBuffer.NumberPayloadBuffer); -#endif - - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - return GetDefaultReply(); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HID); + return GetDefaultReply(IPC_SUCCESS); } void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest, @@ -344,10 +298,10 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor* des dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } -void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +void CWII_IPC_HLE_Device_hid::FillOutDevices(const IOSIOCtlRequest& request) { static u16 check = 1; - int OffsetBuffer = BufferOut; + int OffsetBuffer = request.buffer_out; int OffsetStart = 0; // int OffsetDevice = 0; int d, c, ic, i, e; /* config, interface container, interface, endpoint */ diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h index 8a8d3ddb04..f88a42f4d0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -38,8 +38,8 @@ public: virtual ~CWII_IPC_HLE_Device_hid(); - IPCCommandResult IOCtlV(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum @@ -115,7 +115,7 @@ private: }; u32 deviceCommandAddress; - void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + void FillOutDevices(const IOSIOCtlRequest& request); int GetAvailableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check); bool ClaimDevice(libusb_device_handle* dev); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 3eae1d40e4..337afc2ac4 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -72,21 +72,15 @@ CWII_IPC_HLE_Device_net_kd_request::~CWII_IPC_HLE_Device_net_kd_request() WiiSockMan::GetInstance().Clean(); } -IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(const IOSIOCtlRequest& request) { - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Parameter) + s32 return_value = 0; + switch (request.request) { case IOCTL_NWC24_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib from NWC24SuspendScheduler (Input: none, Output: 32 bytes) INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI"); - Memory::Write_U32(0, BufferOut); // no error + Memory::Write_U32(0, request.buffer_out); // no error break; case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR: // NWC24iResumeForCloseLib @@ -95,18 +89,17 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) case IOCTL_NWC24_EXEC_RESUME_SCHEDULAR: // NWC24iResumeForCloseLib INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULAR - NI"); - Memory::Write_U32(0, BufferOut); // no error + Memory::Write_U32(0, request.buffer_out); // no error break; case IOCTL_NWC24_STARTUP_SOCKET: // NWC24iStartupSocket - Memory::Write_U32(0, BufferOut); - Memory::Write_U32(0, BufferOut + 4); - ReturnValue = 0; + Memory::Write_U32(0, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); + return_value = 0; INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI"); break; case IOCTL_NWC24_CLEANUP_SOCKET: - Memory::Memset(BufferOut, 0, BufferOutSize); INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_CLEANUP_SOCKET - NI"); break; @@ -120,8 +113,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) case IOCTL_NWC24_REQUEST_REGISTER_USER_ID: INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID"); - Memory::Write_U32(0, BufferOut); - Memory::Write_U32(0, BufferOut + 4); + Memory::Write_U32(0, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); break; case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes) @@ -161,23 +154,23 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) config.SetCreationStage(NWC24::NWC24Config::NWC24_IDCS_GENERATED); config.WriteConfig(); - Memory::Write_U32(ret, BufferOut); + Memory::Write_U32(ret, request.buffer_out); } else { - Memory::Write_U32(NWC24::WC24_ERR_FATAL, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_FATAL, request.buffer_out); } } else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_GENERATED) { - Memory::Write_U32(NWC24::WC24_ERR_ID_GENERATED, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out); } else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_REGISTERED) { - Memory::Write_U32(NWC24::WC24_ERR_ID_REGISTERED, BufferOut); + Memory::Write_U32(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out); } - Memory::Write_U64(config.Id(), BufferOut + 4); - Memory::Write_U32(config.CreationStage(), BufferOut + 0xC); + Memory::Write_U64(config.Id(), request.buffer_out + 4); + Memory::Write_U32(config.CreationStage(), request.buffer_out + 0xC); break; case IOCTL_NWC24_GET_SCHEDULAR_STAT: @@ -194,14 +187,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) break; default: - INFO_LOG(WII_IPC_WC24, - "/dev/net/kd/request::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } u8 CWII_IPC_HLE_Device_net_kd_request::GetAreaCode(const std::string& area) const @@ -337,52 +326,49 @@ CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage() { } -IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(const IOSIOCtlVRequest& request) { - u32 return_value = 0; + s32 return_value = IPC_SUCCESS; u32 common_result = 0; u32 common_vector = 0; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_NCD_LOCKWIRELESSDRIVER: break; case IOCTLV_NCD_UNLOCKWIRELESSDRIVER: - // Memory::Read_U32(CommandBuffer.InBuffer.at(0).m_Address); + // Memory::Read_U32(request.in_vectors.at(0).address); break; case IOCTLV_NCD_GETCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG"); - config.WriteToMem(CommandBuffer.PayloadBuffer.at(0).m_Address); + config.WriteToMem(request.io_vectors.at(0).address); common_vector = 1; break; case IOCTLV_NCD_SETCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_SETCONFIG"); - config.ReadFromMem(CommandBuffer.InBuffer.at(0).m_Address); + config.ReadFromMem(request.in_vectors.at(0).address); break; case IOCTLV_NCD_READCONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_READCONFIG"); config.ReadConfig(); - config.WriteToMem(CommandBuffer.PayloadBuffer.at(0).m_Address); + config.WriteToMem(request.io_vectors.at(0).address); common_vector = 1; break; case IOCTLV_NCD_WRITECONFIG: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_WRITECONFIG"); - config.ReadFromMem(CommandBuffer.InBuffer.at(0).m_Address); + config.ReadFromMem(request.in_vectors.at(0).address); config.WriteConfig(); break; case IOCTLV_NCD_GETLINKSTATUS: INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETLINKSTATUS"); // Always connected - Memory::Write_U32(Net::ConnectionSettings::LINK_WIRED, - CommandBuffer.PayloadBuffer.at(0).m_Address + 4); + Memory::Write_U32(Net::ConnectionSettings::LINK_WIRED, request.io_vectors.at(0).address + 4); break; case IOCTLV_NCD_GETWIRELESSMACADDRESS: @@ -390,21 +376,20 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress) u8 address[MAC_ADDRESS_SIZE]; GetMacAddress(address); - Memory::CopyToEmu(CommandBuffer.PayloadBuffer.at(1).m_Address, address, sizeof(address)); + Memory::CopyToEmu(request.io_vectors.at(1).address, address, sizeof(address)); break; default: - INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", CommandBuffer.Parameter); + INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %#x", request.request); break; } - Memory::Write_U32(common_result, CommandBuffer.PayloadBuffer.at(common_vector).m_Address); + Memory::Write_U32(common_result, request.io_vectors.at(common_vector).address); if (common_vector == 1) { - Memory::Write_U32(common_result, CommandBuffer.PayloadBuffer.at(common_vector).m_Address + 4); + Memory::Write_U32(common_result, request.io_vectors.at(common_vector).address + 4); } - Memory::Write_U32(return_value, _CommandAddress + 4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } // ********************************************************************************** @@ -422,21 +407,19 @@ CWII_IPC_HLE_Device_net_wd_command::~CWII_IPC_HLE_Device_net_wd_command() // This is just for debugging / playing around. // There really is no reason to implement wd unless we can bend it such that // we can talk to the DS. -IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(const IOSIOCtlVRequest& request) { - u32 return_value = 0; + s32 return_value = IPC_SUCCESS; - SIOCtlVBuffer CommandBuffer(CommandAddress); - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_WD_SCAN: { // Gives parameters detailing type of scan and what to match // XXX - unused - // ScanInfo *scan = (ScanInfo *)Memory::GetPointer(CommandBuffer.InBuffer.at(0).m_Address); + // ScanInfo *scan = (ScanInfo *)Memory::GetPointer(request.in_vectors.at(0).m_Address); - u16* results = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer.at(0).m_Address); + u16* results = (u16*)Memory::GetPointer(request.io_vectors.at(0).address); // first u16 indicates number of BSSInfo following results[0] = Common::swap16(1); @@ -459,7 +442,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) case IOCTLV_WD_GET_INFO: { - Info* info = (Info*)Memory::GetPointer(CommandBuffer.PayloadBuffer.at(0).m_Address); + Info* info = (Info*)Memory::GetPointer(request.io_vectors.at(0).address); memset(info, 0, sizeof(Info)); // Probably used to disallow certain channels? memcpy(info->country, "US", 2); @@ -488,28 +471,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_wd_command::IOCtlV(u32 CommandAddress) case IOCTLV_WD_RECV_FRAME: case IOCTLV_WD_RECV_NOTIFICATION: default: - INFO_LOG(WII_IPC_NET, "NET_WD_COMMAND IOCtlV %#x in %i out %i", CommandBuffer.Parameter, - CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); - for (u32 i = 0; i < CommandBuffer.NumberInBuffer; ++i) - { - DEBUG_LOG(WII_IPC_NET, "in %i addr %x size %i", i, CommandBuffer.InBuffer.at(i).m_Address, - CommandBuffer.InBuffer.at(i).m_Size); - DEBUG_LOG(WII_IPC_NET, "%s", - ArrayToString(Memory::GetPointer(CommandBuffer.InBuffer.at(i).m_Address), - CommandBuffer.InBuffer.at(i).m_Size) - .c_str()); - } - for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; ++i) - { - DEBUG_LOG(WII_IPC_NET, "out %i addr %x size %i", i, - CommandBuffer.PayloadBuffer.at(i).m_Address, - CommandBuffer.PayloadBuffer.at(i).m_Size); - } - break; + request.Dump(GetDeviceName(), LogTypes::WII_IPC_NET, LogTypes::LINFO); } - Memory::Write_U32(return_value, CommandAddress + 4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } // ********************************************************************************** @@ -581,61 +546,53 @@ static unsigned int opt_level_mapping[][2] = {{SOL_SOCKET, 0xFFFF}}; static unsigned int opt_name_mapping[][2] = { {SO_REUSEADDR, 0x4}, {SO_SNDBUF, 0x1001}, {SO_RCVBUF, 0x1002}, {SO_ERROR, 0x1009}}; -IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 4); - return GetDefaultReply(); + return GetDefaultReply(IPC_EACCES); } - u32 Command = Memory::Read_U32(_CommandAddress + 0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Command) + s32 return_value = 0; + switch (request.request) { case IOCTL_SO_STARTUP: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_STARTUP " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); break; } case IOCTL_SO_SOCKET: { - u32 af = Memory::Read_U32(BufferIn); - u32 type = Memory::Read_U32(BufferIn + 0x04); - u32 prot = Memory::Read_U32(BufferIn + 0x08); + u32 af = Memory::Read_U32(request.buffer_in); + u32 type = Memory::Read_U32(request.buffer_in + 4); + u32 prot = Memory::Read_U32(request.buffer_in + 8); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.NewSocket(af, type, prot); + return_value = sm.NewSocket(af, type, prot); INFO_LOG(WII_IPC_NET, "IOCTL_SO_SOCKET " "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, af, type, prot, BufferIn, BufferInSize, BufferOut, BufferOutSize); + return_value, af, type, prot, request.buffer_in, request.buffer_in_size, + request.buffer_out, request.buffer_out_size); break; } case IOCTL_SO_ICMPSOCKET: { - u32 pf = Memory::Read_U32(BufferIn); + u32 pf = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, ReturnValue); + return_value = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP); + INFO_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, return_value); break; } case IOCTL_SO_CLOSE: case IOCTL_SO_ICMPCLOSE: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - ReturnValue = sm.DeleteSocket(fd); + return_value = sm.DeleteSocket(fd); INFO_LOG(WII_IPC_NET, "%s(%x) %x", - Command == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd, - ReturnValue); + request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd, + return_value); break; } case IOCTL_SO_ACCEPT: @@ -643,9 +600,9 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_CONNECT: case IOCTL_SO_FCNTL: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, _CommandAddress, (NET_IOCTL)Command); + sm.DoSock(fd, request, static_cast(request.request)); return GetNoReply(); } ///////////////////////////////////////////////////////////// @@ -653,36 +610,30 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) ///////////////////////////////////////////////////////////// case IOCTL_SO_SHUTDOWN: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_SHUTDOWN " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); - u32 fd = Memory::Read_U32(BufferIn); - u32 how = Memory::Read_U32(BufferIn + 4); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 how = Memory::Read_U32(request.buffer_in + 4); int ret = shutdown(fd, how); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false); break; } case IOCTL_SO_LISTEN: { - u32 fd = Memory::Read_U32(BufferIn); - u32 BACKLOG = Memory::Read_U32(BufferIn + 0x04); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04); u32 ret = listen(fd, BACKLOG); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_LISTEN = %d " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); break; } case IOCTL_SO_GETSOCKOPT: { - u32 fd = Memory::Read_U32(BufferOut); - u32 level = Memory::Read_U32(BufferOut + 4); - u32 optname = Memory::Read_U32(BufferOut + 8); + u32 fd = Memory::Read_U32(request.buffer_out); + u32 level = Memory::Read_U32(request.buffer_out + 4); + u32 optname = Memory::Read_U32(request.buffer_out + 8); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKOPT(%08x, %08x, %08x)" - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - fd, level, optname, BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); // Do the level/optname translation int nat_level = -1, nat_optname = -1; @@ -699,45 +650,46 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) u32 optlen = 4; int ret = getsockopt(fd, nat_level, nat_optname, (char*)&optval, (socklen_t*)&optlen); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); - Memory::Write_U32(optlen, BufferOut + 0xC); - Memory::CopyToEmu(BufferOut + 0x10, optval, optlen); + Memory::Write_U32(optlen, request.buffer_out + 0xC); + Memory::CopyToEmu(request.buffer_out + 0x10, optval, optlen); if (optname == SO_ERROR) { s32 last_error = WiiSockMan::GetInstance().GetLastNetError(); - Memory::Write_U32(sizeof(s32), BufferOut + 0xC); - Memory::Write_U32(last_error, BufferOut + 0x10); + Memory::Write_U32(sizeof(s32), request.buffer_out + 0xC); + Memory::Write_U32(last_error, request.buffer_out + 0x10); } break; } case IOCTL_SO_SETSOCKOPT: { - u32 fd = Memory::Read_U32(BufferIn); - u32 level = Memory::Read_U32(BufferIn + 4); - u32 optname = Memory::Read_U32(BufferIn + 8); - u32 optlen = Memory::Read_U32(BufferIn + 0xc); + u32 fd = Memory::Read_U32(request.buffer_in); + u32 level = Memory::Read_U32(request.buffer_in + 4); + u32 optname = Memory::Read_U32(request.buffer_in + 8); + u32 optlen = Memory::Read_U32(request.buffer_in + 0xc); u8 optval[20]; optlen = std::min(optlen, (u32)sizeof(optval)); - Memory::CopyFromEmu(optval, BufferIn + 0x10, optlen); + Memory::CopyFromEmu(optval, request.buffer_in + 0x10, optlen); INFO_LOG(WII_IPC_NET, "IOCTL_SO_SETSOCKOPT(%08x, %08x, %08x, %08x) " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)" "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx", - fd, level, optname, optlen, BufferIn, BufferInSize, BufferOut, BufferOutSize, - optval[0], optval[1], optval[2], optval[3], optval[4], optval[5], optval[6], optval[7], - optval[8], optval[9], optval[10], optval[11], optval[12], optval[13], optval[14], - optval[15], optval[16], optval[17], optval[18], optval[19]); + fd, level, optname, optlen, request.buffer_in, request.buffer_in_size, + request.buffer_out, request.buffer_out_size, optval[0], optval[1], optval[2], + optval[3], optval[4], optval[5], optval[6], optval[7], optval[8], optval[9], + optval[10], optval[11], optval[12], optval[13], optval[14], optval[15], optval[16], + optval[17], optval[18], optval[19]); // TODO: bug booto about this, 0x2005 most likely timeout related, default value on Wii is , // 0x2001 is most likely tcpnodelay if (level == 6 && (optname == 0x2005 || optname == 0x2001)) { - ReturnValue = 0; + return_value = 0; break; } @@ -762,38 +714,36 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) } int ret = setsockopt(fd, nat_level, nat_optname, (char*)optval, optlen); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false); + return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false); break; } case IOCTL_SO_GETSOCKNAME: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKNAME " - "Socket: %08X, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - fd, BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); sockaddr sa; socklen_t sa_len; sa_len = sizeof(sa); int ret = getsockname(fd, &sa, &sa_len); - if (BufferOutSize < 2 + sizeof(sa.sa_data)) + if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating"); - if (BufferOutSize > 0) - Memory::Write_U8(BufferOutSize, BufferOut); - if (BufferOutSize > 1) - Memory::Write_U8(sa.sa_family & 0xFF, BufferOut + 1); - if (BufferOutSize > 2) - Memory::CopyToEmu(BufferOut + 2, &sa.sa_data, - std::min(sizeof(sa.sa_data), BufferOutSize - 2)); - ReturnValue = ret; + if (request.buffer_out_size > 0) + Memory::Write_U8(request.buffer_out_size, request.buffer_out); + if (request.buffer_out_size > 1) + Memory::Write_U8(sa.sa_family & 0xFF, request.buffer_out + 1); + if (request.buffer_out_size > 2) + Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, + std::min(sizeof(sa.sa_data), request.buffer_out_size - 2)); + return_value = ret; break; } case IOCTL_SO_GETPEERNAME: { - u32 fd = Memory::Read_U32(BufferIn); + u32 fd = Memory::Read_U32(request.buffer_in); sockaddr sa; socklen_t sa_len; @@ -801,28 +751,26 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) int ret = getpeername(fd, &sa, &sa_len); - if (BufferOutSize < 2 + sizeof(sa.sa_data)) + if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(WII_IPC_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating"); - if (BufferOutSize > 0) - Memory::Write_U8(BufferOutSize, BufferOut); - if (BufferOutSize > 1) - Memory::Write_U8(AF_INET, BufferOut + 1); - if (BufferOutSize > 2) - Memory::CopyToEmu(BufferOut + 2, &sa.sa_data, - std::min(sizeof(sa.sa_data), BufferOutSize - 2)); + if (request.buffer_out_size > 0) + Memory::Write_U8(request.buffer_out_size, request.buffer_out); + if (request.buffer_out_size > 1) + Memory::Write_U8(AF_INET, request.buffer_out + 1); + if (request.buffer_out_size > 2) + Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, + std::min(sizeof(sa.sa_data), request.buffer_out_size - 2)); INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETPEERNAME(%x)", fd); - ReturnValue = ret; + return_value = ret; break; } case IOCTL_SO_GETHOSTID: { - INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTID " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.Log(GetDeviceName(), LogTypes::WII_IPC_WC24); #ifdef _WIN32 DWORD forwardTableSize, ipTableSize, result; @@ -869,7 +817,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) { if (ipTable->table[i].dwIndex == ifIndex) { - ReturnValue = Common::swap32(ipTable->table[i].dwAddr); + return_value = Common::swap32(ipTable->table[i].dwAddr); break; } } @@ -877,14 +825,14 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) #endif // default placeholder, in case of failure - if (ReturnValue == 0) - ReturnValue = 192 << 24 | 168 << 16 | 1 << 8 | 150; + if (return_value == 0) + return_value = 192 << 24 | 168 << 16 | 1 << 8 | 150; break; } case IOCTL_SO_INETATON: { - std::string hostname = Memory::GetString(BufferIn); + std::string hostname = Memory::GetString(request.buffer_in); struct hostent* remoteHost = gethostbyname(hostname.c_str()); if (remoteHost == nullptr || remoteHost->h_addr_list == nullptr || @@ -892,42 +840,43 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) { INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = -1 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: None", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); - ReturnValue = 0; + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); + return_value = 0; } else { - Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), BufferOut); + Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), request.buffer_out); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = 0 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize, - Common::swap32(*(u32*)remoteHost->h_addr_list[0])); - ReturnValue = 1; + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size, Common::swap32(*(u32*)remoteHost->h_addr_list[0])); + return_value = 1; } break; } case IOCTL_SO_INETPTON: { - std::string address = Memory::GetString(BufferIn); + std::string address = Memory::GetString(request.buffer_in); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETPTON " "(Translating: %s)", address.c_str()); - ReturnValue = inet_pton(address.c_str(), Memory::GetPointer(BufferOut + 4)); + return_value = inet_pton(address.c_str(), Memory::GetPointer(request.buffer_out + 4)); break; } case IOCTL_SO_INETNTOP: { // u32 af = Memory::Read_U32(BufferIn); - // u32 validAddress = Memory::Read_U32(BufferIn + 4); - // u32 src = Memory::Read_U32(BufferIn + 8); + // u32 validAddress = Memory::Read_U32(request.buffer_in + 4); + // u32 src = Memory::Read_U32(request.buffer_in + 8); char ip_s[16]; - sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(BufferIn + 8), Memory::Read_U8(BufferIn + 8 + 1), - Memory::Read_U8(BufferIn + 8 + 2), Memory::Read_U8(BufferIn + 8 + 3)); + sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(request.buffer_in + 8), + Memory::Read_U8(request.buffer_in + 8 + 1), Memory::Read_U8(request.buffer_in + 8 + 2), + Memory::Read_U8(request.buffer_in + 8 + 3)); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETNTOP %s", ip_s); - Memory::Memset(BufferOut, 0, BufferOutSize); - Memory::CopyToEmu(BufferOut, (u8*)ip_s, strlen(ip_s)); + Memory::CopyToEmu(request.buffer_out, (u8*)ip_s, strlen(ip_s)); break; } @@ -943,10 +892,10 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) {POLLWRBAND, 0x0010}, {POLLERR, 0x0020}, {POLLHUP, 0x0040}, {POLLNVAL, 0x0080}, }; - u32 unknown = Memory::Read_U32(BufferIn); - u32 timeout = Memory::Read_U32(BufferIn + 4); + u32 unknown = Memory::Read_U32(request.buffer_in); + u32 timeout = Memory::Read_U32(request.buffer_in + 4); - int nfds = BufferOutSize / 0xc; + int nfds = request.buffer_out_size / 0xc; if (nfds == 0) ERROR_LOG(WII_IPC_NET, "Hidden POLL"); @@ -954,9 +903,9 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) for (int i = 0; i < nfds; ++i) { - ufds[i].fd = Memory::Read_U32(BufferOut + 0xc * i); // fd - int events = Memory::Read_U32(BufferOut + 0xc * i + 4); // events - ufds[i].revents = Memory::Read_U32(BufferOut + 0xc * i + 8); // revents + ufds[i].fd = Memory::Read_U32(request.buffer_out + 0xc * i); // fd + int events = Memory::Read_U32(request.buffer_out + 0xc * i + 4); // events + ufds[i].revents = Memory::Read_U32(request.buffer_out + 0xc * i + 8); // revents // Translate Wii to native events int unhandled_events = events; @@ -993,33 +942,34 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) } // No need to change fd or events as they are input only. - // Memory::Write_U32(ufds[i].fd, BufferOut + 0xc*i); //fd - // Memory::Write_U32(events, BufferOut + 0xc*i + 4); //events - Memory::Write_U32(revents, BufferOut + 0xc * i + 8); // revents + // Memory::Write_U32(ufds[i].fd, request.buffer_out + 0xc*i); //fd + // Memory::Write_U32(events, request.buffer_out + 0xc*i + 4); //events + Memory::Write_U32(revents, request.buffer_out + 0xc * i + 8); // revents DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d wevents %08X events %08X revents %08X", i, revents, ufds[i].events, ufds[i].revents); } - ReturnValue = ret; + return_value = ret; break; } case IOCTL_SO_GETHOSTBYNAME: { - if (BufferOutSize != 0x460) + if (request.buffer_out_size != 0x460) { ERROR_LOG(WII_IPC_NET, "Bad buffer size for IOCTL_SO_GETHOSTBYNAME"); - ReturnValue = -1; + return_value = -1; break; } - std::string hostname = Memory::GetString(BufferIn); + std::string hostname = Memory::GetString(request.buffer_in); hostent* remoteHost = gethostbyname(hostname.c_str()); INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTBYNAME " "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); + hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); if (remoteHost) { @@ -1036,8 +986,6 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) DEBUG_LOG(WII_IPC_NET, "addr%i:%s", i, ip_s.c_str()); } - Memory::Memset(BufferOut, 0, BufferOutSize); - // Host name; located immediately after struct static const u32 GETHOSTBYNAME_STRUCT_SIZE = 0x10; static const u32 GETHOSTBYNAME_IP_LIST_OFFSET = 0x110; @@ -1046,11 +994,12 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) if (name_length > (GETHOSTBYNAME_IP_LIST_OFFSET - GETHOSTBYNAME_STRUCT_SIZE)) { ERROR_LOG(WII_IPC_NET, "Hostname too long in IOCTL_SO_GETHOSTBYNAME"); - ReturnValue = -1; + return_value = -1; break; } - Memory::CopyToEmu(BufferOut + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name, name_length); - Memory::Write_U32(BufferOut + GETHOSTBYNAME_STRUCT_SIZE, BufferOut); + Memory::CopyToEmu(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name, + name_length); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, request.buffer_out); // IP address list; located at offset 0x110. u32 num_ip_addr = 0; @@ -1062,7 +1011,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) num_ip_addr = std::min(num_ip_addr, GETHOSTBYNAME_MAX_ADDRESSES); for (u32 i = 0; i < num_ip_addr; ++i) { - u32 addr = BufferOut + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4; + u32 addr = request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4; Memory::Write_U32_Swap(*(u32*)(remoteHost->h_addr_list[i]), addr); } @@ -1070,30 +1019,31 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) // This must be exact: PPC code to convert the struct hardcodes // this offset. static const u32 GETHOSTBYNAME_IP_PTR_LIST_OFFSET = 0x340; - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET, BufferOut + 12); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET, + request.buffer_out + 12); for (u32 i = 0; i < num_ip_addr; ++i) { - u32 addr = BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4; - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr); + u32 addr = request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4; + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr); } - Memory::Write_U32(0, BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4); + Memory::Write_U32(0, request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4); // Aliases - empty. (Hardware doesn't return anything.) - Memory::Write_U32(BufferOut + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4, - BufferOut + 4); + Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4, + request.buffer_out + 4); // Returned struct must be ipv4. _assert_msg_(WII_IPC_NET, remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32), "returned host info is not IPv4"); - Memory::Write_U16(AF_INET, BufferOut + 8); - Memory::Write_U16(sizeof(u32), BufferOut + 10); + Memory::Write_U16(AF_INET, request.buffer_out + 8); + Memory::Write_U16(sizeof(u32), request.buffer_out + 10); - ReturnValue = 0; + return_value = 0; } else { - ReturnValue = -1; + return_value = -1; } break; @@ -1101,89 +1051,38 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_ICMPCANCEL: ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCANCEL"); - goto default_; default: - INFO_LOG(WII_IPC_NET, "0x%x " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); - default_: - if (BufferInSize) - { - ERROR_LOG(WII_IPC_NET, "in addr %x size %x", BufferIn, BufferInSize); - ERROR_LOG(WII_IPC_NET, "\n%s", - ArrayToString(Memory::GetPointer(BufferIn), BufferInSize, 4).c_str()); - } - - if (BufferOutSize) - { - ERROR_LOG(WII_IPC_NET, "out addr %x size %x", BufferOut, BufferOutSize); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(CommandAddress); - - s32 ReturnValue = 0; - - u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0; - u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0; - - u32 _BufferOut = 0, _BufferOut2 = 0; - u32 BufferOutSize = 0; - - if (CommandBuffer.InBuffer.size() > 0) - { - _BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; - } - if (CommandBuffer.InBuffer.size() > 1) - { - _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; - } - if (CommandBuffer.InBuffer.size() > 2) - { - _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address; - BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size; - } - - if (CommandBuffer.PayloadBuffer.size() > 0) - { - _BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; - } - if (CommandBuffer.PayloadBuffer.size() > 1) - { - _BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - } + s32 return_value = 0; u32 param = 0, param2 = 0, param3, param4, param5 = 0; - - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_SO_GETINTERFACEOPT: { - param = Memory::Read_U32(_BufferIn); - param2 = Memory::Read_U32(_BufferIn + 4); - param3 = Memory::Read_U32(_BufferOut); - param4 = Memory::Read_U32(_BufferOut2); - if (BufferOutSize >= 8) + param = Memory::Read_U32(request.in_vectors[0].address); + param2 = Memory::Read_U32(request.in_vectors[0].address + 4); + param3 = Memory::Read_U32(request.io_vectors[0].address); + param4 = Memory::Read_U32(request.io_vectors[1].address); + if (request.io_vectors[0].size >= 8) { - param5 = Memory::Read_U32(_BufferOut + 4); + param5 = Memory::Read_U32(request.io_vectors[0].address + 4); } INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETINTERFACEOPT(%08X, %08X, %X, %X, %X) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i) ", - param, param2, param3, param4, param5, _BufferIn, BufferInSize, _BufferIn2, - BufferInSize2); + param, param2, param3, param4, param5, request.in_vectors[0].address, + request.in_vectors[0].size, + request.in_vectors.size() > 1 ? request.in_vectors[1].address : 0, + request.in_vectors.size() > 1 ? request.in_vectors[1].size : 0); switch (param2) { @@ -1257,33 +1156,33 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) if (address == 0) address = 0x08080808; - Memory::Write_U32(address, _BufferOut); - Memory::Write_U32(0x08080404, _BufferOut + 4); + Memory::Write_U32(address, request.io_vectors[0].address); + Memory::Write_U32(0x08080404, request.io_vectors[0].address + 4); break; } case 0x1003: // error - Memory::Write_U32(0, _BufferOut); + Memory::Write_U32(0, request.io_vectors[0].address); break; case 0x1004: // mac address u8 address[MAC_ADDRESS_SIZE]; GetMacAddress(address); - Memory::CopyToEmu(_BufferOut, address, sizeof(address)); + Memory::CopyToEmu(request.io_vectors[0].address, address, sizeof(address)); break; case 0x1005: // link state - Memory::Write_U32(1, _BufferOut); + Memory::Write_U32(1, request.io_vectors[0].address); break; case 0x4002: // ip addr number - Memory::Write_U32(1, _BufferOut); + Memory::Write_U32(1, request.io_vectors[0].address); break; case 0x4003: // ip addr table - Memory::Write_U32(0xC, _BufferOut2); - Memory::Write_U32(10 << 24 | 1 << 8 | 30, _BufferOut); - Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, _BufferOut + 4); - Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, _BufferOut + 8); + Memory::Write_U32(0xC, request.io_vectors[1].address); + Memory::Write_U32(10 << 24 | 1 << 8 | 30, request.io_vectors[0].address); + Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, request.io_vectors[0].address + 4); + Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, request.io_vectors[0].address + 8); break; default: @@ -1294,17 +1193,17 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) } case IOCTLV_SO_SENDTO: { - u32 fd = Memory::Read_U32(_BufferIn2); + u32 fd = Memory::Read_U32(request.in_vectors[1].address); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, CommandAddress, IOCTLV_SO_SENDTO); + sm.DoSock(fd, request, IOCTLV_SO_SENDTO); return GetNoReply(); break; } case IOCTLV_SO_RECVFROM: { - u32 fd = Memory::Read_U32(_BufferIn); + u32 fd = Memory::Read_U32(request.in_vectors[0].address); WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(fd, CommandAddress, IOCTLV_SO_RECVFROM); + sm.DoSock(fd, request, IOCTLV_SO_RECVFROM); return GetNoReply(); break; } @@ -1312,13 +1211,13 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) { addrinfo hints; - if (BufferInSize3) + if (request.in_vectors.size() > 2 && request.in_vectors[2].size) { - hints.ai_flags = Memory::Read_U32(_BufferIn3); - hints.ai_family = Memory::Read_U32(_BufferIn3 + 0x4); - hints.ai_socktype = Memory::Read_U32(_BufferIn3 + 0x8); - hints.ai_protocol = Memory::Read_U32(_BufferIn3 + 0xC); - hints.ai_addrlen = Memory::Read_U32(_BufferIn3 + 0x10); + hints.ai_flags = Memory::Read_U32(request.in_vectors[2].address); + hints.ai_family = Memory::Read_U32(request.in_vectors[2].address + 0x4); + hints.ai_socktype = Memory::Read_U32(request.in_vectors[2].address + 0x8); + hints.ai_protocol = Memory::Read_U32(request.in_vectors[2].address + 0xC); + hints.ai_addrlen = Memory::Read_U32(request.in_vectors[2].address + 0x10); hints.ai_canonname = nullptr; hints.ai_addr = nullptr; hints.ai_next = nullptr; @@ -1328,23 +1227,25 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) // So we have to do a bit of juggling here. std::string nodeNameStr; const char* pNodeName = nullptr; - if (BufferInSize > 0) + if (request.in_vectors.size() > 0 && request.in_vectors[0].size > 0) { - nodeNameStr = Memory::GetString(_BufferIn, BufferInSize); + nodeNameStr = Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size); pNodeName = nodeNameStr.c_str(); } std::string serviceNameStr; const char* pServiceName = nullptr; - if (BufferInSize2 > 0) + if (request.in_vectors.size() > 1 && request.in_vectors[1].size > 0) { - serviceNameStr = Memory::GetString(_BufferIn2, BufferInSize2); + serviceNameStr = Memory::GetString(request.in_vectors[1].address, request.in_vectors[1].size); pServiceName = serviceNameStr.c_str(); } addrinfo* result = nullptr; - int ret = getaddrinfo(pNodeName, pServiceName, BufferInSize3 ? &hints : nullptr, &result); - u32 addr = _BufferOut; + int ret = getaddrinfo( + pNodeName, pServiceName, + (request.in_vectors.size() > 2 && request.in_vectors[2].size) ? &hints : nullptr, &result); + u32 addr = request.io_vectors[0].address; u32 sockoffset = addr + 0x460; if (ret == 0) { @@ -1394,11 +1295,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) ret = -305; } - INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - _BufferIn, BufferInSize, _BufferOut, BufferOutSize); - INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetString(_BufferIn).c_str()); - ReturnValue = ret; + request.Dump(GetDeviceName(), LogTypes::WII_IPC_NET, LogTypes::LINFO); + return_value = ret; break; } case IOCTLV_SO_ICMPPING: @@ -1411,19 +1309,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) u32 ip; } ip_info; - u32 fd = Memory::Read_U32(_BufferIn); - u32 num_ip = Memory::Read_U32(_BufferIn + 4); - u64 timeout = Memory::Read_U64(_BufferIn + 8); + u32 fd = Memory::Read_U32(request.in_vectors[0].address); + u32 num_ip = Memory::Read_U32(request.in_vectors[0].address + 4); + u64 timeout = Memory::Read_U64(request.in_vectors[0].address + 8); if (num_ip != 1) { INFO_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING %i IPs", num_ip); } - ip_info.length = Memory::Read_U8(_BufferIn + 16); - ip_info.addr_family = Memory::Read_U8(_BufferIn + 17); - ip_info.icmp_id = Memory::Read_U16(_BufferIn + 18); - ip_info.ip = Memory::Read_U32(_BufferIn + 20); + ip_info.length = Memory::Read_U8(request.in_vectors[0].address + 16); + ip_info.addr_family = Memory::Read_U8(request.in_vectors[0].address + 17); + ip_info.icmp_id = Memory::Read_U16(request.in_vectors[0].address + 18); + ip_info.ip = Memory::Read_U32(request.in_vectors[0].address + 20); if (ip_info.length != 8 || ip_info.addr_family != AF_INET) { @@ -1443,8 +1341,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) memset(data, 0, sizeof(data)); s32 icmp_length = sizeof(data); - if (BufferInSize2 == sizeof(data)) - Memory::CopyFromEmu(data, _BufferIn2, BufferInSize2); + if (request.in_vectors.size() > 1 && request.in_vectors[1].size == sizeof(data)) + Memory::CopyFromEmu(data, request.in_vectors[1].address, request.in_vectors[1].size); else { // TODO sequence number is incremented either statically, by @@ -1461,32 +1359,14 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) } // TODO proper error codes - ReturnValue = 0; + return_value = 0; break; } default: - INFO_LOG(WII_IPC_NET, "0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)", - CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2); - for (u32 i = 0; i < CommandBuffer.NumberInBuffer; ++i) - { - ERROR_LOG(WII_IPC_NET, "in %i addr %x size %x", i, CommandBuffer.InBuffer.at(i).m_Address, - CommandBuffer.InBuffer.at(i).m_Size); - ERROR_LOG(WII_IPC_NET, "\n%s", - ArrayToString(Memory::GetPointer(CommandBuffer.InBuffer.at(i).m_Address), - CommandBuffer.InBuffer.at(i).m_Size, 4) - .c_str()); - } - for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; ++i) - { - ERROR_LOG(WII_IPC_NET, "out %i addr %x size %x", i, - CommandBuffer.PayloadBuffer.at(i).m_Address, - CommandBuffer.PayloadBuffer.at(i).m_Size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_NET); } - Memory::Write_U32(ReturnValue, CommandAddress + 4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } void CWII_IPC_HLE_Device_net_ip_top::Update() diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h index 3e02819351..2e82d20956 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -30,7 +30,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_kd_request(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum @@ -86,35 +86,31 @@ public: } virtual ~CWII_IPC_HLE_Device_net_kd_time() {} - IPCCommandResult IOCtl(u32 _CommandAddress) override + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override { - u32 Parameter = Memory::Read_U32(_CommandAddress + 0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - - u32 result = 0; + s32 result = 0; u32 common_result = 0; // TODO Writes stuff to /shared2/nwc24/misc.bin // u32 update_misc = 0; - switch (Parameter) + switch (request.request) { case IOCTL_NW24_GET_UNIVERSAL_TIME: - Memory::Write_U64(GetAdjustedUTC(), BufferOut + 4); + Memory::Write_U64(GetAdjustedUTC(), request.buffer_out + 4); break; case IOCTL_NW24_SET_UNIVERSAL_TIME: - SetAdjustedUTC(Memory::Read_U64(BufferIn)); - // update_misc = Memory::Read_U32(BufferIn + 8); + SetAdjustedUTC(Memory::Read_U64(request.buffer_in)); + // update_misc = Memory::Read_U32(request.buffer_in + 8); break; case IOCTL_NW24_SET_RTC_COUNTER: - rtc = Memory::Read_U32(BufferIn); - // update_misc = Memory::Read_U32(BufferIn + 4); + rtc = Memory::Read_U32(request.buffer_in); + // update_misc = Memory::Read_U32(request.buffer_in + 4); break; case IOCTL_NW24_GET_TIME_DIFF: - Memory::Write_U64(GetAdjustedUTC() - rtc, BufferOut + 4); + Memory::Write_U64(GetAdjustedUTC() - rtc, request.buffer_out + 4); break; case IOCTL_NW24_UNIMPLEMENTED: @@ -122,14 +118,13 @@ public: break; default: - ERROR_LOG(WII_IPC_NET, "%s - unknown IOCtl: %x", GetDeviceName().c_str(), Parameter); + ERROR_LOG(WII_IPC_NET, "%s - unknown IOCtl: %x", GetDeviceName().c_str(), request.request); break; } // write return values - Memory::Write_U32(common_result, BufferOut); - Memory::Write_U32(result, _CommandAddress + 4); - return GetDefaultReply(); + Memory::Write_U32(common_result, request.buffer_out); + return GetDefaultReply(result); } private: @@ -207,8 +202,8 @@ public: virtual ~CWII_IPC_HLE_Device_net_ip_top(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void Update() override; @@ -227,7 +222,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_ncd_manage(); - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum @@ -253,7 +248,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_wd_command(); - IPCCommandResult IOCtlV(u32 CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; private: enum diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp index ab77ef1596..32d6129f7a 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp @@ -75,72 +75,58 @@ int CWII_IPC_HLE_Device_net_ssl::GetSSLFreeID() const return 0; } -IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtl(const IOSIOCtlRequest& request) { - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - u32 Command = Memory::Read_U32(_CommandAddress + 0x0C); - - INFO_LOG(WII_IPC_SSL, "%s unknown %i " - "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); + request.Log(GetDeviceName(), LogTypes::WII_IPC_SSL, LogTypes::LINFO); + return GetDefaultReply(IPC_SUCCESS); } -IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(const IOSIOCtlVRequest& request) { - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0; + u32 BufferIn = 0, BufferIn2 = 0, BufferIn3 = 0; u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0; u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0; u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0; - if (CommandBuffer.InBuffer.size() > 0) + if (request.in_vectors.size() > 0) { - _BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; + BufferIn = request.in_vectors.at(0).address; + BufferInSize = request.in_vectors.at(0).size; } - if (CommandBuffer.InBuffer.size() > 1) + if (request.in_vectors.size() > 1) { - _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; + BufferIn2 = request.in_vectors.at(1).address; + BufferInSize2 = request.in_vectors.at(1).size; } - if (CommandBuffer.InBuffer.size() > 2) + if (request.in_vectors.size() > 2) { - _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address; - BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size; + BufferIn3 = request.in_vectors.at(2).address; + BufferInSize3 = request.in_vectors.at(2).size; } - if (CommandBuffer.PayloadBuffer.size() > 0) + if (request.io_vectors.size() > 0) { - BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; + BufferOut = request.io_vectors.at(0).address; + BufferOutSize = request.io_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 1) + if (request.io_vectors.size() > 1) { - BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size; + BufferOut2 = request.io_vectors.at(1).address; + BufferOutSize2 = request.io_vectors.at(1).size; } - if (CommandBuffer.PayloadBuffer.size() > 2) + if (request.io_vectors.size() > 2) { - BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address; - BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size; + BufferOut3 = request.io_vectors.at(2).address; + BufferOutSize3 = request.io_vectors.at(2).size; } // I don't trust SSL to be deterministic, and this is never going to sync // as such (as opposed to forwarding IPC results or whatever), so - if (Core::g_want_determinism) - { - Memory::Write_U32(-1, _CommandAddress + 0x4); - return GetDefaultReply(); - } + return GetDefaultReply(IPC_EACCES); - switch (CommandBuffer.Parameter) + switch (request.request) { case IOCTLV_NET_SSL_NEW: { @@ -187,20 +173,20 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str()); ssl->active = true; - Memory::Write_U32(freeSSL, _BufferIn); + Memory::Write_U32(freeSSL, BufferIn); } else { _SSL_NEW_ERROR: - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - verifyOption, hostname.c_str(), _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, - _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, + verifyOption, hostname.c_str(), BufferIn, BufferInSize, BufferIn2, BufferInSize2, + BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } @@ -226,18 +212,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) ssl->active = false; - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETROOTCA: @@ -246,8 +232,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -264,19 +250,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (ret) { - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } @@ -286,8 +272,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -302,19 +288,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) { mbedtls_x509_crt_free(&ssl->clicert); mbedtls_pk_free(&ssl->pk); - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_own_cert(&ssl->config, &ssl->clicert, &ssl->pk); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, pk_ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; @@ -325,8 +311,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) @@ -336,11 +322,11 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) mbedtls_pk_free(&ssl->pk); mbedtls_ssl_conf_own_cert(&ssl->config, nullptr, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; @@ -357,25 +343,25 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (ret) { mbedtls_x509_crt_free(&ssl->clicert); - Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); + Memory::Write_U32(SSL_ERR_FAILED, BufferIn); } else { mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_CONNECT: @@ -388,18 +374,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) ssl->sockfd = Memory::Read_U32(BufferOut2); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", ssl->sockfd); mbedtls_ssl_set_bio(&ssl->ctx, &ssl->sockfd, mbedtls_net_send, mbedtls_net_recv, nullptr); - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_DOHANDSHAKE: @@ -408,12 +394,12 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } @@ -423,19 +409,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); INFO_LOG(WII_IPC_SSL, "%s", Memory::GetString(BufferOut2).c_str()); break; } @@ -446,19 +432,19 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) if (SSLID_VALID(sslID)) { WiiSockMan& sm = WiiSockMan::GetInstance(); - sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ); + sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ); return GetNoReply(); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)" "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - ret, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, + ret, BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } @@ -467,18 +453,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT: @@ -487,33 +473,24 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, - BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); + BufferIn, BufferInSize, BufferIn2, BufferInSize2, BufferIn3, BufferInSize3, BufferOut, + BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { - Memory::Write_U32(SSL_OK, _BufferIn); + Memory::Write_U32(SSL_OK, BufferIn); } else { - Memory::Write_U32(SSL_ERR_ID, _BufferIn); + Memory::Write_U32(SSL_ERR_ID, BufferIn); } break; } default: - ERROR_LOG(WII_IPC_SSL, "%i " - "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " - "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " - "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, - _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, - BufferOut3, BufferOutSize3); - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_SSL); } // SSL return codes are written to BufferIn - Memory::Write_U32(0, _CommandAddress + 4); - - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h index b8ec088776..cdb689163b 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h @@ -87,8 +87,8 @@ public: virtual ~CWII_IPC_HLE_Device_net_ssl(); - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; int GetSSLFreeID() const; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index be712534cd..da985a72e6 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -38,15 +38,15 @@ void CWII_IPC_HLE_Device_sdio_slot0::DoState(PointerWrap& p) void CWII_IPC_HLE_Device_sdio_slot0::EventNotify() { + if (!m_event) + return; // Accessing SConfig variables like this isn't really threadsafe, // but this is how it's done all over the place... - if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) || - (!SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_REMOVE)) + if ((SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_INSERT) || + (!SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_REMOVE)) { - Memory::Write_U32(m_event.type, m_event.addr + 4); - WII_IPC_HLE_Interface::EnqueueReply(m_event.addr); - m_event.addr = 0; - m_event.type = EVENT_NONE; + WII_IPC_HLE_Interface::EnqueueReply(m_event->request, m_event->type); + m_event.reset(); } } @@ -70,50 +70,35 @@ void CWII_IPC_HLE_Device_sdio_slot0::OpenInternal() } } -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_sdio_slot0::Open(const IOSOpenRequest& request) { - INFO_LOG(WII_IPC_SD, "Open"); - OpenInternal(); - m_registers.fill(0); + m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::Close(u32 _CommandAddress, bool _bForce) +void CWII_IPC_HLE_Device_sdio_slot0::Close() { - INFO_LOG(WII_IPC_SD, "Close"); - m_Card.Close(); m_BlockLength = 0; m_BusWidth = 0; m_is_active = false; - return GetDefaultReply(); } // The front SD slot -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(const IOSIOCtlRequest& request) { - u32 Cmd = Memory::Read_U32(_CommandAddress + 0xC); - - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - // As a safety precaution we fill the out buffer with zeros to avoid - // returning nonsense values - Memory::Memset(BufferOut, 0, BufferOutSize); - - u32 ReturnValue = 0; - switch (Cmd) + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_WRITEHCR: { - u32 reg = Memory::Read_U32(BufferIn); - u32 val = Memory::Read_U32(BufferIn + 16); + u32 reg = Memory::Read_U32(request.buffer_in); + u32 val = Memory::Read_U32(request.buffer_in + 16); INFO_LOG(WII_IPC_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val); @@ -143,7 +128,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) case IOCTL_READHCR: { - u32 reg = Memory::Read_U32(BufferIn); + u32 reg = Memory::Read_U32(request.buffer_in); if (reg >= m_registers.size()) { @@ -155,7 +140,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val); // Just reading the register - Memory::Write_U32(val, BufferOut); + Memory::Write_U32(val, request.buffer_out); } break; @@ -164,7 +149,7 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) if (m_Card) m_Status |= CARD_INITIALIZED; // Returns 16bit RCA and 16bit 0s (meaning success) - Memory::Write_U32(0x9f620000, BufferOut); + Memory::Write_U32(0x9f620000, request.buffer_out); break; case IOCTL_SETCLK: @@ -172,15 +157,17 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_SETCLK"); // libogc only sets it to 1 and makes sure the return isn't negative... // one half of the sdclk divisor: a power of two or zero. - u32 clock = Memory::Read_U32(BufferIn); + u32 clock = Memory::Read_U32(request.buffer_in); if (clock != 1) INFO_LOG(WII_IPC_SD, "Setting to %i, interesting", clock); } break; case IOCTL_SENDCMD: - INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(BufferIn), _CommandAddress); - ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize); + INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(request.buffer_in), + request.address); + return_value = ExecuteCommand(request, request.buffer_in, request.buffer_in_size, 0, 0, + request.buffer_out, request.buffer_out_size); break; case IOCTL_GETSTATUS: @@ -191,89 +178,51 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s", (m_Status & CARD_INSERTED) ? "inserted" : "not present", (m_Status & CARD_INITIALIZED) ? " and initialized" : ""); - Memory::Write_U32(m_Status, BufferOut); + Memory::Write_U32(m_Status, request.buffer_out); break; case IOCTL_GETOCR: INFO_LOG(WII_IPC_SD, "IOCTL_GETOCR"); - Memory::Write_U32(0x80ff8000, BufferOut); + Memory::Write_U32(0x80ff8000, request.buffer_out); break; default: - ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", Cmd); + ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", request.request); break; } - // INFO_LOG(WII_IPC_SD, "InBuffer"); - // DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD); - // INFO_LOG(WII_IPC_SD, "OutBuffer"); - // DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD); - - if (ReturnValue == RET_EVENT_REGISTER) + if (return_value == RET_EVENT_REGISTER) { - // async - m_event.addr = _CommandAddress; - Memory::Write_U32(0, _CommandAddress + 0x4); // Check if the condition is already true EventNotify(); return GetNoReply(); } - else if (ReturnValue == RET_EVENT_UNREGISTER) - { - // release returns 0 - // unknown sd int - // technically we do it out of order, oh well - Memory::Write_U32(EVENT_INVALID, m_event.addr + 4); - WII_IPC_HLE_Interface::EnqueueReply(m_event.addr); - m_event.addr = 0; - m_event.type = EVENT_NONE; - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); - } - else - { - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - return GetDefaultReply(); - } + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(const IOSIOCtlVRequest& request) { - // PPC sending commands - - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - // Prepare the out buffer(s) with zeros as a safety precaution - // to avoid returning bad values - for (const auto& buffer : CommandBuffer.PayloadBuffer) - Memory::Memset(buffer.m_Address, 0, buffer.m_Size); - - u32 ReturnValue = 0; - switch (CommandBuffer.Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTLV_SENDCMD: - DEBUG_LOG(WII_IPC_SD, "IOCTLV_SENDCMD 0x%08x", - Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address)); - ReturnValue = ExecuteCommand( - CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size, - CommandBuffer.InBuffer[1].m_Address, CommandBuffer.InBuffer[1].m_Size, - CommandBuffer.PayloadBuffer[0].m_Address, CommandBuffer.PayloadBuffer[0].m_Size); + DEBUG_LOG(WII_IPC_SD, "IOCTLV_SENDCMD 0x%08x", Memory::Read_U32(request.in_vectors[0].address)); + Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size); + return_value = + ExecuteCommand(request, request.in_vectors[0].address, request.in_vectors[0].size, + request.in_vectors[1].address, request.in_vectors[1].size, + request.io_vectors[0].address, request.io_vectors[0].size); break; default: - ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtlV command 0x%08x", CommandBuffer.Parameter); - break; + ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtlV command 0x%08x", request.request); } - // DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - // CommandBuffer.NumberPayloadBuffer, LogTypes::WII_IPC_SD); - - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - return GetDefaultReply(); + return GetDefaultReply(return_value); } -u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _rwBuffer, +u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(const IOSRequest& request, u32 _BufferIn, + u32 _BufferInSize, u32 _rwBuffer, u32 _rwBufferSize, u32 _BufferOut, u32 _BufferOutSize) { @@ -429,15 +378,23 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS case EVENT_REGISTER: // async INFO_LOG(WII_IPC_SD, "Register event %x", req.arg); - m_event.type = (EventType)req.arg; + m_event = std::make_unique(static_cast(req.arg), request); ret = RET_EVENT_REGISTER; break; - case EVENT_UNREGISTER: // synchronous + // Used to cancel an event that was already registered. + case EVENT_UNREGISTER: + { INFO_LOG(WII_IPC_SD, "Unregister event %x", req.arg); - m_event.type = (EventType)req.arg; - ret = RET_EVENT_UNREGISTER; + if (!m_event) + return IPC_EINVAL; + // release returns 0 + // unknown sd int + // technically we do it out of order, oh well + WII_IPC_HLE_Interface::EnqueueReply(m_event->request, EVENT_INVALID); + m_event.reset(); break; + } default: ERROR_LOG(WII_IPC_SD, "Unknown SD command 0x%08x", req.command); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h index 7d51547c0c..d8d409322c 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h @@ -23,11 +23,10 @@ public: void DoState(PointerWrap& p) override; - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtl(u32 _CommandAddress) override; - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void EventNotify(); @@ -63,7 +62,6 @@ private: RET_OK, RET_FAIL, RET_EVENT_REGISTER, // internal state only - not actually returned - RET_EVENT_UNREGISTER }; // Status @@ -100,9 +98,8 @@ private: enum EventType { - EVENT_NONE = 0, - EVENT_INSERT, - EVENT_REMOVE, + EVENT_INSERT = 1, + EVENT_REMOVE = 2, // from unregister, i think it is just meant to be invalid EVENT_INVALID = 0xc210000 }; @@ -110,9 +107,11 @@ private: // TODO do we need more than one? struct Event { - EventType type = EVENT_NONE; - u32 addr = 0; - } m_event; + Event(EventType type_, IOSRequest request_) : type(type_), request(request_) {} + EventType type; + IOSRequest request; + }; + std::unique_ptr m_event; u32 m_Status = CARD_NOT_EXIST; u32 m_BlockLength = 0; @@ -122,7 +121,7 @@ private: File::IOFile m_Card; - u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 BufferIn2, u32 BufferInSize2, - u32 _BufferOut, u32 BufferOutSize); + u32 ExecuteCommand(const IOSRequest& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2, + u32 BufferInSize2, u32 _BufferOut, u32 BufferOutSize); void OpenInternal(); }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp index 07d2747ba0..7a57814b15 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp @@ -5,6 +5,7 @@ #include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h" #include +#include #include "Common/Assert.h" #include "Common/Logging/Log.h" @@ -16,22 +17,12 @@ void QueueHostJob(std::function job, bool run_during_stop); void Stop(); } -static u32 s_event_hook_address = 0; +static std::unique_ptr s_event_hook_request; -IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(const IOSIOCtlRequest& request) { - u32 parameter = Memory::Read_U32(command_address + 0x0C); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - - // Prepare the out buffer(s) with zeroes as a safety precaution - // to avoid returning bad values - Memory::Memset(buffer_out, 0, buffer_out_size); - u32 return_value = 0; - - switch (parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_STM_IDLE: case IOCTL_STM_SHUTDOWN: @@ -40,15 +31,14 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) break; case IOCTL_STM_RELEASE_EH: - if (s_event_hook_address == 0) + if (!s_event_hook_request) { return_value = IPC_ENOENT; break; } - Memory::Write_U32(0, Memory::Read_U32(s_event_hook_address + 0x18)); - Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address); - s_event_hook_address = 0; + Memory::Write_U32(0, s_event_hook_request->buffer_out); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request, IPC_SUCCESS); + s_event_hook_request.reset(); break; case IOCTL_STM_HOTRESET: @@ -59,7 +49,6 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) case IOCTL_STM_VIDIMMING: // (Input: 20 bytes, Output: 20 bytes) INFO_LOG(WII_IPC_STM, "%s - IOCtl:", GetDeviceName().c_str()); INFO_LOG(WII_IPC_STM, " IOCTL_STM_VIDIMMING"); - // DumpCommands(buffer_in, buffer_in_size / 4, LogTypes::WII_IPC_STM); // Memory::Write_U32(1, buffer_out); // return_value = 1; break; @@ -70,79 +59,53 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) break; default: - { - _dbg_assert_msg_(WII_IPC_STM, 0, "CWII_IPC_HLE_Device_stm_immediate: 0x%x", parameter); - - INFO_LOG(WII_IPC_STM, "%s - IOCtl:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_STM, " parameter: 0x%x", parameter); - DEBUG_LOG(WII_IPC_STM, " InBuffer: 0x%08x", buffer_in); - DEBUG_LOG(WII_IPC_STM, " InBufferSize: 0x%08x", buffer_in_size); - DEBUG_LOG(WII_IPC_STM, " OutBuffer: 0x%08x", buffer_out); - DEBUG_LOG(WII_IPC_STM, " OutBufferSize: 0x%08x", buffer_out_size); - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_STM); } - // Write return value to the IPC call - Memory::Write_U32(return_value, command_address + 0x4); - return GetDefaultReply(); + return GetDefaultReply(return_value); } -IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_stm_eventhook::Close() { - s_event_hook_address = 0; - + s_event_hook_request.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(const IOSIOCtlRequest& request) { - u32 parameter = Memory::Read_U32(command_address + 0x0C); - if (parameter != IOCTL_STM_EVENTHOOK) + if (request.request != IOCTL_STM_EVENTHOOK) { ERROR_LOG(WII_IPC_STM, "Bad IOCtl in CWII_IPC_HLE_Device_stm_eventhook"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); - return GetDefaultReply(); + return GetDefaultReply(IPC_EINVAL); } - if (s_event_hook_address != 0) - { - Memory::Write_U32(FS_EEXIST, command_address + 4); - return GetDefaultReply(); - } + if (s_event_hook_request) + return GetDefaultReply(IPC_EEXIST); - // IOCTL_STM_EVENTHOOK waits until the reset button or power button - // is pressed. - s_event_hook_address = command_address; + // IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed. + s_event_hook_request = std::make_unique(request.address); return GetNoReply(); } bool CWII_IPC_HLE_Device_stm_eventhook::HasHookInstalled() const { - return s_event_hook_address != 0; + return s_event_hook_request != nullptr; } void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const { - if (!m_is_active || s_event_hook_address == 0) - { - // If the device isn't open, ignore the button press. + // If the device isn't open, ignore the button press. + if (!m_is_active || !s_event_hook_request) return; - } - // The reset button returns STM_EVENT_RESET. - u32 buffer_out = Memory::Read_U32(s_event_hook_address + 0x18); - Memory::Write_U32(event, buffer_out); - - Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4); - WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address); - s_event_hook_address = 0; + Memory::Write_U32(event, s_event_hook_request->buffer_out); + WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request, IPC_SUCCESS); + s_event_hook_request.reset(); } void CWII_IPC_HLE_Device_stm_eventhook::ResetButton() const { - // The reset button returns STM_EVENT_RESET. + // The reset button triggers STM_EVENT_RESET. TriggerEvent(STM_EVENT_RESET); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h index 879568ea15..b83a8dc4a3 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -43,8 +43,7 @@ public: { } - ~CWII_IPC_HLE_Device_stm_immediate() override = default; - IPCCommandResult IOCtl(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; }; // The /dev/stm/eventhook @@ -56,9 +55,8 @@ public: { } - ~CWII_IPC_HLE_Device_stm_eventhook() override = default; - IPCCommandResult Close(u32 command_address, bool force) override; - IPCCommandResult IOCtl(u32 command_address) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; bool HasHookInstalled() const; void ResetButton() const; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp index aa8dc57050..690182ab52 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp @@ -4,37 +4,33 @@ #include "Core/IPC_HLE/WII_IPC_HLE_Device_stub.h" #include "Common/Logging/Log.h" -#include "Core/HW/Memmap.h" CWII_IPC_HLE_Device_stub::CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name) : IWII_IPC_HLE_Device(device_id, device_name) { } -IPCCommandResult CWII_IPC_HLE_Device_stub::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_stub::Open(const IOSOpenRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking Open()", m_name.c_str()); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_stub::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_stub::Close() { WARN_LOG(WII_IPC_HLE, "%s faking Close()", m_name.c_str()); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(const IOSIOCtlRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_name.c_str()); - Memory::Write_U32(IPC_SUCCESS, command_address + 4); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } -IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(const IOSIOCtlVRequest& request) { WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_name.c_str()); - Memory::Write_U32(IPC_SUCCESS, command_address + 4); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h index 68449b8172..8dd7c72eab 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h @@ -15,8 +15,8 @@ class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name); - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult Close(u32 command_address, bool force = false) override; - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp index 4f6b9d77b0..26a182d8ed 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp @@ -50,24 +50,23 @@ void RestoreBTInfoSection(SysConf* sysconf) File::Delete(filename); } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const SIOCtlVBuffer& cmd_buffer) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - request_type = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - request = Memory::Read_U8(cmd_buffer.InBuffer[1].m_Address); - value = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[2].m_Address)); - index = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[3].m_Address)); - length = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[4].m_Address)); - payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - address = cmd_buffer.m_Address; + request_type = Memory::Read_U8(ioctlv.in_vectors[0].address); + request = Memory::Read_U8(ioctlv.in_vectors[1].address); + value = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[2].address)); + index = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[3].address)); + length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address)); + payload_addr = ioctlv.io_vectors[0].address; } -CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, - const u32 command_address) +CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const IOSIOCtlVRequest& ioctlv) + : ios_request(ioctlv) { - m_endpoint = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address); - m_length = Memory::Read_U16(cmd_buffer.InBuffer[1].m_Address); - m_payload_addr = cmd_buffer.PayloadBuffer[0].m_Address; - m_cmd_address = command_address; + m_endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address); + m_length = Memory::Read_U16(ioctlv.in_vectors[1].address); + m_payload_addr = ioctlv.io_vectors[0].address; } void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* src, @@ -77,8 +76,3 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* m_length); Memory::CopyToEmu(m_payload_addr, src, size); } - -void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::SetRetVal(const u32 retval) const -{ - Memory::Write_U32(retval, m_cmd_address + 4); -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h index a880498fa1..d5580299c3 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h @@ -24,11 +24,6 @@ public: : IWII_IPC_HLE_Device(device_id, device_name) { } - virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_base() override = default; - - virtual IPCCommandResult Open(u32 command_address, u32 mode) override = 0; - - virtual void DoState(PointerWrap& p) override = 0; virtual void UpdateSyncButtonState(bool is_held) {} virtual void TriggerSyncButtonPressedEvent() {} @@ -56,31 +51,23 @@ protected: struct CtrlMessage { - CtrlMessage() = default; - CtrlMessage(const SIOCtlVBuffer& cmd_buffer); - + CtrlMessage(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; u8 request_type = 0; u8 request = 0; u16 value = 0; u16 index = 0; u16 length = 0; u32 payload_addr = 0; - u32 address = 0; }; - class CtrlBuffer + struct CtrlBuffer { - public: - CtrlBuffer() = default; - CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, u32 command_address); - + CtrlBuffer(const IOSIOCtlVRequest& ioctlv); + IOSIOCtlVRequest ios_request; void FillBuffer(const u8* src, size_t size) const; - void SetRetVal(const u32 retval) const; - bool IsValid() const { return m_cmd_address != 0; } - void Invalidate() { m_cmd_address = m_payload_addr = 0; } u8 m_endpoint = 0; u16 m_length = 0; u32 m_payload_addr = 0; - u32 m_cmd_address = 0; }; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index f81169a140..11d5371b55 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -95,8 +95,6 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu m_ControllerBD.b[4] = 0x00; m_ControllerBD.b[5] = 0xFF; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - Host_SetWiiMoteConnectionState(0); } @@ -106,6 +104,18 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::~CWII_IPC_HLE_Device_usb_oh1_57e_305_em SetUsbPointer(nullptr); } +template +static void DoStateForMessage(PointerWrap& p, std::unique_ptr& message) +{ + u32 request_address = (message != nullptr) ? message->ios_request.address : 0; + p.Do(request_address); + if (request_address != 0) + { + IOSIOCtlVRequest request{request_address}; + message = std::make_unique(request); + } +} + void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) { bool passthrough_bluetooth = false; @@ -119,10 +129,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p) p.Do(m_is_active); p.Do(m_ControllerBD); - p.Do(m_CtrlSetup); - p.Do(m_ACLSetup); - p.DoPOD(m_HCIEndpoint); - p.DoPOD(m_ACLEndpoint); + DoStateForMessage(p, m_CtrlSetup); + DoStateForMessage(p, m_HCIEndpoint); + DoStateForMessage(p, m_ACLEndpoint); p.Do(m_last_ticks); p.DoArray(m_PacketCount); p.Do(m_ScanEnable); @@ -138,75 +147,41 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::RemoteDisconnect(u16 _connectionHa return SendEventDisconnect(_connectionHandle, 0x13); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Open(u32 _CommandAddress, u32 _Mode) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close() { + // Clean up state m_ScanEnable = 0; - m_last_ticks = 0; memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; - - m_is_active = true; - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close(u32 _CommandAddress, bool _bForce) -{ - m_ScanEnable = 0; - - m_last_ticks = 0; - memset(m_PacketCount, 0, sizeof(m_PacketCount)); - - m_HCIEndpoint.m_cmd_address = 0; - m_ACLEndpoint.m_cmd_address = 0; + m_HCIEndpoint.reset(); + m_ACLEndpoint.reset(); m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(const IOSIOCtlVRequest& request) { - bool _SendReply = false; - - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - switch (CommandBuffer.Parameter) + bool send_reply = true; + switch (request.request) { case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack { - // This is the HCI datapath from CPU to Wii Remote, the USB stuff is little endian.. - m_CtrlSetup.bRequestType = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); - m_CtrlSetup.bRequest = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address); - m_CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address); - m_CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address); - m_CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address); - m_CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address; - m_CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size; - m_CtrlSetup.m_Address = CommandBuffer.m_Address; - - // check termination - _dbg_assert_msg_(WII_IPC_WIIMOTE, - *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0, - "WIIMOTE: Termination != 0"); - + m_CtrlSetup = std::make_unique(request); // Replies are generated inside - ExecuteHCICommandMessage(m_CtrlSetup); + ExecuteHCICommandMessage(*m_CtrlSetup); + m_CtrlSetup.reset(); + send_reply = false; + break; } - break; case USBV0_IOCTL_BLKMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; switch (ctrl.m_endpoint) { case ACL_DATA_OUT: // ACL data is received from the stack { // This is the ACL datapath from CPU to Wii Remote - // Here we only need to record the command address in case we need to delay the reply - m_ACLSetup = CommandBuffer.m_Address; - const auto* acl_header = reinterpret_cast(Memory::GetPointer(ctrl.m_payload_addr)); @@ -216,69 +191,42 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAdd SendToDevice(HCI_CON_HANDLE(acl_header->con_handle), Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)), acl_header->length); - - _SendReply = true; + break; } - break; - case ACL_DATA_IN: // We are given an ACL buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_ACLEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", _CommandAddress); + m_ACLEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address); + send_reply = false; + break; } - break; - default: - { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint); } break; - } } - break; case USBV0_IOCTL_INTRMSG: { - const CtrlBuffer ctrl(CommandBuffer, _CommandAddress); + const CtrlBuffer ctrl{request}; if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill { - CtrlBuffer temp(CommandBuffer, _CommandAddress); - m_HCIEndpoint = temp; - - DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", _CommandAddress); + m_HCIEndpoint = std::make_unique(request); + DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address); + send_reply = false; } else { _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint); } + break; } - break; default: - { - _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown CWII_IPC_HLE_Device_usb_oh1_57e_305: %x", - CommandBuffer.Parameter); - - INFO_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, - CommandBuffer.NumberPayloadBuffer); -#endif - } - break; + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_WIIMOTE); } - // write return value - Memory::Write_U32(0, _CommandAddress + 4); - return _SendReply ? GetDefaultReply() : GetNoReply(); + return send_reply ? GetDefaultReply(IPC_SUCCESS) : GetNoReply(); } // Here we handle the USBV0_IOCTL_BLKMSG Ioctlv @@ -306,22 +254,22 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", connection_handle); - if (m_ACLEndpoint.IsValid() && !m_HCIEndpoint.IsValid() && m_EventQueue.empty()) + if (m_ACLEndpoint && !m_HCIEndpoint && m_EventQueue.empty()) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x", - m_ACLEndpoint.m_cmd_address); + m_ACLEndpoint->ios_request.address); hci_acldata_hdr_t* header = - reinterpret_cast(Memory::GetPointer(m_ACLEndpoint.m_payload_addr)); + reinterpret_cast(Memory::GetPointer(m_ACLEndpoint->m_payload_addr)); header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT); header->length = size; // Write the packet to the buffer memcpy(reinterpret_cast(header) + sizeof(hci_acldata_hdr_t), data, header->length); - m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint.m_cmd_address); - m_ACLEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request, + sizeof(hci_acldata_hdr_t) + size); + m_ACLEndpoint.reset(); } else { @@ -340,17 +288,16 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...", ((hci_event_hdr_t*)_event.m_buffer)->event); - if (m_HCIEndpoint.IsValid()) + if (m_HCIEndpoint) { if (m_EventQueue.empty()) // fast path :) { DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x", - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size); - m_HCIEndpoint.SetRetVal(_event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, _event.m_size); + m_HCIEndpoint.reset(); } else // push new one, pop oldest { @@ -361,12 +308,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x " "being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } } @@ -381,24 +327,26 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() { // check HCI queue - if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid()) + if (!m_EventQueue.empty() && m_HCIEndpoint) { // an endpoint has become available, and we have a stored response. const SQueuedEvent& event = m_EventQueue.front(); DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x being written from queue (%zu) to %08x...", ((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1, - m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size); - m_HCIEndpoint.SetRetVal(event.m_size); + m_HCIEndpoint->ios_request.address); + m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); // Send a reply to indicate HCI buffer is filled - WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address); - m_HCIEndpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); + m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } // check ACL queue - if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty()) - m_acl_pool.WriteToEndpoint(m_ACLEndpoint); + if (!m_acl_pool.IsEmpty() && m_ACLEndpoint && m_EventQueue.empty()) + { + m_acl_pool.WriteToEndpoint(*m_ACLEndpoint); + m_ACLEndpoint.reset(); + } // We wait for ScanEnable to be sent from the Bluetooth stack through HCI_CMD_WRITE_SCAN_ENABLE // before we initiate the connection. @@ -406,7 +354,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() // FiRES: TODO find a better way to do this // Create ACL connection - if (m_HCIEndpoint.IsValid() && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) + if (m_HCIEndpoint && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE)) { for (auto& wiimote : m_WiiMotes) { @@ -419,7 +367,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update() } // Link channels when connected - if (m_ACLEndpoint.IsValid()) + if (m_ACLEndpoint) { for (auto& wiimote : m_WiiMotes) { @@ -473,7 +421,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " "queue to %08x", - endpoint.m_cmd_address); + endpoint.ios_request.address); hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr); pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); @@ -482,12 +430,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe // Write the packet to the buffer std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t)); - endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); - m_queue.pop_front(); - WII_IPC_HLE_Interface::EnqueueReply(endpoint.m_cmd_address); - endpoint.Invalidate(); + WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size); } bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete() @@ -1027,10 +972,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventConPacketTypeChange(u16 _ // Command dispatcher // This is called from the USBV0_IOCTL_CTRLMSG Ioctlv void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( - const SHCICommandMessage& _rHCICommandMessage) + const CtrlMessage& ctrl_message) { - u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3); - SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr); + u8* pInput = Memory::GetPointer(ctrl_message.payload_addr + 3); + SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.payload_addr); u16 ocf = HCI_OCF(pMsg->Opcode); u16 ogf = HCI_OGF(pMsg->Opcode); @@ -1114,11 +1059,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( // vendor specific... case 0xFC4C: - CommandVendorSpecific_FC4C(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4C(pInput, ctrl_message.length - 3); break; case 0xFC4F: - CommandVendorSpecific_FC4F(pInput, _rHCICommandMessage.m_PayLoadSize - 3); + CommandVendorSpecific_FC4F(pInput, ctrl_message.length - 3); break; case HCI_CMD_INQUIRY_CANCEL: @@ -1207,7 +1152,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage( } // HCI command is finished, send a reply to command - WII_IPC_HLE_Interface::EnqueueReply(_rHCICommandMessage.m_Address); + WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request, ctrl_message.length); } // diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h index c2986ec676..c3b6ad2cc0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -43,10 +44,8 @@ public: virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_emu(); - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - - IPCCommandResult IOCtlV(u32 _CommandAddress) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void Update() override; @@ -62,31 +61,16 @@ public: void DoState(PointerWrap& p) override; private: - struct SHCICommandMessage - { - u8 bRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; - - u32 m_PayLoadAddr; - u32 m_PayLoadSize; - u32 m_Address; - }; - bdaddr_t m_ControllerBD; // this is used to trigger connecting via ACL u8 m_ScanEnable = 0; - SHCICommandMessage m_CtrlSetup; - CtrlBuffer m_HCIEndpoint; + std::unique_ptr m_CtrlSetup; + std::unique_ptr m_HCIEndpoint; + std::unique_ptr m_ACLEndpoint; std::deque m_EventQueue; - u32 m_ACLSetup; - CtrlBuffer m_ACLEndpoint; - class ACLPool { struct Packet @@ -109,7 +93,7 @@ private: void DoState(PointerWrap& p) { p.Do(m_queue); } } m_acl_pool; - u32 m_PacketCount[MAX_BBMOTES]; + u32 m_PacketCount[MAX_BBMOTES] = {}; u64 m_last_ticks = 0; // Send ACL data to a device (wiimote) @@ -138,7 +122,7 @@ private: bool SendEventLinkKeyNotification(const u8 num_to_send); // Execute HCI Message - void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage); + void ExecuteHCICommandMessage(const CtrlMessage& ctrl_message); // OGF 0x01 - Link control commands and return parameters void CommandWriteInquiryMode(const u8* input); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp index c3dfb461a7..70dca89afc 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.cpp @@ -18,6 +18,7 @@ #include "Common/Assert.h" #include "Common/ChunkFile.h" +#include "Common/CommonFuncs.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/Network.h" @@ -89,7 +90,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_real::~CWII_IPC_HLE_Device_usb_oh1_57e_305_r SaveLinkKeys(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(const IOSOpenRequest& request) { libusb_device** list; const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list); @@ -136,18 +137,18 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_addr PanicAlertT("Bluetooth passthrough mode is enabled, " "but no usable Bluetooth USB device was found. Aborting."); Core::QueueHostJob(Core::Stop); - return GetNoReply(); + return IPC_ENOENT; } StartTransferThread(); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_address, bool force) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close() { - if (!force) + if (m_handle) { libusb_release_interface(m_handle, 0); StopTransferThread(); @@ -156,10 +157,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_add } m_is_active = false; - return GetDefaultReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(const IOSIOCtlVRequest& request) { if (!m_is_wii_bt_module && s_need_reset_keys.TestAndClear()) { @@ -170,14 +170,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad WaitForHCICommandComplete(HCI_CMD_WRITE_STORED_LINK_KEY); } - const SIOCtlVBuffer cmd_buffer(command_address); - switch (cmd_buffer.Parameter) + switch (request.request) { // HCI commands to the Bluetooth adapter case USBV0_IOCTL_CTRLMSG: { - auto cmd = std::make_unique(cmd_buffer); - const u16 opcode = *reinterpret_cast(Memory::GetPointer(cmd->payload_addr)); + auto cmd = std::make_unique(request); + const u16 opcode = Common::swap16(Memory::Read_U16(cmd->payload_addr)); if (opcode == HCI_CMD_READ_BUFFER_SIZE) { m_fake_read_buffer_size_reply.Set(); @@ -220,25 +219,24 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad case USBV0_IOCTL_BLKMSG: case USBV0_IOCTL_INTRMSG: { - auto buffer = std::make_unique(cmd_buffer, command_address); - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) + auto buffer = std::make_unique(request); + if (request.request == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear()) { FakeReadBufferSizeReply(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear()) + if (request.request == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear()) { FakeVendorCommandReply(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && - m_sync_button_state == SyncButtonState::Pressed) + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::Pressed) { Core::DisplayMessage("Scanning for Wii Remotes", 2000); FakeSyncButtonPressedEvent(*buffer); return GetNoReply(); } - if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && + if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::LongPressed) { Core::DisplayMessage("Reset saved Wii Remote pairings", 2000); @@ -253,8 +251,8 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; transfer->length = buffer->m_length; transfer->timeout = TIMEOUT; - transfer->type = cmd_buffer.Parameter == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : - LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->type = request.request == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK : + LIBUSB_TRANSFER_TYPE_INTERRUPT; transfer->user_data = buffer.release(); libusb_submit_transfer(transfer); break; @@ -387,7 +385,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_real::SendHCIStoreLinkKeyCommand() return true; } -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -395,8 +393,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2; hci_event->PacketIndicator = 0x01; hci_event->Opcode = m_fake_vendor_command_reply_opcode; - ctrl.SetRetVal(sizeof(SHCIEventCommand)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request, static_cast(sizeof(SHCIEventCommand))); } // Due to how the widcomm stack which Nintendo uses is coded, we must never @@ -404,7 +401,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl // - it will cause a u8 underflow and royally screw things up. // Therefore, the reply to this command has to be faked to avoid random, weird issues // (including Wiimote disconnects and "event mismatch" warning messages). -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(CtrlBuffer& ctrl) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); auto* hci_event = reinterpret_cast(packet); @@ -421,11 +418,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const Ctr reply.num_sco_pkts = SCO_PKT_NUM; memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp)); - ctrl.SetRetVal(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp)); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + WII_IPC_HLE_Interface::EnqueueReply( + ctrl.ios_request, + static_cast(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp))); } -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuffer& ctrl, +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, const u8 size) { u8* packet = Memory::GetPointer(ctrl.m_payload_addr); @@ -433,15 +431,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuf hci_event->event = HCI_EVENT_VENDOR; hci_event->length = size; memcpy(packet + sizeof(hci_event_hdr_t), payload, size); - ctrl.SetRetVal(sizeof(hci_event_hdr_t) + size); - WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address); + WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request, + static_cast(sizeof(hci_event_hdr_t) + size)); } // When the red sync button is pressed, a HCI event is generated: // > HCI Event: Vendor (0xff) plen 1 // 08 // This causes the emulated software to perform a BT inquiry and connect to found Wiimotes. -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet"); const u8 payload[1] = {0x08}; @@ -450,7 +448,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const } // When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent. -void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl) +void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(CtrlBuffer& ctrl) { NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button held' (0x09) event packet"); const u8 payload[1] = {0x09}; @@ -580,7 +578,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer* s_showed_failed_transfer.Clear(); } - WII_IPC_HLE_Interface::EnqueueReply(cmd->address, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); } void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr) @@ -624,6 +623,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* } } - ctrl->SetRetVal(tr->actual_length); - WII_IPC_HLE_Interface::EnqueueReply(ctrl->m_cmd_address, 0, CoreTiming::FromThread::NON_CPU); + WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h index 1925fca877..6c267264cb 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h @@ -42,9 +42,9 @@ public: CWII_IPC_HLE_Device_usb_oh1_57e_305_real(u32 device_id, const std::string& device_name); ~CWII_IPC_HLE_Device_usb_oh1_57e_305_real() override; - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult Close(u32 command_address, bool force) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + void Close() override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; void DoState(PointerWrap& p) override; void UpdateSyncButtonState(bool is_held) override; @@ -80,11 +80,11 @@ private: void SendHCIResetCommand(); void SendHCIDeleteLinkKeyCommand(); bool SendHCIStoreLinkKeyCommand(); - void FakeVendorCommandReply(const CtrlBuffer& ctrl); - void FakeReadBufferSizeReply(const CtrlBuffer& ctrl); - void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size); - void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl); - void FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl); + void FakeVendorCommandReply(CtrlBuffer& ctrl); + void FakeReadBufferSizeReply(CtrlBuffer& ctrl); + void FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, u8 size); + void FakeSyncButtonPressedEvent(CtrlBuffer& ctrl); + void FakeSyncButtonHeldEvent(CtrlBuffer& ctrl); void LoadLinkKeys(); void SaveLinkKeys(); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp index e4cbd011eb..252cefadf7 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.cpp @@ -12,11 +12,11 @@ namespace Core void DisplayMessage(const std::string& message, int time_in_ms); } -IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(u32 command_address, u32 mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(const IOSOpenRequest& request) { PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb." " Passthrough mode cannot be used."); - return GetNoReply(); + return IPC_ENOENT; } void CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::DoState(PointerWrap& p) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h index 074c9cae5c..efb149496e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_stub.h @@ -16,11 +16,10 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305_stub final : public CWII_IPC_HLE_Device_usb_oh1_57e_305_base { public: - CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(u32 device_id, const std::string& device_name) + CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(const u32 device_id, const std::string& device_name) : CWII_IPC_HLE_Device_usb_oh1_57e_305_base(device_id, device_name) { } - ~CWII_IPC_HLE_Device_usb_oh1_57e_305_stub() override {} - IPCCommandResult Open(u32 command_address, u32 mode) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; void DoState(PointerWrap& p) override; }; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index ed8c3df786..c5da572139 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -38,17 +38,14 @@ CWII_IPC_HLE_Device_usb_kbd::CWII_IPC_HLE_Device_usb_kbd(u32 _DeviceID, { } -CWII_IPC_HLE_Device_usb_kbd::~CWII_IPC_HLE_Device_usb_kbd() -{ -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mode) +IOSReturnCode CWII_IPC_HLE_Device_usb_kbd::Open(const IOSOpenRequest& request) { INFO_LOG(WII_IPC_HLE, "CWII_IPC_HLE_Device_usb_kbd: Open"); IniFile ini; ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); ini.GetOrCreateSection("USB Keyboard")->Get("Layout", &m_KeyboardLayout, KBD_LAYOUT_QWERTY); + m_MessageQueue = std::queue(); for (bool& pressed : m_OldKeyBuffer) { pressed = false; @@ -58,39 +55,17 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mod // m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr)); m_is_active = true; - return GetDefaultReply(); + return IPC_SUCCESS; } -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Close(u32 _CommandAddress, bool _bForce) +IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::IOCtl(const IOSIOCtlRequest& request) { - INFO_LOG(WII_IPC_HLE, "CWII_IPC_HLE_Device_usb_kbd: Close"); - while (!m_MessageQueue.empty()) - m_MessageQueue.pop(); - m_is_active = false; - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::Write(u32 _CommandAddress) -{ - DEBUG_LOG(WII_IPC_HLE, "Ignoring write to CWII_IPC_HLE_Device_usb_kbd"); -#if defined(_DEBUG) || defined(DEBUGFAST) - DumpCommands(_CommandAddress, 10, LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); -#endif - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_kbd::IOCtl(u32 _CommandAddress) -{ - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - if (SConfig::GetInstance().m_WiiKeyboard && !Core::g_want_determinism && !m_MessageQueue.empty()) { - Memory::CopyToEmu(BufferOut, &m_MessageQueue.front(), sizeof(SMessageData)); + Memory::CopyToEmu(request.buffer_out, &m_MessageQueue.front(), sizeof(SMessageData)); m_MessageQueue.pop(); } - - Memory::Write_U32(0, _CommandAddress + 0x4); - return GetDefaultReply(); + return GetDefaultReply(IPC_SUCCESS); } bool CWII_IPC_HLE_Device_usb_kbd::IsKeyPressed(int _Key) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h index 4f0a852057..18b3efade0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h @@ -15,12 +15,9 @@ class CWII_IPC_HLE_Device_usb_kbd : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_usb_kbd(u32 _DeviceID, const std::string& _rDeviceName); - virtual ~CWII_IPC_HLE_Device_usb_kbd(); - IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override; - IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override; - IPCCommandResult Write(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IOSReturnCode Open(const IOSOpenRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; void Update() override; private: diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp index a613e39242..384e2d0154 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp @@ -12,43 +12,22 @@ CWII_IPC_HLE_Device_usb_ven::CWII_IPC_HLE_Device_usb_ven(const u32 device_id, { } -CWII_IPC_HLE_Device_usb_ven::~CWII_IPC_HLE_Device_usb_ven() +IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(const IOSIOCtlVRequest& request) { -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address) -{ - SIOCtlVBuffer command_buffer(command_address); - - INFO_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(OSHLE, " Parameter: 0x%x", command_buffer.Parameter); - INFO_LOG(OSHLE, " NumberIn: 0x%08x", command_buffer.NumberInBuffer); - INFO_LOG(OSHLE, " NumberOut: 0x%08x", command_buffer.NumberPayloadBuffer); - INFO_LOG(OSHLE, " BufferVector: 0x%08x", command_buffer.BufferVector); - DumpAsync(command_buffer.BufferVector, command_buffer.NumberInBuffer, - command_buffer.NumberPayloadBuffer); - - Memory::Write_U32(0, command_address + 4); + request.Dump(GetDeviceName()); return GetNoReply(); } -IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(const IOSIOCtlRequest& request) { - IPCCommandResult reply = GetDefaultReply(); - u32 command = Memory::Read_U32(command_address + 0x0c); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1c); + request.Log(GetDeviceName(), LogTypes::OSHLE); - INFO_LOG(OSHLE, "%s - IOCtl: %x", GetDeviceName().c_str(), command); - INFO_LOG(OSHLE, "%x:%x %x:%x", buffer_in, buffer_in_size, buffer_out, buffer_out_size); - - switch (command) + IPCCommandResult reply = GetDefaultReply(IPC_SUCCESS); + switch (request.request) { case USBV5_IOCTL_GETVERSION: - Memory::Write_U32(0x50001, buffer_out); - reply = GetDefaultReply(); + Memory::Write_U32(0x50001, request.buffer_out); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_GETDEVICECHANGE: @@ -57,48 +36,41 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address) static bool firstcall = true; if (firstcall) { - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); firstcall = false; } // num devices - Memory::Write_U32(0, command_address + 4); + reply = GetDefaultReply(0); return reply; } break; case USBV5_IOCTL_ATTACHFINISH: - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_SUSPEND_RESUME: - DEBUG_LOG(OSHLE, "Device: %i Resumed: %i", Memory::Read_U32(buffer_in), - Memory::Read_U32(buffer_in + 4)); - reply = GetDefaultReply(); + DEBUG_LOG(OSHLE, "Device: %i Resumed: %i", Memory::Read_U32(request.buffer_in), + Memory::Read_U32(request.buffer_in + 4)); + reply = GetDefaultReply(IPC_SUCCESS); break; case USBV5_IOCTL_GETDEVPARAMS: { - s32 device = Memory::Read_U32(buffer_in); - u32 unk = Memory::Read_U32(buffer_in + 4); + s32 device = Memory::Read_U32(request.buffer_in); + u32 unk = Memory::Read_U32(request.buffer_in + 4); DEBUG_LOG(OSHLE, "USBV5_IOCTL_GETDEVPARAMS device: %i unk: %i", device, unk); - Memory::Write_U32(0, buffer_out); + Memory::Write_U32(0, request.buffer_out); - reply = GetDefaultReply(); + reply = GetDefaultReply(IPC_SUCCESS); } break; default: - DEBUG_LOG(OSHLE, "%x:%x %x:%x", buffer_in, buffer_in_size, buffer_out, buffer_out_size); - break; + request.Log(GetDeviceName(), LogTypes::OSHLE, LogTypes::LDEBUG); } - - Memory::Write_U32(0, command_address + 4); return reply; } - -void CWII_IPC_HLE_Device_usb_ven::DoState(PointerWrap& p) -{ -} diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h index 612400f1e0..7cb5406483 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h @@ -10,19 +10,13 @@ #include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" -class PointerWrap; - class CWII_IPC_HLE_Device_usb_ven final : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_usb_ven(u32 device_id, const std::string& device_name); - ~CWII_IPC_HLE_Device_usb_ven() override; - - IPCCommandResult IOCtlV(u32 command_address) override; - IPCCommandResult IOCtl(u32 command_address) override; - - void DoState(PointerWrap& p) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum USBIOCtl diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp index 4fabc7200f..2d178db263 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.cpp @@ -29,17 +29,11 @@ CWII_IPC_HLE_Device_usb_wfssrv::CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, m_device_name = "msc01"; } -IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) +IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(const IOSIOCtlRequest& request) { - u32 command = Memory::Read_U32(command_address + 0xC); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - int return_error_code = IPC_SUCCESS; - switch (command) + switch (request.request) { case IOCTL_WFS_INIT: // TODO(wfs): Implement. @@ -48,56 +42,56 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) case IOCTL_WFS_DEVICE_INFO: INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_DEVICE_INFO"); - Memory::Write_U64(16ull << 30, buffer_out); // 16GB storage. - Memory::Write_U8(4, buffer_out + 8); + Memory::Write_U64(16ull << 30, request.buffer_out); // 16GB storage. + Memory::Write_U8(4, request.buffer_out + 8); break; case IOCTL_WFS_GET_DEVICE_NAME: { INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GET_DEVICE_NAME"); - Memory::Write_U8(static_cast(m_device_name.size()), buffer_out); - Memory::CopyToEmu(buffer_out + 1, m_device_name.data(), m_device_name.size()); + Memory::Write_U8(static_cast(m_device_name.size()), request.buffer_out); + Memory::CopyToEmu(request.buffer_out + 1, m_device_name.data(), m_device_name.size()); break; } case IOCTL_WFS_ATTACH_DETACH_2: // TODO(wfs): Implement. - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%d)", command); - Memory::Write_U32(1, buffer_out); - Memory::Write_U32(0, buffer_out + 4); // device id? - Memory::Write_U32(0, buffer_out + 8); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH_2(%u)", request.request); + Memory::Write_U32(1, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); // device id? + Memory::Write_U32(0, request.buffer_out + 8); break; case IOCTL_WFS_ATTACH_DETACH: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%d)", command); - Memory::Write_U32(1, buffer_out); - Memory::Write_U32(0, buffer_out + 4); - Memory::Write_U32(0, buffer_out + 8); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_ATTACH_DETACH(%u)", request.request); + Memory::Write_U32(1, request.buffer_out); + Memory::Write_U32(0, request.buffer_out + 4); + Memory::Write_U32(0, request.buffer_out + 8); return GetNoReply(); // TODO(wfs): Globbing is not really implemented, we just fake the one case // (listing /vol/*) which is required to get the installer to work. case IOCTL_WFS_GLOB_START: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%d)", command); - Memory::Memset(buffer_out, 0, buffer_out_size); - memcpy(Memory::GetPointer(buffer_out + 0x14), m_device_name.data(), m_device_name.size()); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_START(%u)", request.request); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); + Memory::CopyToEmu(request.buffer_out + 0x14, m_device_name.data(), m_device_name.size()); break; case IOCTL_WFS_GLOB_NEXT: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_NEXT(%d)", command); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_NEXT(%u)", request.request); return_error_code = WFS_EEMPTY; break; case IOCTL_WFS_GLOB_END: - INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%d)", command); - Memory::Memset(buffer_out, 0, buffer_out_size); + INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_GLOB_END(%u)", request.request); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; case IOCTL_WFS_OPEN: { - u32 mode = Memory::Read_U32(buffer_in); - u16 path_len = Memory::Read_U16(buffer_in + 0x20); - std::string path = Memory::GetString(buffer_in + 0x22, path_len); + u32 mode = Memory::Read_U32(request.buffer_in); + u16 path_len = Memory::Read_U16(request.buffer_in + 0x20); + std::string path = Memory::GetString(request.buffer_in + 0x22, path_len); u16 fd = GetNewFileDescriptor(); FileDescriptor* fd_obj = &m_fds[fd]; @@ -115,13 +109,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) } INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_OPEN(%s, %d) -> %d", path.c_str(), mode, fd); - Memory::Write_U16(fd, buffer_out + 0x14); + Memory::Write_U16(fd, request.buffer_out + 0x14); break; } case IOCTL_WFS_CLOSE: { - u16 fd = Memory::Read_U16(buffer_in + 0x4); + u16 fd = Memory::Read_U16(request.buffer_in + 0x4); INFO_LOG(WII_IPC_HLE, "IOCTL_WFS_CLOSE(%d)", fd); ReleaseFileDescriptor(fd); break; @@ -129,9 +123,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) case IOCTL_WFS_READ: { - u32 addr = Memory::Read_U32(buffer_in); - u16 fd = Memory::Read_U16(buffer_in + 0xC); - u32 size = Memory::Read_U32(buffer_in + 8); + u32 addr = Memory::Read_U32(request.buffer_in); + u16 fd = Memory::Read_U16(request.buffer_in + 0xC); + u32 size = Memory::Read_U32(request.buffer_in + 8); FileDescriptor* fd_obj = FindFileDescriptor(fd); if (fd_obj == nullptr) @@ -158,24 +152,12 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtl(u32 command_address) default: // TODO(wfs): Should be returning -3. However until we have everything // properly stubbed it's easier to simulate the methods succeeding. - WARN_LOG(WII_IPC_HLE, "%s unimplemented IOCtl(0x%08x, size_in=%08x, size_out=%08x)\n%s\n%s", - m_name.c_str(), command, buffer_in_size, buffer_out_size, - HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str(), - HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); - Memory::Memset(buffer_out, 0, buffer_out_size); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; } - Memory::Write_U32(return_error_code, command_address + 4); - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_usb_wfssrv::IOCtlV(u32 command_address) -{ - SIOCtlVBuffer command_buffer(command_address); - ERROR_LOG(WII_IPC_HLE, "IOCtlV on /dev/usb/wfssrv -- unsupported"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); - return GetDefaultReply(); + return GetDefaultReply(return_error_code); } CWII_IPC_HLE_Device_usb_wfssrv::FileDescriptor* diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h index f722bde402..5616424bd8 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_wfssrv.h @@ -23,8 +23,7 @@ class CWII_IPC_HLE_Device_usb_wfssrv : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_usb_wfssrv(u32 device_id, const std::string& device_name); - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: // WFS device name, e.g. msc01/msc02. diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp index 040ec001c0..b2497ee723 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.cpp @@ -79,28 +79,16 @@ CWII_IPC_HLE_Device_wfsi::CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::str { } -IPCCommandResult CWII_IPC_HLE_Device_wfsi::Open(u32 command_address, u32 mode) +IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(const IOSIOCtlRequest& request) { - INFO_LOG(WII_IPC_HLE, "/dev/wfsi: Open"); - return IWII_IPC_HLE_Device::Open(command_address, mode); -} - -IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) -{ - u32 command = Memory::Read_U32(command_address + 0xC); - u32 buffer_in = Memory::Read_U32(command_address + 0x10); - u32 buffer_in_size = Memory::Read_U32(command_address + 0x14); - u32 buffer_out = Memory::Read_U32(command_address + 0x18); - u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C); - u32 return_error_code = IPC_SUCCESS; - switch (command) + switch (request.request) { case IOCTL_WFSI_PREPARE_DEVICE: { - u32 tmd_addr = Memory::Read_U32(buffer_in); - u32 tmd_size = Memory::Read_U32(buffer_in + 4); + u32 tmd_addr = Memory::Read_U32(request.buffer_in); + u32 tmd_size = Memory::Read_U32(request.buffer_in + 4); INFO_LOG(WII_IPC_HLE, "IOCTL_WFSI_PREPARE_DEVICE"); @@ -135,11 +123,12 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_PREPARE_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_PREPARE_PROFILE ? "IOCTL_WFSI_PREPARE_PROFILE" : - "IOCTL_WFSI_PREPARE_CONTENT"; + const char* ioctl_name = request.request == IOCTL_WFSI_PREPARE_PROFILE ? + "IOCTL_WFSI_PREPARE_PROFILE" : + "IOCTL_WFSI_PREPARE_CONTENT"; // Initializes the IV from the index of the content in the TMD contents. - u32 content_id = Memory::Read_U32(buffer_in + 8); + u32 content_id = Memory::Read_U32(request.buffer_in + 8); TMDReader::Content content_info; if (!m_tmd.FindContentById(content_id, &content_info)) { @@ -161,12 +150,13 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_IMPORT_PROFILE: case IOCTL_WFSI_IMPORT_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_IMPORT_PROFILE ? "IOCTL_WFSI_IMPORT_PROFILE" : - "IOCTL_WFSI_IMPORT_CONTENT"; + const char* ioctl_name = request.request == IOCTL_WFSI_IMPORT_PROFILE ? + "IOCTL_WFSI_IMPORT_PROFILE" : + "IOCTL_WFSI_IMPORT_CONTENT"; - u32 content_id = Memory::Read_U32(buffer_in + 0xC); - u32 input_ptr = Memory::Read_U32(buffer_in + 0x10); - u32 input_size = Memory::Read_U32(buffer_in + 0x14); + u32 content_id = Memory::Read_U32(request.buffer_in + 0xC); + u32 input_ptr = Memory::Read_U32(request.buffer_in + 0x10); + u32 input_size = Memory::Read_U32(request.buffer_in + 0x14); INFO_LOG(WII_IPC_HLE, "%s: %08x bytes of data at %08x from content id %d", ioctl_name, content_id, input_ptr, input_size); @@ -181,7 +171,7 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_FINALIZE_PROFILE: case IOCTL_WFSI_FINALIZE_CONTENT: { - const char* ioctl_name = command == IOCTL_WFSI_FINALIZE_PROFILE ? + const char* ioctl_name = request.request == IOCTL_WFSI_FINALIZE_PROFILE ? "IOCTL_WFSI_FINALIZE_PROFILE" : "IOCTL_WFSI_FINALIZE_CONTENT"; INFO_LOG(WII_IPC_HLE, "%s", ioctl_name); @@ -225,7 +215,7 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) case IOCTL_WFSI_SET_DEVICE_NAME: INFO_LOG(WII_IPC_HLE, "IOCTL_WFSI_SET_DEVICE_NAME"); - m_device_name = Memory::GetString(buffer_in); + m_device_name = Memory::GetString(request.buffer_in); break; case IOCTL_WFSI_APPLY_TITLE_PROFILE: @@ -243,21 +233,10 @@ IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtl(u32 command_address) // TODO(wfs): Should be returning an error. However until we have // everything properly stubbed it's easier to simulate the methods // succeeding. - WARN_LOG(WII_IPC_HLE, "%s unimplemented IOCtl(0x%08x, size_in=%08x, size_out=%08x)\n%s\n%s", - m_name.c_str(), command, buffer_in_size, buffer_out_size, - HexDump(Memory::GetPointer(buffer_in), buffer_in_size).c_str(), - HexDump(Memory::GetPointer(buffer_out), buffer_out_size).c_str()); - Memory::Memset(buffer_out, 0, buffer_out_size); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HLE, LogTypes::LWARNING); + Memory::Memset(request.buffer_out, 0, request.buffer_out_size); break; } - Memory::Write_U32(return_error_code, command_address + 4); - return GetDefaultReply(); -} - -IPCCommandResult CWII_IPC_HLE_Device_wfsi::IOCtlV(u32 command_address) -{ - ERROR_LOG(WII_IPC_HLE, "IOCtlV on /dev/wfsi -- unsupported"); - Memory::Write_U32(IPC_EINVAL, command_address + 4); - return GetDefaultReply(); + return GetDefaultReply(return_error_code); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h index d5afa62a3a..68cffd0eee 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_wfsi.h @@ -34,9 +34,7 @@ class CWII_IPC_HLE_Device_wfsi : public IWII_IPC_HLE_Device public: CWII_IPC_HLE_Device_wfsi(u32 device_id, const std::string& device_name); - IPCCommandResult Open(u32 command_address, u32 mode) override; - IPCCommandResult IOCtl(u32 command_address) override; - IPCCommandResult IOCtlV(u32 command_address) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: std::string m_device_name; diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.cpp b/Source/Core/Core/IPC_HLE/WII_Socket.cpp index 167d30d558..233b39d6d9 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.cpp +++ b/Source/Core/Core/IPC_HLE/WII_Socket.cpp @@ -187,28 +187,23 @@ void WiiSocket::Update(bool read, bool write, bool except) { s32 ReturnValue = 0; bool forceNonBlock = false; - IPCCommandType ct = static_cast(Memory::Read_U32(it->_CommandAddress)); + IPCCommandType ct = it->request.command; if (!it->is_ssl && ct == IPC_CMD_IOCTL) { - u32 BufferIn = Memory::Read_U32(it->_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(it->_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(it->_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(it->_CommandAddress + 0x1C); - + IOSIOCtlRequest ioctl{it->request.address}; switch (it->net_type) { case IOCTL_SO_FCNTL: { - u32 cmd = Memory::Read_U32(BufferIn + 4); - u32 arg = Memory::Read_U32(BufferIn + 8); + u32 cmd = Memory::Read_U32(ioctl.buffer_in + 4); + u32 arg = Memory::Read_U32(ioctl.buffer_in + 8); ReturnValue = FCntl(cmd, arg); break; } case IOCTL_SO_BIND: { - // u32 has_addr = Memory::Read_U32(BufferIn + 0x04); sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_in + 8); WiiSockMan::Convert(*wii_name, local_name); int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name)); @@ -220,9 +215,8 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_CONNECT: { - // u32 has_addr = Memory::Read_U32(BufferIn + 0x04); sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_in + 8); WiiSockMan::Convert(*wii_name, local_name); int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name)); @@ -234,10 +228,10 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_ACCEPT: { - if (BufferOutSize > 0) + if (ioctl.buffer_out_size > 0) { sockaddr_in local_name; - WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferOut); + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(ioctl.buffer_out); WiiSockMan::Convert(*wii_name, local_name); socklen_t addrlen = sizeof(sockaddr_in); @@ -254,10 +248,7 @@ void WiiSocket::Update(bool read, bool write, bool except) WiiSockMan::GetInstance().AddSocket(ReturnValue); - INFO_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - + ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::WII_IPC_NET); break; } default: @@ -275,34 +266,34 @@ void WiiSocket::Update(bool read, bool write, bool except) } else if (ct == IPC_CMD_IOCTLV) { - SIOCtlVBuffer CommandBuffer(it->_CommandAddress); + IOSIOCtlVRequest ioctlv{it->request.address}; u32 BufferIn = 0, BufferIn2 = 0; u32 BufferInSize = 0, BufferInSize2 = 0; u32 BufferOut = 0, BufferOut2 = 0; u32 BufferOutSize = 0, BufferOutSize2 = 0; - if (CommandBuffer.InBuffer.size() > 0) + if (ioctlv.in_vectors.size() > 0) { - BufferIn = CommandBuffer.InBuffer.at(0).m_Address; - BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; + BufferIn = ioctlv.in_vectors.at(0).address; + BufferInSize = ioctlv.in_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 0) + if (ioctlv.io_vectors.size() > 0) { - BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; - BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; + BufferOut = ioctlv.io_vectors.at(0).address; + BufferOutSize = ioctlv.io_vectors.at(0).size; } - if (CommandBuffer.PayloadBuffer.size() > 1) + if (ioctlv.io_vectors.size() > 1) { - BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; - BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size; + BufferOut2 = ioctlv.io_vectors.at(1).address; + BufferOutSize2 = ioctlv.io_vectors.at(1).size; } - if (CommandBuffer.InBuffer.size() > 1) + if (ioctlv.in_vectors.size() > 1) { - BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; - BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; + BufferIn2 = ioctlv.in_vectors.at(1).address; + BufferInSize2 = ioctlv.in_vectors.at(1).size; } if (it->is_ssl) @@ -576,8 +567,7 @@ void WiiSocket::Update(bool read, bool write, bool except) "IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d", fd, it->is_ssl ? (int)it->ssl_type : (int)it->net_type, ReturnValue, nonBlock, forceNonBlock); - Memory::Write_U32(ReturnValue, it->_CommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(it->_CommandAddress); + WII_IPC_HLE_Interface::EnqueueReply(it->request, ReturnValue); it = pending_sockops.erase(it); } else @@ -587,16 +577,16 @@ void WiiSocket::Update(bool read, bool write, bool except) } } -void WiiSocket::DoSock(u32 _CommandAddress, NET_IOCTL type) +void WiiSocket::DoSock(IOSRequest request, NET_IOCTL type) { - sockop so = {_CommandAddress, false}; + sockop so = {request, false}; so.net_type = type; pending_sockops.push_back(so); } -void WiiSocket::DoSock(u32 _CommandAddress, SSL_IOCTL type) +void WiiSocket::DoSock(IOSRequest request, SSL_IOCTL type) { - sockop so = {_CommandAddress, true}; + sockop so = {request, true}; so.ssl_type = type; pending_sockops.push_back(so); } diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.h b/Source/Core/Core/IPC_HLE/WII_Socket.h index 93076576a1..793c02d1f2 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.h +++ b/Source/Core/Core/IPC_HLE/WII_Socket.h @@ -172,7 +172,7 @@ class WiiSocket { struct sockop { - u32 _CommandAddress; + IOSRequest request; bool is_ssl; union { @@ -191,8 +191,8 @@ private: s32 CloseFd(); s32 FCntl(u32 cmd, u32 arg); - void DoSock(u32 _CommandAddress, NET_IOCTL type); - void DoSock(u32 _CommandAddress, SSL_IOCTL type); + void DoSock(IOSRequest request, NET_IOCTL type); + void DoSock(IOSRequest request, SSL_IOCTL type); void Update(bool read, bool write, bool except); bool IsValid() const { return fd >= 0; } public: @@ -223,19 +223,18 @@ public: void SetLastNetError(s32 error) { errno_last = error; } void Clean() { WiiSockets.clear(); } template - void DoSock(s32 sock, u32 CommandAddress, T type) + void DoSock(s32 sock, const IOSRequest& request, T type) { auto socket_entry = WiiSockets.find(sock); if (socket_entry == WiiSockets.end()) { - ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, CommandAddress, - type); - Memory::Write_U32(-SO_EBADF, CommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(CommandAddress); + ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, + request.address, type); + WII_IPC_HLE_Interface::EnqueueReply(request, -SO_EBADF); } else { - socket_entry->second.DoSock(CommandAddress, type); + socket_entry->second.DoSock(request, type); } } diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 6d84534de5..428ccb339e 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 68; // Last changed in PR 4638 +static const u32 STATE_VERSION = 69; // Last changed in PR 4661 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,