From 7c1936aff109e7860dd4b619c88b0e1ed78eb09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Mon, 11 May 2020 00:06:35 +0200 Subject: [PATCH] Porting USB functions --- sys/Ds4Pdo.cpp | 14 +++++++++++++- sys/Ds4Pdo.hpp | 2 +- sys/EmulationTargetPDO.cpp | 29 +++++++++++++++++++++++++++++ sys/EmulationTargetPDO.hpp | 12 +++++++++--- sys/XusbPdo.cpp | 14 +++++++++++++- sys/XusbPdo.hpp | 2 +- 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/sys/Ds4Pdo.cpp b/sys/Ds4Pdo.cpp index bf34389..4c93eaa 100644 --- a/sys/Ds4Pdo.cpp +++ b/sys/Ds4Pdo.cpp @@ -397,8 +397,18 @@ VOID ViGEm::Bus::Targets::EmulationTargetDS4::GetDeviceDescriptorType(PUSB_DEVIC pDescriptor->bNumConfigurations = 0x01; } -VOID ViGEm::Bus::Targets::EmulationTargetDS4::SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo) +NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::SelectConfiguration(PURB Urb) { + if (Urb->UrbHeader.Length < DS4_CONFIGURATION_SIZE) + { + TraceEvents(TRACE_LEVEL_WARNING, + TRACE_USBPDO, + ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Invalid ConfigurationDescriptor"); + return STATUS_INVALID_PARAMETER; + } + + PUSBD_INTERFACE_INFORMATION pInfo = &Urb->UrbSelectConfiguration.Interface; + TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DS4, ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d", @@ -428,6 +438,8 @@ VOID ViGEm::Bus::Targets::EmulationTargetDS4::SelectConfiguration(PUSBD_INTERFAC pInfo->Pipes[1].PipeType = (USBD_PIPE_TYPE)0x03; pInfo->Pipes[1].PipeHandle = (USBD_PIPE_HANDLE)0xFFFF0003; pInfo->Pipes[1].PipeFlags = 0x00; + + return STATUS_SUCCESS; } VOID ViGEm::Bus::Targets::EmulationTargetDS4::PendingUsbRequestsTimerFunc( diff --git a/sys/Ds4Pdo.hpp b/sys/Ds4Pdo.hpp index 69f85be..8dc7d8a 100644 --- a/sys/Ds4Pdo.hpp +++ b/sys/Ds4Pdo.hpp @@ -26,7 +26,7 @@ namespace ViGEm::Bus::Targets VOID GetDeviceDescriptorType(PUSB_DEVICE_DESCRIPTOR pDescriptor) override; - VOID SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo) override; + NTSTATUS SelectConfiguration(PURB Urb) override; private: static PCWSTR _deviceDescription; diff --git a/sys/EmulationTargetPDO.cpp b/sys/EmulationTargetPDO.cpp index b5c6178..407c01b 100644 --- a/sys/EmulationTargetPDO.cpp +++ b/sys/EmulationTargetPDO.cpp @@ -4,6 +4,7 @@ #include "EmulationTargetPDO.tmh" #define NTSTRSAFE_LIB #include +#include #include @@ -367,8 +368,36 @@ VOID USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbGetUSBDIVersion(IN PVO #pragma endregion +void ViGEm::Bus::Core::EmulationTargetPDO::UsbAbortPipe() +{ + this->AbortPipe(); + + // Higher driver shutting down, emptying PDOs queues + WdfIoQueuePurge(this->PendingUsbInRequests, NULL, NULL); + WdfIoQueuePurge(this->PendingNotificationRequests, NULL, NULL); +} + +NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::UsbSelectConfiguration(PURB Urb) +{ + TraceEvents(TRACE_LEVEL_VERBOSE, + TRACE_USBPDO, + ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: TotalLength %d", + Urb->UrbHeader.Length); + + if (Urb->UrbHeader.Length == sizeof(struct _URB_SELECT_CONFIGURATION)) + { + TraceEvents(TRACE_LEVEL_VERBOSE, + TRACE_USBPDO, + ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: NULL ConfigurationDescriptor"); + return STATUS_SUCCESS; + } + + return this->SelectConfiguration(Urb); +} + ViGEm::Bus::Core::EmulationTargetPDO::EmulationTargetPDO(USHORT VID, USHORT PID) : VendorId(VID), ProductId(PID) { + KeInitializeEvent(&this->PdoBootNotificationEvent, NotificationEvent, FALSE); } NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EvtDevicePrepareHardware( diff --git a/sys/EmulationTargetPDO.hpp b/sys/EmulationTargetPDO.hpp index 86b2c75..f13a620 100644 --- a/sys/EmulationTargetPDO.hpp +++ b/sys/EmulationTargetPDO.hpp @@ -41,9 +41,7 @@ namespace ViGEm::Bus::Core virtual VOID GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length) = 0; virtual VOID GetDeviceDescriptorType(PUSB_DEVICE_DESCRIPTOR pDescriptor) = 0; - - virtual VOID SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo) = 0; - + NTSTATUS CreateDevice(_In_ WDFDEVICE Device, _In_ PWDFDEVICE_INIT DeviceInit, _In_ PPDO_IDENTIFICATION_DESCRIPTION Description); @@ -56,6 +54,10 @@ namespace ViGEm::Bus::Core { return (other.SerialNo == this->SerialNo); } + + NTSTATUS UsbSelectConfiguration(PURB Urb); + + void UsbAbortPipe(); protected: static const ULONG _maxHardwareIdLength = 0xFF; @@ -88,6 +90,10 @@ namespace ViGEm::Bus::Core static const int MAX_INSTANCE_ID_LEN = 80; + virtual NTSTATUS SelectConfiguration(PURB Urb) = 0; + + virtual void AbortPipe() = 0; + // // Unique serial number of the device on the bus // diff --git a/sys/XusbPdo.cpp b/sys/XusbPdo.cpp index af2d221..0c826bc 100644 --- a/sys/XusbPdo.cpp +++ b/sys/XusbPdo.cpp @@ -464,8 +464,18 @@ VOID ViGEm::Bus::Targets::EmulationTargetXUSB::GetDeviceDescriptorType(PUSB_DEVI pDescriptor->bNumConfigurations = 0x01; } -VOID ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo) +NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PURB Urb) { + if (Urb->UrbHeader.Length < XUSB_CONFIGURATION_SIZE) + { + TraceEvents(TRACE_LEVEL_WARNING, + TRACE_USBPDO, + ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Invalid ConfigurationDescriptor"); + return STATUS_INVALID_PARAMETER; + } + + PUSBD_INTERFACE_INFORMATION pInfo = &Urb->UrbSelectConfiguration.Interface; + TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XUSB, ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d", @@ -583,4 +593,6 @@ VOID ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PUSBD_INTERFA pInfo->Protocol = 0x13; pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)0xFFFF0000; + + return STATUS_SUCCESS; } diff --git a/sys/XusbPdo.hpp b/sys/XusbPdo.hpp index 263ae8f..3570106 100644 --- a/sys/XusbPdo.hpp +++ b/sys/XusbPdo.hpp @@ -33,7 +33,7 @@ namespace ViGEm::Bus::Targets VOID GetDeviceDescriptorType(PUSB_DEVICE_DESCRIPTOR pDescriptor) override; - VOID SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo) override; + NTSTATUS SelectConfiguration(PURB Urb) override; private: static PCWSTR _deviceDescription;