From 0e278ebe21cb8eccc3cad26d55ca79a80524548d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Mon, 11 May 2020 14:09:32 +0200 Subject: [PATCH] Implemented UsbControlTransfer --- sys/Ds4Pdo.cpp | 28 +++++++++++++++++++++++++ sys/Ds4Pdo.hpp | 1 + sys/EmulationTargetPDO.cpp | 37 +------------------------------- sys/EmulationTargetPDO.hpp | 2 ++ sys/XusbPdo.cpp | 43 ++++++++++++++++++++++++++++++++++++++ sys/XusbPdo.hpp | 1 + 6 files changed, 76 insertions(+), 36 deletions(-) diff --git a/sys/Ds4Pdo.cpp b/sys/Ds4Pdo.cpp index dc51b6f..1ec122c 100644 --- a/sys/Ds4Pdo.cpp +++ b/sys/Ds4Pdo.cpp @@ -1033,6 +1033,34 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbBulkOrInterruptTransfer(_UR return status; } +NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbControlTransfer(PURB Urb) +{ + NTSTATUS status; + + switch (Urb->UrbControlTransfer.SetupPacket[6]) + { + case 0x14: + // + // This is some weird USB 1.0 condition and _must fail_ + // + Urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; + status = STATUS_UNSUCCESSFUL; + break; + case 0x08: + // + // This is some weird USB 1.0 condition and _must fail_ + // + Urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; + status = STATUS_UNSUCCESSFUL; + break; + default: + status = STATUS_SUCCESS; + break; + } + + return status; +} + VOID ViGEm::Bus::Targets::EmulationTargetDS4::PendingUsbRequestsTimerFunc( _In_ WDFTIMER Timer ) diff --git a/sys/Ds4Pdo.hpp b/sys/Ds4Pdo.hpp index d9c52ef..4f6c85a 100644 --- a/sys/Ds4Pdo.hpp +++ b/sys/Ds4Pdo.hpp @@ -44,6 +44,7 @@ namespace ViGEm::Bus::Targets NTSTATUS UsbSelectInterface(PURB Urb) override; NTSTATUS UsbGetStringDescriptorType(PURB Urb) override; NTSTATUS UsbBulkOrInterruptTransfer(_URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request) override; + NTSTATUS UsbControlTransfer(PURB Urb) override; private: static PCWSTR _deviceDescription; diff --git a/sys/EmulationTargetPDO.cpp b/sys/EmulationTargetPDO.cpp index e16bdef..87568a0 100644 --- a/sys/EmulationTargetPDO.cpp +++ b/sys/EmulationTargetPDO.cpp @@ -483,42 +483,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl( TRACE_BUSPDO, ">> >> URB_FUNCTION_CONTROL_TRANSFER"); - //switch (urb->UrbControlTransfer.SetupPacket[6]) - //{ - //case 0x04: - // if (pdoData->TargetType == Xbox360Wired) - // { - // pXusbData = XusbGetData(hDevice); - // blobBuffer = WdfMemoryGetBuffer(pXusbData->InterruptBlobStorage, NULL); - // // - // // Xenon magic - // // - // RtlCopyMemory( - // urb->UrbControlTransfer.TransferBuffer, - // &blobBuffer[XUSB_BLOB_07_OFFSET], - // 0x04 - // ); - // status = STATUS_SUCCESS; - // } - // break; - //case 0x14: - // // - // // This is some weird USB 1.0 condition and _must fail_ - // // - // urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; - // status = STATUS_UNSUCCESSFUL; - // break; - //case 0x08: - // // - // // This is some weird USB 1.0 condition and _must fail_ - // // - // urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; - // status = STATUS_UNSUCCESSFUL; - // break; - //default: - // status = STATUS_SUCCESS; - // break; - //} + status = ctx->Target->UsbControlTransfer(urb); break; diff --git a/sys/EmulationTargetPDO.hpp b/sys/EmulationTargetPDO.hpp index be2323c..617bf02 100644 --- a/sys/EmulationTargetPDO.hpp +++ b/sys/EmulationTargetPDO.hpp @@ -70,6 +70,8 @@ namespace ViGEm::Bus::Core virtual NTSTATUS UsbBulkOrInterruptTransfer(struct _URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request) = 0; + virtual NTSTATUS UsbControlTransfer(PURB Urb) = 0; + protected: static const ULONG _maxHardwareIdLength = 0xFF; diff --git a/sys/XusbPdo.cpp b/sys/XusbPdo.cpp index 0b23596..cae58fc 100644 --- a/sys/XusbPdo.cpp +++ b/sys/XusbPdo.cpp @@ -917,3 +917,46 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U return status; } + +NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbControlTransfer(PURB Urb) +{ + NTSTATUS status; + PUCHAR blobBuffer; + + switch (Urb->UrbControlTransfer.SetupPacket[6]) + { + case 0x04: + + blobBuffer = (PUCHAR)WdfMemoryGetBuffer(this->InterruptBlobStorage, NULL); + // + // Xenon magic + // + RtlCopyMemory( + Urb->UrbControlTransfer.TransferBuffer, + &blobBuffer[XUSB_BLOB_07_OFFSET], + 0x04 + ); + status = STATUS_SUCCESS; + + break; + case 0x14: + // + // This is some weird USB 1.0 condition and _must fail_ + // + Urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; + status = STATUS_UNSUCCESSFUL; + break; + case 0x08: + // + // This is some weird USB 1.0 condition and _must fail_ + // + Urb->UrbControlTransfer.Hdr.Status = USBD_STATUS_STALL_PID; + status = STATUS_UNSUCCESSFUL; + break; + default: + status = STATUS_SUCCESS; + break; + } + + return status; +} diff --git a/sys/XusbPdo.hpp b/sys/XusbPdo.hpp index af211ed..31453be 100644 --- a/sys/XusbPdo.hpp +++ b/sys/XusbPdo.hpp @@ -52,6 +52,7 @@ namespace ViGEm::Bus::Targets NTSTATUS UsbSelectInterface(PURB Urb) override; NTSTATUS UsbGetStringDescriptorType(PURB Urb) override; NTSTATUS UsbBulkOrInterruptTransfer(_URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request) override; + NTSTATUS UsbControlTransfer(PURB Urb) override; private: static PCWSTR _deviceDescription;