IPC_HLE/57e_305: Fake vendor-specific command replies
Homebrew programs seem to rely on getting a reply to the vendor specific commands, without which Bluetooth initialisation will never complete. This vendor-specific command is typically used to patch the Wii's Bluetooth module, so the replies are only faked when the passed through adapter is not a Wii Bluetooth module.
This commit is contained in:
parent
5b50b1e1aa
commit
b91095a9fc
|
@ -171,6 +171,12 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
|
|||
m_fake_read_buffer_size_reply.Set();
|
||||
return GetNoReply();
|
||||
}
|
||||
if (!m_is_wii_bt_module && (opcode == 0xFC4C || opcode == 0xFC4F))
|
||||
{
|
||||
m_fake_vendor_command_reply.Set();
|
||||
m_fake_vendor_command_reply_opcode = opcode;
|
||||
return GetNoReply();
|
||||
}
|
||||
if (opcode == HCI_CMD_DELETE_STORED_LINK_KEY)
|
||||
{
|
||||
// Delete link key(s) from our own link key storage when the game tells the adapter to
|
||||
|
@ -208,6 +214,11 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
|
|||
FakeReadBufferSizeReply(*buffer);
|
||||
return GetNoReply();
|
||||
}
|
||||
if (cmd_buffer.Parameter == 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)
|
||||
{
|
||||
|
@ -364,6 +375,18 @@ 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)
|
||||
{
|
||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
||||
hci_event->EventType = HCI_EVENT_COMMAND_COMPL;
|
||||
hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2;
|
||||
hci_event->PacketIndicator = 0x01;
|
||||
hci_event->Opcode = m_fake_vendor_command_reply_opcode;
|
||||
ctrl.SetRetVal(sizeof(SHCIEventCommand));
|
||||
EnqueueReply(ctrl.m_cmd_address);
|
||||
}
|
||||
|
||||
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
||||
// let the stack think the controller is buffering more than 10 data packets
|
||||
// - it will cause a u8 underflow and royally screw things up.
|
||||
|
|
|
@ -68,8 +68,10 @@ private:
|
|||
Common::Flag m_thread_running;
|
||||
std::thread m_thread;
|
||||
|
||||
// Set when we received a command to read the buffer size, and we need to fake a reply
|
||||
// Set when we received a command to which we need to fake a reply
|
||||
Common::Flag m_fake_read_buffer_size_reply;
|
||||
Common::Flag m_fake_vendor_command_reply;
|
||||
u16 m_fake_vendor_command_reply_opcode;
|
||||
|
||||
bool m_is_wii_bt_module = false;
|
||||
|
||||
|
@ -77,6 +79,7 @@ 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);
|
||||
|
|
Loading…
Reference in New Issue