Porting over common USB logic

This commit is contained in:
Benjamin Höglinger-Stelzer
2020-05-10 22:57:05 +02:00
parent 027ff95b78
commit 6f228df7b2
7 changed files with 461 additions and 80 deletions

View File

@@ -27,7 +27,6 @@
#pragma once
EXTERN_C_START
//
// Used to identify children in the device list of the bus.
@@ -196,4 +195,3 @@ typedef struct _FDO_PLUGIN_REQUEST_DATA
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_PLUGIN_REQUEST_DATA, PluginRequestGetData)
EXTERN_C_END

View File

@@ -5,12 +5,14 @@
#include <ntstrsafe.h>
#include <hidclass.h>
#include "Ds4.h"
PCWSTR ViGEm::Bus::Targets::EmulationTargetDS4::_deviceDescription = L"Virtual DualShock 4 Controller";
ViGEm::Bus::Targets::EmulationTargetDS4::EmulationTargetDS4() : EmulationTargetPDO(0x054C, 0x05C4)
{
TargetType = DualShock4Wired;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareDevice(PWDFDEVICE_INIT DeviceInit,
@@ -97,14 +99,14 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareDevice(PWDFDEVICE_INIT
return STATUS_SUCCESS;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareHardware(WDFDEVICE Device)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareHardware()
{
WDF_QUERY_INTERFACE_CONFIG ifaceCfg;
INTERFACE devinterfaceHid;
devinterfaceHid.Size = sizeof(INTERFACE);
devinterfaceHid.Version = 1;
devinterfaceHid.Context = (PVOID)Device;
devinterfaceHid.Context = static_cast<PVOID>(this->PdoDevice);
devinterfaceHid.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
devinterfaceHid.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
@@ -117,7 +119,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareHardware(WDFDEVICE Devi
NULL
);
NTSTATUS status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
NTSTATUS status = WdfDeviceAddQueryInterface(this->PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
@@ -150,7 +152,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PrepareHardware(WDFDEVICE Devi
return STATUS_SUCCESS;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::InitContext(WDFDEVICE Device)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::InitContext()
{
NTSTATUS status;
@@ -167,7 +169,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::InitContext(WDFDEVICE Device)
WDF_OBJECT_ATTRIBUTES_INIT(&timerAttribs);
// PDO is parent
timerAttribs.ParentObject = Device;
timerAttribs.ParentObject = this->PdoDevice;
// Create timer
status = WdfTimerCreate(
@@ -433,5 +435,38 @@ VOID ViGEm::Bus::Targets::EmulationTargetDS4::PendingUsbRequestsTimerFunc(
_In_ WDFTIMER Timer
)
{
UNREFERENCED_PARAMETER(Timer);
auto ctx = reinterpret_cast<EmulationTargetDS4*>(Core::EmulationTargetPdoGetContext(WdfTimerGetParentObject(Timer)));
WDFREQUEST usbRequest;
PIRP pendingIrp;
PIO_STACK_LOCATION irpStack;
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DS4, "%!FUNC! Entry");
// Get pending USB request
NTSTATUS status = WdfIoQueueRetrieveNextRequest(ctx->PendingUsbInRequests, &usbRequest);
if (NT_SUCCESS(status))
{
// Get pending IRP
pendingIrp = WdfRequestWdmGetIrp(usbRequest);
irpStack = IoGetCurrentIrpStackLocation(pendingIrp);
// Get USB request block
PURB urb = (PURB)irpStack->Parameters.Others.Argument1;
// Get transfer buffer
PUCHAR Buffer = (PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer;
// Set buffer length to report size
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DS4_REPORT_SIZE;
// Copy cached report to transfer buffer
if (Buffer)
RtlCopyBytes(Buffer, ctx->Report, DS4_REPORT_SIZE);
// Complete pending request
WdfRequestComplete(usbRequest, status);
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DS4, "%!FUNC! Exit with status %!STATUS!", status);
}

View File

@@ -18,9 +18,9 @@ namespace ViGEm::Bus::Targets
PUNICODE_STRING DeviceId,
PUNICODE_STRING DeviceDescription) override;
NTSTATUS PrepareHardware(WDFDEVICE Device) override;
NTSTATUS PrepareHardware() override;
NTSTATUS InitContext(WDFDEVICE Device) override;
NTSTATUS InitContext() override;
VOID GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length) override;
@@ -87,14 +87,4 @@ namespace ViGEm::Bus::Targets
static EVT_WDF_TIMER PendingUsbRequestsTimerFunc;
};
//
// DS4-specific device context data.
//
typedef struct _DS4_PDO_CONTEXT
{
EmulationTargetDS4* Context;
} DS4_PDO_CONTEXT, *PDS4_PDO_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DS4_PDO_CONTEXT, Ds4PdoGetContext)
}

View File

@@ -1,7 +1,305 @@
#include "EmulationTargetPDO.hpp"
#include "CRTCPP.hpp"
#include "trace.h"
#include "EmulationTargetPDO.tmh"
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <usbiodef.h>
PCWSTR ViGEm::Bus::Core::EmulationTargetPDO::_deviceLocation = L"Virtual Gamepad Emulation Bus";
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::CreateDevice(WDFDEVICE Device, PWDFDEVICE_INIT DeviceInit, PPDO_IDENTIFICATION_DESCRIPTION Description)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
WDF_DEVICE_POWER_CAPABILITIES powerCaps;
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_OBJECT_ATTRIBUTES pdoAttributes;
WDF_IO_QUEUE_CONFIG defaultPdoQueueConfig;
WDFQUEUE defaultPdoQueue;
UNICODE_STRING deviceDescription;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_IO_QUEUE_CONFIG usbInQueueConfig;
WDF_IO_QUEUE_CONFIG notificationsQueueConfig;
DECLARE_CONST_UNICODE_STRING(deviceLocation, L"Virtual Gamepad Emulation Bus");
DECLARE_UNICODE_STRING_SIZE(buffer, MAX_INSTANCE_ID_LEN);
// reserve space for device id
DECLARE_UNICODE_STRING_SIZE(deviceId, MAX_INSTANCE_ID_LEN);
UNREFERENCED_PARAMETER(Description);
UNREFERENCED_PARAMETER(Device);
PAGED_CODE();
// set device type
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
// Bus is power policy owner
WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);
do
{
#pragma region Enter RAW device mode
status = WdfPdoInitAssignRawDevice(DeviceInit, &GUID_DEVCLASS_VIGEM_RAWPDO);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfPdoInitAssignRawDevice failed with status %!STATUS!",
status);
break;
}
WdfDeviceInitSetCharacteristics(DeviceInit, FILE_AUTOGENERATED_DEVICE_NAME, TRUE);
status = WdfDeviceInitAssignSDDLString(DeviceInit, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfDeviceInitAssignSDDLString failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Prepare PDO
status = this->PrepareDevice(DeviceInit, &deviceId, &deviceDescription);
if (!NT_SUCCESS(status))
break;
// set device id
status = WdfPdoInitAssignDeviceID(DeviceInit, &deviceId);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfPdoInitAssignDeviceID failed with status %!STATUS!",
status);
break;
}
// prepare instance id
status = RtlUnicodeStringPrintf(&buffer, L"%02d", this->SerialNo);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"RtlUnicodeStringPrintf failed with status %!STATUS!",
status);
break;
}
// set instance id
status = WdfPdoInitAssignInstanceID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfPdoInitAssignInstanceID failed with status %!STATUS!",
status);
break;
}
// set device description (for English operating systems)
status = WdfPdoInitAddDeviceText(DeviceInit, &deviceDescription, &deviceLocation, 0x409);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfPdoInitAddDeviceText failed with status %!STATUS!",
status);
break;
}
// default locale is English
// TODO: add more locales
WdfPdoInitSetDefaultLocale(DeviceInit, 0x409);
#pragma region PNP/Power event callbacks
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
#pragma endregion
// NOTE: not utilized at the moment
WdfPdoInitAllowForwardingRequestToParent(DeviceInit);
#pragma endregion
#pragma region Create PDO
// Add common device data context
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, EMULATION_TARGET_PDO_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &pdoAttributes, &this->PdoDevice);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfDeviceCreate failed with status %!STATUS!",
status);
break;
}
TraceEvents(TRACE_LEVEL_VERBOSE,
TRACE_BUSPDO,
"Created PDO 0x%p",
this->PdoDevice);
#pragma endregion
#pragma region Expose USB Interface
status = WdfDeviceCreateDeviceInterface(
Device,
const_cast<LPGUID>(&GUID_DEVINTERFACE_USB_DEVICE),
NULL
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfDeviceCreateDeviceInterface failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Set PDO contexts
status = this->InitContext();
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"Couldn't initialize additional contexts: %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Create Queues & Locks
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = this->PdoDevice;
// Create and assign queue for incoming interrupt transfer
WDF_IO_QUEUE_CONFIG_INIT(&usbInQueueConfig, WdfIoQueueDispatchManual);
status = WdfIoQueueCreate(
this->PdoDevice,
&usbInQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&this->PendingUsbInRequests
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfIoQueueCreate (PendingUsbInRequests) failed with status %!STATUS!",
status);
break;
}
// Create and assign queue for user-land notification requests
WDF_IO_QUEUE_CONFIG_INIT(&notificationsQueueConfig, WdfIoQueueDispatchManual);
status = WdfIoQueueCreate(
Device,
&notificationsQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&this->PendingNotificationRequests
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfIoQueueCreate (PendingNotificationRequests) failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Default I/O queue setup
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&defaultPdoQueueConfig, WdfIoQueueDispatchParallel);
defaultPdoQueueConfig.EvtIoInternalDeviceControl = EvtIoInternalDeviceControl;
status = WdfIoQueueCreate(
this->PdoDevice,
&defaultPdoQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&defaultPdoQueue
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfIoQueueCreate (Default) failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region PNP capabilities
WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
pnpCaps.Removable = WdfTrue;
pnpCaps.EjectSupported = WdfTrue;
pnpCaps.SurpriseRemovalOK = WdfTrue;
pnpCaps.Address = this->SerialNo;
pnpCaps.UINumber = this->SerialNo;
WdfDeviceSetPnpCapabilities(this->PdoDevice, &pnpCaps);
#pragma endregion
#pragma region Power capabilities
WDF_DEVICE_POWER_CAPABILITIES_INIT(&powerCaps);
powerCaps.DeviceD1 = WdfTrue;
powerCaps.WakeFromD1 = WdfTrue;
powerCaps.DeviceWake = PowerDeviceD1;
powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0;
powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
WdfDeviceSetPowerCapabilities(this->PdoDevice, &powerCaps);
#pragma endregion
} while (FALSE);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSPDO, "%!FUNC! Exit with status %!STATUS!", status);
return status;
}
#pragma region USB Interface Functions
BOOLEAN USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbIsDeviceHighSpeed(IN PVOID BusContext)
{
UNREFERENCED_PARAMETER(BusContext);
@@ -10,9 +308,9 @@ BOOLEAN USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbIsDeviceHighSpeed(I
}
NTSTATUS USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbQueryBusInformation(IN PVOID BusContext, IN ULONG Level,
IN OUT PVOID BusInformationBuffer,
IN OUT PULONG BusInformationBufferLength,
OUT PULONG BusInformationActualLength)
IN OUT PVOID BusInformationBuffer,
IN OUT PULONG BusInformationBufferLength,
OUT PULONG BusInformationActualLength)
{
UNREFERENCED_PARAMETER(BusContext);
UNREFERENCED_PARAMETER(Level);
@@ -40,8 +338,8 @@ NTSTATUS USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbQueryBusTime(IN PV
}
VOID USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbGetUSBDIVersion(IN PVOID BusContext,
IN OUT PUSBD_VERSION_INFORMATION VersionInformation,
IN OUT PULONG HcdCapabilities)
IN OUT PUSBD_VERSION_INFORMATION VersionInformation,
IN OUT PULONG HcdCapabilities)
{
UNREFERENCED_PARAMETER(BusContext);
@@ -57,6 +355,38 @@ VOID USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbGetUSBDIVersion(IN PVO
}
}
ViGEm::Bus::Core::EmulationTargetPDO::EmulationTargetPDO(USHORT VID, USHORT PID): VendorId(VID), ProductId(PID)
#pragma endregion
ViGEm::Bus::Core::EmulationTargetPDO::EmulationTargetPDO(USHORT VID, USHORT PID) : VendorId(VID), ProductId(PID)
{
}
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EvtDevicePrepareHardware(
_In_ WDFDEVICE Device,
_In_ WDFCMRESLIST ResourcesRaw,
_In_ WDFCMRESLIST ResourcesTranslated
)
{
UNREFERENCED_PARAMETER(ResourcesRaw);
UNREFERENCED_PARAMETER(ResourcesTranslated);
const auto ctx = EmulationTargetPdoGetContext(Device);
return ctx->Target->PrepareHardware();
}
VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ size_t OutputBufferLength,
_In_ size_t InputBufferLength,
_In_ ULONG IoControlCode
)
{
UNREFERENCED_PARAMETER(Queue);
UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(InputBufferLength);
UNREFERENCED_PARAMETER(IoControlCode);
WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
}

View File

@@ -18,6 +18,12 @@
namespace ViGEm::Bus::Core
{
// {A8BA2D1F-894F-464A-B0CE-7A0C8FD65DF1}
DEFINE_GUID(GUID_DEVCLASS_VIGEM_RAWPDO,
0xA8BA2D1F, 0x894F, 0x464A, 0xB0, 0xCE, 0x7A, 0x0C, 0x8F, 0xD6, 0x5D, 0xF1);
typedef struct _PDO_IDENTIFICATION_DESCRIPTION* PPDO_IDENTIFICATION_DESCRIPTION;
class EmulationTargetPDO
{
public:
@@ -25,21 +31,27 @@ namespace ViGEm::Bus::Core
virtual ~EmulationTargetPDO() = default;
virtual NTSTATUS PrepareDevice(PWDFDEVICE_INIT DeviceInit,
virtual NTSTATUS PrepareDevice(PWDFDEVICE_INIT DeviceInit,
PUNICODE_STRING DeviceId, PUNICODE_STRING DeviceDescription) = 0;
virtual NTSTATUS PrepareHardware(WDFDEVICE Device) = 0;
virtual NTSTATUS PrepareHardware() = 0;
virtual NTSTATUS InitContext(WDFDEVICE Device) = 0;
virtual NTSTATUS InitContext() = 0;
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);
protected:
static const ULONG _maxHardwareIdLength = 0xFF;
static PCWSTR _deviceLocation;
static BOOLEAN USB_BUSIFFN UsbIsDeviceHighSpeed(IN PVOID BusContext);
static NTSTATUS USB_BUSIFFN UsbQueryBusInformation(
@@ -60,44 +72,69 @@ namespace ViGEm::Bus::Core
IN OUT PULONG HcdCapabilities
);
//
// Unique serial number of the device on the bus
//
ULONG SerialNo{};
static EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware;
//
// PID of the process creating this PDO
//
DWORD OwnerProcessId{};
static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL EvtIoInternalDeviceControl;
//
// Device type this PDO is emulating
//
VIGEM_TARGET_TYPE TargetType;
static const int MAX_INSTANCE_ID_LEN = 80;
//
// If set, the vendor ID the emulated device is reporting
//
USHORT VendorId{};
//
// Unique serial number of the device on the bus
//
ULONG SerialNo{};
//
// If set, the product ID the emulated device is reporting
//
USHORT ProductId{};
//
// PID of the process creating this PDO
//
DWORD OwnerProcessId{};
//
// Queue for incoming data interrupt transfer
//
WDFQUEUE PendingUsbInRequests{};
//
// Device type this PDO is emulating
//
VIGEM_TARGET_TYPE TargetType;
//
// Queue for inverted calls
//
WDFQUEUE PendingNotificationRequests{};
//
// If set, the vendor ID the emulated device is reporting
//
USHORT VendorId{};
//
// If set, the product ID the emulated device is reporting
//
USHORT ProductId{};
//
// Queue for incoming data interrupt transfer
//
WDFQUEUE PendingUsbInRequests{};
//
// Queue for inverted calls
//
WDFQUEUE PendingNotificationRequests{};
//
// This child objects' device object
//
WDFDEVICE PdoDevice;
//
// Signals the bus that PDO is ready to receive data
//
KEVENT PdoBootNotificationEvent;
};
typedef struct _PDO_IDENTIFICATION_DESCRIPTION
{
EmulationTargetPDO* Context;
WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
EmulationTargetPDO* Target;
} PDO_IDENTIFICATION_DESCRIPTION, *PPDO_IDENTIFICATION_DESCRIPTION;
typedef struct _EMULATION_TARGET_PDO_CONTEXT
{
EmulationTargetPDO* Target;
} EMULATION_TARGET_PDO_CONTEXT, *PEMULATION_TARGET_PDO_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(EMULATION_TARGET_PDO_CONTEXT, EmulationTargetPdoGetContext)
}

View File

@@ -11,6 +11,7 @@ PCWSTR ViGEm::Bus::Targets::EmulationTargetXUSB::_deviceDescription = L"Virtual
ViGEm::Bus::Targets::EmulationTargetXUSB::EmulationTargetXUSB() : EmulationTargetPDO(0x045E, 0x028E)
{
TargetType = Xbox360Wired;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareDevice(PWDFDEVICE_INIT DeviceInit, PUNICODE_STRING DeviceId,
@@ -98,7 +99,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareDevice(PWDFDEVICE_INIT
return STATUS_SUCCESS;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Device)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware()
{
WDF_QUERY_INTERFACE_CONFIG ifaceCfg;
@@ -106,7 +107,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
dummyIface.Size = sizeof(INTERFACE);
dummyIface.Version = 1;
dummyIface.Context = static_cast<PVOID>(Device);
dummyIface.Context = static_cast<PVOID>(this->PdoDevice);
dummyIface.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
dummyIface.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
@@ -124,7 +125,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
nullptr
);
NTSTATUS status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
NTSTATUS status = WdfDeviceAddQueryInterface(this->PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
@@ -145,7 +146,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
nullptr
);
status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
status = WdfDeviceAddQueryInterface(this->PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
@@ -166,7 +167,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
nullptr
);
status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
status = WdfDeviceAddQueryInterface(this->PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
@@ -185,7 +186,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
xusbInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V1);
xusbInterface.Version = USB_BUSIF_USBDI_VERSION_1;
xusbInterface.BusContext = static_cast<PVOID>(Device);
xusbInterface.BusContext = static_cast<PVOID>(this->PdoDevice);
xusbInterface.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
xusbInterface.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
@@ -203,7 +204,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
nullptr
);
status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
status = WdfDeviceAddQueryInterface(this->PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
@@ -216,13 +217,13 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PrepareHardware(WDFDEVICE Dev
return STATUS_SUCCESS;
}
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::InitContext(WDFDEVICE Device)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::InitContext()
{
WDF_OBJECT_ATTRIBUTES attributes;
PUCHAR blobBuffer;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = Device;
attributes.ParentObject = this->PdoDevice;
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XUSB, "Initializing XUSB context...");
@@ -286,7 +287,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::InitContext(WDFDEVICE Device)
WDF_IO_QUEUE_CONFIG_INIT(&holdingInQueueConfig, WdfIoQueueDispatchManual);
status = WdfIoQueueCreate(
Device,
this->PdoDevice,
&holdingInQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&this->HoldingUsbInRequests

View File

@@ -26,9 +26,9 @@ namespace ViGEm::Bus::Targets
NTSTATUS PrepareDevice(PWDFDEVICE_INIT DeviceInit,
PUNICODE_STRING DeviceId, PUNICODE_STRING DeviceDescription) override;
NTSTATUS PrepareHardware(WDFDEVICE Device) override;
NTSTATUS PrepareHardware() override;
NTSTATUS InitContext(WDFDEVICE Device) override;
NTSTATUS InitContext() override;
VOID GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length) override;
@@ -95,14 +95,4 @@ namespace ViGEm::Bus::Targets
//
WDFMEMORY InterruptBlobStorage;
};
//
// XUSB-specific device context data.
//
typedef struct _XUSB_PDO_CONTEXT
{
EmulationTargetXUSB* Context;
} XUSB_PDO_CONTEXT, *PXUSB_PDO_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XUSB_PDO_CONTEXT, XusbPdoGetContext)
}