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();
|
m_fake_read_buffer_size_reply.Set();
|
||||||
return GetNoReply();
|
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)
|
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
|
// 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);
|
FakeReadBufferSizeReply(*buffer);
|
||||||
return GetNoReply();
|
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 &&
|
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG &&
|
||||||
m_sync_button_state == SyncButtonState::Pressed)
|
m_sync_button_state == SyncButtonState::Pressed)
|
||||||
{
|
{
|
||||||
|
@ -364,6 +375,18 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_real::SendHCIStoreLinkKeyCommand()
|
||||||
return true;
|
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
|
// 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
|
// let the stack think the controller is buffering more than 10 data packets
|
||||||
// - it will cause a u8 underflow and royally screw things up.
|
// - it will cause a u8 underflow and royally screw things up.
|
||||||
|
|
|
@ -68,8 +68,10 @@ private:
|
||||||
Common::Flag m_thread_running;
|
Common::Flag m_thread_running;
|
||||||
std::thread m_thread;
|
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_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;
|
bool m_is_wii_bt_module = false;
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ private:
|
||||||
void SendHCIResetCommand();
|
void SendHCIResetCommand();
|
||||||
void SendHCIDeleteLinkKeyCommand();
|
void SendHCIDeleteLinkKeyCommand();
|
||||||
bool SendHCIStoreLinkKeyCommand();
|
bool SendHCIStoreLinkKeyCommand();
|
||||||
|
void FakeVendorCommandReply(const CtrlBuffer& ctrl);
|
||||||
void FakeReadBufferSizeReply(const CtrlBuffer& ctrl);
|
void FakeReadBufferSizeReply(const CtrlBuffer& ctrl);
|
||||||
void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size);
|
void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size);
|
||||||
void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl);
|
void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl);
|
||||||
|
|
Loading…
Reference in New Issue