mirror of
https://github.com/nefarius/ViGEmBus.git
synced 2025-08-10 00:52:17 +00:00
Removed XGIP stuff
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -23,6 +23,7 @@ mono_crash.*
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
@@ -61,6 +62,9 @@ project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
@@ -350,4 +354,7 @@ healthchecksdb
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
2
client
2
client
Submodule client updated: d466227688...465736429b
60
sys/Queue.c
60
sys/Queue.c
@@ -50,8 +50,6 @@ VOID Bus_EvtIoDeviceControl(
|
||||
PXUSB_REQUEST_NOTIFICATION xusbNotify = NULL;
|
||||
PDS4_SUBMIT_REPORT ds4Submit = NULL;
|
||||
PDS4_REQUEST_NOTIFICATION ds4Notify = NULL;
|
||||
PXGIP_SUBMIT_REPORT xgipSubmit = NULL;
|
||||
PXGIP_SUBMIT_INTERRUPT xgipInterrupt = NULL;
|
||||
PVIGEM_CHECK_VERSION pCheckVersion = NULL;
|
||||
PXUSB_GET_USER_INDEX pXusbGetUserIndex = NULL;
|
||||
|
||||
@@ -278,64 +276,6 @@ VOID Bus_EvtIoDeviceControl(
|
||||
break;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOCTL_XGIP_SUBMIT_REPORT
|
||||
case IOCTL_XGIP_SUBMIT_REPORT:
|
||||
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE,
|
||||
TRACE_QUEUE,
|
||||
"IOCTL_XGIP_SUBMIT_REPORT");
|
||||
|
||||
status = WdfRequestRetrieveInputBuffer(Request, sizeof(XGIP_SUBMIT_REPORT), (PVOID)&xgipSubmit, &length);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
KdPrint((DRIVERNAME "WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sizeof(XGIP_SUBMIT_REPORT) == xgipSubmit->Size) && (length == InputBufferLength))
|
||||
{
|
||||
// This request only supports a single PDO at a time
|
||||
if (xgipSubmit->SerialNo == 0)
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
status = Bus_XgipSubmitReport(Device, xgipSubmit->SerialNo, xgipSubmit, FALSE);
|
||||
}
|
||||
|
||||
break;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOCTL_XGIP_SUBMIT_INTERRUPT
|
||||
case IOCTL_XGIP_SUBMIT_INTERRUPT:
|
||||
|
||||
KdPrint((DRIVERNAME "IOCTL_XGIP_SUBMIT_INTERRUPT\n"));
|
||||
|
||||
status = WdfRequestRetrieveInputBuffer(Request, sizeof(XGIP_SUBMIT_INTERRUPT), (PVOID)&xgipInterrupt, &length);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
KdPrint((DRIVERNAME "WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sizeof(XGIP_SUBMIT_INTERRUPT) == xgipInterrupt->Size) && (length == InputBufferLength))
|
||||
{
|
||||
// This request only supports a single PDO at a time
|
||||
if (xgipInterrupt->SerialNo == 0)
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
status = Bus_XgipSubmitInterrupt(Device, xgipSubmit->SerialNo, xgipInterrupt, FALSE);
|
||||
}
|
||||
|
||||
break;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOCTL_XUSB_GET_USER_INDEX
|
||||
case IOCTL_XUSB_GET_USER_INDEX:
|
||||
|
||||
|
||||
@@ -191,7 +191,6 @@
|
||||
<ClInclude Include="trace.h" />
|
||||
<ClInclude Include="UsbPdo.h" />
|
||||
<ClInclude Include="Util.h" />
|
||||
<ClInclude Include="Xgip.h" />
|
||||
<ClInclude Include="Xusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -206,7 +205,6 @@
|
||||
<ClCompile Include="Queue.c" />
|
||||
<ClCompile Include="UsbPdo.c" />
|
||||
<ClCompile Include="Util.c" />
|
||||
<ClCompile Include="xgip.c" />
|
||||
<ClCompile Include="xusb.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -48,9 +48,6 @@
|
||||
<ClInclude Include="Util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Xgip.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ByteArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -63,6 +60,9 @@
|
||||
<ClInclude Include="..\client\include\ViGEm\km\BusShared.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="busenum.c">
|
||||
@@ -74,9 +74,6 @@
|
||||
<ClCompile Include="xusb.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="xgip.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Queue.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -96,4 +93,9 @@
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ViGEmBus.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
101
sys/Xgip.h
101
sys/Xgip.h
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2016-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// For children emulating XGIP devices, the following dummy interfaces
|
||||
// have to be exposed by the PDO or else the child devices won't start
|
||||
//
|
||||
|
||||
// Below these interfaces are from wdmguid.h being used as dummies
|
||||
// {70211B0E-0AFB-47DB-AFC1-410BF842497A} PNP_LOCATION_INTERFACE
|
||||
// {B38290E5-3CD0-4F9D-9937-F5FE2B44D47A} D3COLD_SUPPORT_INTERFACE
|
||||
// {2AEB0243-6A6E-486B-82FC-D815F6B97006} REENUMERATE_SELF_INTERFACE_STANDARD
|
||||
|
||||
// {DC7A8E51-49B3-4A3A-9E81-625205E7D729} Seems to be GUID_POWER_THREAD_INTERFACE
|
||||
// Source: https://github.com/microsoft/Windows-Driver-Frameworks/blob/master/src/framework/shared/irphandlers/pnp/fxpkgpnp.cpp#L63
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_XGIP_GUID_POWER_THREAD_INTERFACE_DUMMY,
|
||||
0xDC7A8E51, 0x49B3, 0x4A3A, 0x9E, 0x81, 0x62, 0x52, 0x05, 0xE7, 0xD7, 0x29);
|
||||
|
||||
// {DEEE98EA-C0A1-42C3-9738-A04606C84E93}
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_XGIP_UNKNOWN_4,
|
||||
0xDEEE98EA, 0xC0A1, 0x42C3, 0x97, 0x38, 0xA0, 0x46, 0x06, 0xC8, 0x4E, 0x93);
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#define XGIP_DESCRIPTOR_SIZE 0x0040
|
||||
#define XGIP_CONFIGURATION_SIZE 0x88
|
||||
#define XGIP_REPORT_SIZE 0x12
|
||||
#define XGIP_SYS_INIT_PACKETS 0x0F
|
||||
#define XGIP_SYS_INIT_PERIOD 0x32
|
||||
|
||||
typedef struct _XGIP_DEVICE_DATA
|
||||
{
|
||||
UCHAR Report[XGIP_REPORT_SIZE];
|
||||
|
||||
//
|
||||
// Queue for incoming interrupt transfer
|
||||
//
|
||||
WDFQUEUE PendingUsbInRequests;
|
||||
|
||||
//
|
||||
// Queue for inverted calls
|
||||
//
|
||||
WDFQUEUE PendingNotificationRequests;
|
||||
|
||||
WDFCOLLECTION XboxgipSysInitCollection;
|
||||
|
||||
BOOLEAN XboxgipSysInitReady;
|
||||
|
||||
WDFTIMER XboxgipSysInitTimer;
|
||||
} XGIP_DEVICE_DATA, *PXGIP_DEVICE_DATA;
|
||||
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XGIP_DEVICE_DATA, XgipGetData)
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Bus_XgipSubmitInterrupt(
|
||||
WDFDEVICE Device,
|
||||
ULONG SerialNo,
|
||||
PXGIP_SUBMIT_INTERRUPT Report,
|
||||
_In_ BOOLEAN FromInterface
|
||||
);
|
||||
|
||||
//
|
||||
// XGIP-specific functions
|
||||
//
|
||||
NTSTATUS Xgip_PreparePdo(
|
||||
PWDFDEVICE_INIT DeviceInit,
|
||||
PUNICODE_STRING DeviceId,
|
||||
PUNICODE_STRING DeviceDescription
|
||||
);
|
||||
NTSTATUS Xgip_PrepareHardware(WDFDEVICE Device);
|
||||
NTSTATUS Xgip_AssignPdoContext(WDFDEVICE Device);
|
||||
VOID Xgip_GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length);
|
||||
VOID Xgip_GetDeviceDescriptorType(PUSB_DEVICE_DESCRIPTOR pDescriptor, PPDO_DEVICE_DATA pCommon);
|
||||
VOID Xgip_SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo);
|
||||
|
||||
104
sys/busenum.c
104
sys/busenum.c
@@ -140,17 +140,8 @@ NTSTATUS Bus_PlugInDevice(
|
||||
description.ProductId = 0x05C4;
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
description.VendorId = 0x0E6F;
|
||||
description.ProductId = 0x0139;
|
||||
|
||||
#if !DBG
|
||||
// TODO: implement and remove!
|
||||
default:
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -548,20 +539,6 @@ NTSTATUS Bus_Ds4SubmitReport(WDFDEVICE Device, ULONG SerialNo, PDS4_SUBMIT_REPOR
|
||||
return Bus_SubmitReport(Device, SerialNo, Report, FromInterface);
|
||||
}
|
||||
|
||||
NTSTATUS Bus_XgipSubmitReport(WDFDEVICE Device, ULONG SerialNo, PXGIP_SUBMIT_REPORT Report, BOOLEAN FromInterface)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_BUSENUM, "%!FUNC! Entry");
|
||||
|
||||
return Bus_SubmitReport(Device, SerialNo, Report, FromInterface);
|
||||
}
|
||||
|
||||
NTSTATUS Bus_XgipSubmitInterrupt(WDFDEVICE Device, ULONG SerialNo, PXGIP_SUBMIT_INTERRUPT Report, BOOLEAN FromInterface)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_BUSENUM, "%!FUNC! Entry");
|
||||
|
||||
return Bus_SubmitReport(Device, SerialNo, Report, FromInterface);
|
||||
}
|
||||
|
||||
WDFDEVICE Bus_GetPdo(IN WDFDEVICE Device, IN ULONG SerialNo)
|
||||
{
|
||||
WDFCHILDLIST list;
|
||||
@@ -639,12 +616,6 @@ NTSTATUS Bus_SubmitReport(WDFDEVICE Device, ULONG SerialNo, PVOID Report, BOOLEA
|
||||
|
||||
changed = TRUE;
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
// TODO: necessary?
|
||||
changed = TRUE;
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -679,60 +650,6 @@ NTSTATUS Bus_SubmitReport(WDFDEVICE Device, ULONG SerialNo, PVOID Report, BOOLEA
|
||||
|
||||
status = WdfIoQueueRetrieveNextRequest(pdoData->PendingUsbInRequests, &usbRequest);
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
// Request is control data
|
||||
if (((PXGIP_SUBMIT_INTERRUPT)Report)->Size == sizeof(XGIP_SUBMIT_INTERRUPT))
|
||||
{
|
||||
PXGIP_DEVICE_DATA xgip = XgipGetData(hChild);
|
||||
PXGIP_SUBMIT_INTERRUPT interrupt = (PXGIP_SUBMIT_INTERRUPT)Report;
|
||||
WDFMEMORY memory;
|
||||
WDF_OBJECT_ATTRIBUTES memAttribs;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&memAttribs);
|
||||
|
||||
memAttribs.ParentObject = hChild;
|
||||
|
||||
// Allocate kernel memory
|
||||
status = WdfMemoryCreate(&memAttribs, NonPagedPool, VIGEM_POOL_TAG,
|
||||
interrupt->InterruptLength, &memory, NULL);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
KdPrint((DRIVERNAME "WdfMemoryCreate failed with status 0x%X\n", status));
|
||||
goto endSubmitReport;
|
||||
}
|
||||
|
||||
// Copy interrupt buffer to memory object
|
||||
status = WdfMemoryCopyFromBuffer(memory, 0, interrupt->Interrupt, interrupt->InterruptLength);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
KdPrint((DRIVERNAME "WdfMemoryCopyFromBuffer failed with status 0x%X\n", status));
|
||||
goto endSubmitReport;
|
||||
}
|
||||
|
||||
// Add memory object to collection
|
||||
status = WdfCollectionAdd(xgip->XboxgipSysInitCollection, memory);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
KdPrint((DRIVERNAME "WdfCollectionAdd failed with status 0x%X\n", status));
|
||||
goto endSubmitReport;
|
||||
}
|
||||
|
||||
// Check if all packets have been received
|
||||
xgip->XboxgipSysInitReady =
|
||||
WdfCollectionGetCount(xgip->XboxgipSysInitCollection) == XGIP_SYS_INIT_PACKETS;
|
||||
|
||||
// If all packets are cached, start initialization timer
|
||||
if (xgip->XboxgipSysInitReady)
|
||||
{
|
||||
WdfTimerStart(xgip->XboxgipSysInitTimer, XGIP_SYS_INIT_PERIOD);
|
||||
}
|
||||
|
||||
goto endSubmitReport;
|
||||
}
|
||||
|
||||
status = WdfIoQueueRetrieveNextRequest(XgipGetData(hChild)->PendingUsbInRequests, &usbRequest);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -788,25 +705,6 @@ NTSTATUS Bus_SubmitReport(WDFDEVICE Device, ULONG SerialNo, PVOID Report, BOOLEA
|
||||
if (Buffer)
|
||||
RtlCopyBytes(Buffer, Ds4GetData(hChild)->Report, DS4_REPORT_SIZE);
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
// Request is input report
|
||||
if (((PXGIP_SUBMIT_REPORT)Report)->Size == sizeof(XGIP_SUBMIT_REPORT))
|
||||
{
|
||||
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = XGIP_REPORT_SIZE;
|
||||
|
||||
// Increase event counter on every call (can roll-over)
|
||||
XgipGetData(hChild)->Report[2]++;
|
||||
|
||||
/* Copy report to cache and transfer buffer
|
||||
* Skip first four bytes as they are not part of the report */
|
||||
RtlCopyBytes(XgipGetData(hChild)->Report + 4, &((PXGIP_SUBMIT_REPORT)Report)->Report, sizeof(XGIP_REPORT));
|
||||
RtlCopyBytes(Buffer, XgipGetData(hChild)->Report, XGIP_REPORT_SIZE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include "UsbPdo.h"
|
||||
#include "Xusb.h"
|
||||
#include "Ds4.h"
|
||||
#include "Xgip.h"
|
||||
|
||||
|
||||
#pragma region Macros
|
||||
@@ -106,8 +105,6 @@ EVT_WDF_DEVICE_PREPARE_HARDWARE Pdo_EvtDevicePrepareHardware;
|
||||
|
||||
EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL Pdo_EvtIoInternalDeviceControl;
|
||||
|
||||
EVT_WDF_TIMER Xgip_SysInitTimerFunc;
|
||||
|
||||
EVT_WDF_OBJECT_CONTEXT_CLEANUP Bus_EvtDriverContextCleanup;
|
||||
|
||||
EVT_WDF_TIMER Bus_PlugInRequestCleanUpEvtTimerFunc;
|
||||
@@ -146,14 +143,6 @@ Bus_QueueNotification(
|
||||
WDFREQUEST Request
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Bus_XgipSubmitReport(
|
||||
WDFDEVICE Device,
|
||||
ULONG SerialNo,
|
||||
PXGIP_SUBMIT_REPORT Report,
|
||||
_In_ BOOLEAN FromInterface
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Bus_SubmitReport(
|
||||
WDFDEVICE Device,
|
||||
|
||||
42
sys/buspdo.c
42
sys/buspdo.c
@@ -189,18 +189,6 @@ NTSTATUS Bus_CreatePdo(
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// A Xbox One device was requested
|
||||
//
|
||||
case XboxOneWired:
|
||||
|
||||
status = Xgip_PreparePdo(DeviceInit, &deviceId, &deviceDescription);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
goto endCreatePdo;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
@@ -334,23 +322,6 @@ NTSTATUS Bus_CreatePdo(
|
||||
|
||||
break;
|
||||
}
|
||||
case XboxOneWired:
|
||||
{
|
||||
PXGIP_DEVICE_DATA xgipData = NULL;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, XGIP_DEVICE_DATA);
|
||||
|
||||
status = WdfObjectAllocateContext(hChild, &pdoAttributes, (PVOID)&xgipData);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR,
|
||||
TRACE_BUSPDO,
|
||||
"WdfObjectAllocateContext failed with status %!STATUS!",
|
||||
status);
|
||||
goto endCreatePdo;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -406,13 +377,6 @@ NTSTATUS Bus_CreatePdo(
|
||||
status = Ds4_AssignPdoContext(hChild, Description);
|
||||
|
||||
break;
|
||||
|
||||
case XboxOneWired:
|
||||
|
||||
status = Xgip_AssignPdoContext(hChild);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -563,12 +527,6 @@ NTSTATUS Pdo_EvtDevicePrepareHardware(
|
||||
|
||||
break;
|
||||
|
||||
case XboxOneWired:
|
||||
|
||||
status = Xgip_PrepareHardware(Device);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
58
sys/usbpdo.c
58
sys/usbpdo.c
@@ -145,12 +145,6 @@ NTSTATUS UsbPdo_GetDeviceDescriptorType(PURB urb, PPDO_DEVICE_DATA pCommon)
|
||||
|
||||
break;
|
||||
|
||||
case XboxOneWired:
|
||||
|
||||
Xgip_GetDeviceDescriptorType(pDescriptor, pCommon);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
@@ -181,11 +175,6 @@ NTSTATUS UsbPdo_GetConfigurationDescriptorType(PURB urb, PPDO_DEVICE_DATA pCommo
|
||||
|
||||
Ds4_GetConfigurationDescriptorType(Buffer, length);
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
Xgip_GetConfigurationDescriptorType(Buffer, length);
|
||||
|
||||
break;
|
||||
default:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
@@ -212,14 +201,6 @@ NTSTATUS UsbPdo_GetConfigurationDescriptorType(PURB urb, PPDO_DEVICE_DATA pCommo
|
||||
Ds4_GetConfigurationDescriptorType(Buffer, DS4_DESCRIPTOR_SIZE);
|
||||
}
|
||||
|
||||
break;
|
||||
case XboxOneWired:
|
||||
|
||||
if (length >= XGIP_DESCRIPTOR_SIZE)
|
||||
{
|
||||
Xgip_GetConfigurationDescriptorType(Buffer, XGIP_DESCRIPTOR_SIZE);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
@@ -382,20 +363,6 @@ NTSTATUS UsbPdo_SelectConfiguration(PURB urb, PPDO_DEVICE_DATA pCommon)
|
||||
|
||||
break;
|
||||
|
||||
case XboxOneWired:
|
||||
|
||||
if (urb->UrbHeader.Length < XGIP_CONFIGURATION_SIZE)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_WARNING,
|
||||
TRACE_USBPDO,
|
||||
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Invalid ConfigurationDescriptor");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Xgip_SelectConfiguration(pInfo);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
@@ -800,31 +767,6 @@ NTSTATUS UsbPdo_BulkOrInterruptTransfer(PURB urb, WDFDEVICE Device, WDFREQUEST R
|
||||
|
||||
break;
|
||||
}
|
||||
case XboxOneWired:
|
||||
{
|
||||
PXGIP_DEVICE_DATA xgipData = XgipGetData(Device);
|
||||
|
||||
// Data coming FROM us TO higher driver
|
||||
if (pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
|
||||
{
|
||||
KdPrint((DRIVERNAME ">> >> >> Incoming request, queuing..."));
|
||||
|
||||
/* This request is sent periodically and relies on data the "feeder"
|
||||
has to supply, so we queue this request and return with STATUS_PENDING.
|
||||
The request gets completed as soon as the "feeder" sent an update. */
|
||||
status = WdfRequestForwardToIoQueue(Request, xgipData->PendingUsbInRequests);
|
||||
|
||||
return (NT_SUCCESS(status)) ? STATUS_PENDING : status;
|
||||
}
|
||||
|
||||
// Data coming FROM the higher driver TO us
|
||||
KdPrint((DRIVERNAME ">> >> >> URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: Handle %p, Flags %X, Length %d",
|
||||
pTransfer->PipeHandle,
|
||||
pTransfer->TransferFlags,
|
||||
pTransfer->TransferBufferLength));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
409
sys/xgip.c
409
sys/xgip.c
@@ -1,409 +0,0 @@
|
||||
/*
|
||||
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2016-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "busenum.h"
|
||||
#include <wdmguid.h>
|
||||
#include "xgip.tmh"
|
||||
|
||||
NTSTATUS Xgip_PreparePdo(PWDFDEVICE_INIT DeviceInit, PUNICODE_STRING DeviceId, PUNICODE_STRING DeviceDescription)
|
||||
{
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING buffer;
|
||||
|
||||
// prepare device description
|
||||
status = RtlUnicodeStringInit(DeviceDescription, L"Virtual Xbox One Controller");
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
// Set hardware IDs
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\VID_0E6F&PID_0139&REV_0650");
|
||||
|
||||
status = WdfPdoInitAddHardwareID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
RtlUnicodeStringCopy(DeviceId, &buffer);
|
||||
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\VID_0E6F&PID_0139");
|
||||
|
||||
status = WdfPdoInitAddHardwareID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
// Set compatible IDs
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\MS_COMP_XGIP10");
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\Class_FF&SubClass_47&Prot_D0");
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\Class_FF&SubClass_47");
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
RtlUnicodeStringInit(&buffer, L"USB\\Class_FF");
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS Xgip_PrepareHardware(WDFDEVICE Device)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WDF_QUERY_INTERFACE_CONFIG ifaceCfg;
|
||||
|
||||
// Expose USB_BUS_INTERFACE_USBDI_GUID
|
||||
USB_BUS_INTERFACE_USBDI_V1 xgipInterface;
|
||||
|
||||
xgipInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V1);
|
||||
xgipInterface.Version = USB_BUSIF_USBDI_VERSION_1;
|
||||
xgipInterface.BusContext = (PVOID)Device;
|
||||
|
||||
xgipInterface.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
|
||||
xgipInterface.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
|
||||
|
||||
xgipInterface.SubmitIsoOutUrb = UsbPdo_SubmitIsoOutUrb;
|
||||
xgipInterface.GetUSBDIVersion = UsbPdo_GetUSBDIVersion;
|
||||
xgipInterface.QueryBusTime = UsbPdo_QueryBusTime;
|
||||
xgipInterface.QueryBusInformation = UsbPdo_QueryBusInformation;
|
||||
xgipInterface.IsDeviceHighSpeed = UsbPdo_IsDeviceHighSpeed;
|
||||
|
||||
WDF_QUERY_INTERFACE_CONFIG_INIT(&ifaceCfg, (PINTERFACE)&xgipInterface, &USB_BUS_INTERFACE_USBDI_GUID, NULL);
|
||||
|
||||
status = WdfDeviceAddQueryInterface(Device, &ifaceCfg);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_XGIP, "WdfDeviceAddQueryInterface failed with status %!STATUS!", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Default button states
|
||||
UCHAR DefaultReport[XGIP_REPORT_SIZE] =
|
||||
{
|
||||
0x20, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xa3, 0xfd, 0xed, 0x05, 0x5b, 0x03,
|
||||
0x6f, 0x02
|
||||
};
|
||||
|
||||
RtlCopyBytes(XgipGetData(Device)->Report, DefaultReport, XGIP_REPORT_SIZE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS Xgip_AssignPdoContext(WDFDEVICE Device)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
PXGIP_DEVICE_DATA xgip = XgipGetData(Device);
|
||||
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XGIP, "Initializing XGIP context...");
|
||||
|
||||
RtlZeroMemory(xgip, sizeof(XGIP_DEVICE_DATA));
|
||||
|
||||
// Set fixed report id
|
||||
xgip->Report[0] = 0x20;
|
||||
xgip->Report[3] = 0x0E;
|
||||
|
||||
// I/O Queue for pending IRPs
|
||||
WDF_IO_QUEUE_CONFIG pendingUsbQueueConfig, notificationsQueueConfig;
|
||||
|
||||
// Create and assign queue for incoming interrupt transfer
|
||||
WDF_IO_QUEUE_CONFIG_INIT(&pendingUsbQueueConfig, WdfIoQueueDispatchManual);
|
||||
|
||||
status = WdfIoQueueCreate(Device, &pendingUsbQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &xgip->PendingUsbInRequests);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_XGIP, "WdfIoQueueCreate failed with status %!STATUS!", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Create and assign queue for user-land notification requests
|
||||
WDF_IO_QUEUE_CONFIG_INIT(¬ificationsQueueConfig, WdfIoQueueDispatchManual);
|
||||
|
||||
status = WdfIoQueueCreate(Device, ¬ificationsQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &xgip->PendingNotificationRequests);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_XGIP, "WdfIoQueueCreate failed with status %!STATUS!", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
WDF_OBJECT_ATTRIBUTES collectionAttribs;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&collectionAttribs);
|
||||
|
||||
collectionAttribs.ParentObject = Device;
|
||||
|
||||
status = WdfCollectionCreate(&collectionAttribs, &xgip->XboxgipSysInitCollection);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_XGIP, "WdfCollectionCreate failed with status %!STATUS!", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize periodic timer
|
||||
WDF_TIMER_CONFIG timerConfig;
|
||||
WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfig, Xgip_SysInitTimerFunc, XGIP_SYS_INIT_PERIOD);
|
||||
|
||||
// Timer object attributes
|
||||
WDF_OBJECT_ATTRIBUTES timerAttribs;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&timerAttribs);
|
||||
|
||||
// PDO is parent
|
||||
timerAttribs.ParentObject = Device;
|
||||
|
||||
// Create timer
|
||||
status = WdfTimerCreate(&timerConfig, &timerAttribs, &xgip->XboxgipSysInitTimer);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_XGIP, "WdfTimerCreate failed with status %!STATUS!", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID Xgip_GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length)
|
||||
{
|
||||
UCHAR XgipDescriptorData[XGIP_DESCRIPTOR_SIZE] =
|
||||
{
|
||||
0x09, // bLength
|
||||
0x02, // bDescriptorType (Configuration)
|
||||
0x40, 0x00, // wTotalLength 64
|
||||
0x02, // bNumInterfaces 2
|
||||
0x01, // bConfigurationValue
|
||||
0x00, // iConfiguration (String Index)
|
||||
0xC0, // bmAttributes
|
||||
0xFA, // bMaxPower 500mA
|
||||
|
||||
0x09, // bLength
|
||||
0x04, // bDescriptorType (Interface)
|
||||
0x00, // bInterfaceNumber 0
|
||||
0x00, // bAlternateSetting
|
||||
0x02, // bNumEndpoints 2
|
||||
0xFF, // bInterfaceClass
|
||||
0x47, // bInterfaceSubClass
|
||||
0xD0, // bInterfaceProtocol
|
||||
0x00, // iInterface (String Index)
|
||||
|
||||
0x07, // bLength
|
||||
0x05, // bDescriptorType (Endpoint)
|
||||
0x81, // bEndpointAddress (IN/D2H)
|
||||
0x03, // bmAttributes (Interrupt)
|
||||
0x40, 0x00, // wMaxPacketSize 64
|
||||
0x04, // bInterval 4 (unit depends on device speed)
|
||||
|
||||
0x07, // bLength
|
||||
0x05, // bDescriptorType (Endpoint)
|
||||
0x01, // bEndpointAddress (OUT/H2D)
|
||||
0x03, // bmAttributes (Interrupt)
|
||||
0x40, 0x00, // wMaxPacketSize 64
|
||||
0x04, // bInterval 4 (unit depends on device speed)
|
||||
|
||||
0x09, // bLength
|
||||
0x04, // bDescriptorType (Interface)
|
||||
0x01, // bInterfaceNumber 1
|
||||
0x00, // bAlternateSetting
|
||||
0x00, // bNumEndpoints 0
|
||||
0xFF, // bInterfaceClass
|
||||
0x47, // bInterfaceSubClass
|
||||
0xD0, // bInterfaceProtocol
|
||||
0x00, // iInterface (String Index)
|
||||
|
||||
0x09, // bLength
|
||||
0x04, // bDescriptorType (Interface)
|
||||
0x01, // bInterfaceNumber 1
|
||||
0x01, // bAlternateSetting
|
||||
0x02, // bNumEndpoints 2
|
||||
0xFF, // bInterfaceClass
|
||||
0x47, // bInterfaceSubClass
|
||||
0xD0, // bInterfaceProtocol
|
||||
0x00, // iInterface (String Index)
|
||||
|
||||
0x07, // bLength
|
||||
0x05, // bDescriptorType (Endpoint)
|
||||
0x02, // bEndpointAddress (OUT/H2D)
|
||||
0x01, // bmAttributes (Isochronous, No Sync, Data EP)
|
||||
0xE0, 0x00, // wMaxPacketSize 224
|
||||
0x01, // bInterval 1 (unit depends on device speed)
|
||||
|
||||
0x07, // bLength
|
||||
0x05, // bDescriptorType (Endpoint)
|
||||
0x83, // bEndpointAddress (IN/D2H)
|
||||
0x01, // bmAttributes (Isochronous, No Sync, Data EP)
|
||||
0x80, 0x00, // wMaxPacketSize 128
|
||||
0x01, // bInterval 1 (unit depends on device speed)
|
||||
|
||||
// 64 bytes
|
||||
|
||||
// best guess: USB Standard Descriptor
|
||||
};
|
||||
|
||||
RtlCopyBytes(Buffer, XgipDescriptorData, Length);
|
||||
}
|
||||
|
||||
VOID Xgip_GetDeviceDescriptorType(PUSB_DEVICE_DESCRIPTOR pDescriptor, PPDO_DEVICE_DATA pCommon)
|
||||
{
|
||||
pDescriptor->bLength = 0x12;
|
||||
pDescriptor->bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
|
||||
pDescriptor->bcdUSB = 0x0200; // USB v2.0
|
||||
pDescriptor->bDeviceClass = 0xFF;
|
||||
pDescriptor->bDeviceSubClass = 0x47;
|
||||
pDescriptor->bDeviceProtocol = 0xD0;
|
||||
pDescriptor->bMaxPacketSize0 = 0x40;
|
||||
pDescriptor->idVendor = pCommon->VendorId;
|
||||
pDescriptor->idProduct = pCommon->ProductId;
|
||||
pDescriptor->bcdDevice = 0x0650;
|
||||
pDescriptor->iManufacturer = 0x01;
|
||||
pDescriptor->iProduct = 0x02;
|
||||
pDescriptor->iSerialNumber = 0x03;
|
||||
pDescriptor->bNumConfigurations = 0x01;
|
||||
}
|
||||
|
||||
VOID Xgip_SelectConfiguration(PUSBD_INTERFACE_INFORMATION pInfo)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_XGIP, ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
|
||||
(int)pInfo->Length,
|
||||
(int)pInfo->InterfaceNumber,
|
||||
(int)pInfo->AlternateSetting,
|
||||
pInfo->NumberOfPipes);
|
||||
|
||||
pInfo->Class = 0xFF;
|
||||
pInfo->SubClass = 0x47;
|
||||
pInfo->Protocol = 0xD0;
|
||||
|
||||
pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)0xFFFF0000;
|
||||
|
||||
pInfo->Pipes[0].MaximumTransferSize = 0x00400000;
|
||||
pInfo->Pipes[0].MaximumPacketSize = 0x40;
|
||||
pInfo->Pipes[0].EndpointAddress = 0x81;
|
||||
pInfo->Pipes[0].Interval = 0x04;
|
||||
pInfo->Pipes[0].PipeType = UsbdPipeTypeInterrupt;
|
||||
pInfo->Pipes[0].PipeHandle = (USBD_PIPE_HANDLE)0xFFFF0081;
|
||||
pInfo->Pipes[0].PipeFlags = 0x00;
|
||||
|
||||
pInfo->Pipes[1].MaximumTransferSize = 0x00400000;
|
||||
pInfo->Pipes[1].MaximumPacketSize = 0x40;
|
||||
pInfo->Pipes[1].EndpointAddress = 0x01;
|
||||
pInfo->Pipes[1].Interval = 0x04;
|
||||
pInfo->Pipes[1].PipeType = UsbdPipeTypeInterrupt;
|
||||
pInfo->Pipes[1].PipeHandle = (USBD_PIPE_HANDLE)0xFFFF0001;
|
||||
pInfo->Pipes[1].PipeFlags = 0x00;
|
||||
|
||||
pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR)pInfo + pInfo->Length);
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_XGIP, ">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
|
||||
(int)pInfo->Length,
|
||||
(int)pInfo->InterfaceNumber,
|
||||
(int)pInfo->AlternateSetting,
|
||||
pInfo->NumberOfPipes);
|
||||
|
||||
pInfo->Class = 0xFF;
|
||||
pInfo->SubClass = 0x47;
|
||||
pInfo->Protocol = 0xD0;
|
||||
|
||||
pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)0xFFFF0000;
|
||||
}
|
||||
|
||||
VOID Xgip_SysInitTimerFunc(
|
||||
_In_ WDFTIMER Timer
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WDFDEVICE hChild;
|
||||
PXGIP_DEVICE_DATA xgip;
|
||||
WDFREQUEST usbRequest;
|
||||
PIRP pendingIrp;
|
||||
PIO_STACK_LOCATION irpStack;
|
||||
WDFMEMORY mem;
|
||||
|
||||
hChild = WdfTimerGetParentObject(Timer);
|
||||
xgip = XgipGetData(hChild);
|
||||
|
||||
if (xgip == NULL) return;
|
||||
|
||||
// Is TRUE when collection is filled up
|
||||
if (xgip->XboxgipSysInitReady)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XGIP, "XBOXGIP ready, completing requests...");
|
||||
|
||||
// Get pending IN request
|
||||
status = WdfIoQueueRetrieveNextRequest(xgip->PendingUsbInRequests, &usbRequest);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XGIP, "Request found");
|
||||
|
||||
// Get top memory object
|
||||
mem = (WDFMEMORY)WdfCollectionGetFirstItem(xgip->XboxgipSysInitCollection);
|
||||
|
||||
// Get pending IRP
|
||||
pendingIrp = WdfRequestWdmGetIrp(usbRequest);
|
||||
irpStack = IoGetCurrentIrpStackLocation(pendingIrp);
|
||||
|
||||
// Get USB request block
|
||||
PURB urb = (PURB)irpStack->Parameters.Others.Argument1;
|
||||
|
||||
// Get buffer size and content
|
||||
size_t size;
|
||||
PUCHAR Buffer = WdfMemoryGetBuffer(mem, &size);
|
||||
|
||||
// Assign buffer size and content to URB
|
||||
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = (ULONG)size;
|
||||
RtlCopyBytes(urb->UrbBulkOrInterruptTransfer.TransferBuffer, Buffer, size);
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_XGIP, "[%X] Buffer length: %d",
|
||||
((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0],
|
||||
urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
|
||||
|
||||
// Complete pending request
|
||||
WdfRequestComplete(usbRequest, status);
|
||||
|
||||
// Free memory from collection
|
||||
WdfCollectionRemoveItem(xgip->XboxgipSysInitCollection, 0);
|
||||
WdfObjectDelete(mem);
|
||||
}
|
||||
|
||||
// Stop timer when collection is purged
|
||||
if (WdfCollectionGetCount(xgip->XboxgipSysInitCollection) == 0)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XGIP, "Collection finished");
|
||||
|
||||
WdfTimerStop(xgip->XboxgipSysInitTimer, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user