diff --git a/sys/Xusb.h b/sys/Xusb.h index 9989798..20e3b9e 100644 --- a/sys/Xusb.h +++ b/sys/Xusb.h @@ -49,7 +49,15 @@ DEFINE_GUID(GUID_DEVINTERFACE_XUSB_UNKNOWN_2, #define XUSB_LEDSET_SIZE 0x03 #define XUSB_LEDNUM_SIZE 0x01 #define XUSB_INIT_STAGE_SIZE 0x03 -#define XUSB_INIT_BLOB_COUNT 0x07 +#define XUSB_BLOB_STORAGE_SIZE 0x26 + +#define XUSB_BLOB_00_OFFSET 0x00 +#define XUSB_BLOB_01_OFFSET 0x03 +#define XUSB_BLOB_02_OFFSET 0x06 +#define XUSB_BLOB_03_OFFSET 0x09 +#define XUSB_BLOB_04_OFFSET 0x0C +#define XUSB_BLOB_05_OFFSET 0x20 +#define XUSB_BLOB_06_OFFSET 0x23 #define XUSB_IS_DATA_PIPE(_x_) ((BOOLEAN)(_x_->PipeHandle == (USBD_PIPE_HANDLE)0xFFFF0081)) #define XUSB_IS_CONTROL_PIPE(_x_) ((BOOLEAN)(_x_->PipeHandle == (USBD_PIPE_HANDLE)0xFFFF0083)) @@ -102,7 +110,7 @@ typedef struct _XUSB_DEVICE_DATA // // Storage of binary blobs (packets) for PDO initialization // - PVOID InterruptInitStageBlobs[XUSB_INIT_BLOB_COUNT]; + WDFMEMORY InterruptBlobStorage; } XUSB_DEVICE_DATA, *PXUSB_DEVICE_DATA; diff --git a/sys/busenum.h b/sys/busenum.h index 6b01bcd..3379f2c 100644 --- a/sys/busenum.h +++ b/sys/busenum.h @@ -95,7 +95,7 @@ EVT_WDF_CHILD_LIST_CREATE_DEVICE Bus_EvtDeviceListCreatePdo; EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE Bus_EvtChildListIdentificationDescriptionCompare; EVT_WDF_DEVICE_PREPARE_HARDWARE Pdo_EvtDevicePrepareHardware; -EVT_WDF_OBJECT_CONTEXT_CLEANUP Pdo_EvtWdfObjectContextCleanup; + EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL Pdo_EvtIoInternalDeviceControl; EVT_WDF_TIMER Xgip_SysInitTimerFunc; diff --git a/sys/buspdo.c b/sys/buspdo.c index 2216aec..b2a0c54 100644 --- a/sys/buspdo.c +++ b/sys/buspdo.c @@ -26,7 +26,6 @@ #pragma alloc_text(PAGE, Bus_CreatePdo) #pragma alloc_text(PAGE, Bus_EvtDeviceListCreatePdo) #pragma alloc_text(PAGE, Pdo_EvtDevicePrepareHardware) -#pragma alloc_text(PAGE, Pdo_EvtWdfObjectContextCleanup) #endif NTSTATUS Bus_EvtDeviceListCreatePdo( @@ -274,7 +273,6 @@ NTSTATUS Bus_CreatePdo( // Add common device data context WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, PDO_DEVICE_DATA); - pdoAttributes.EvtCleanupCallback = Pdo_EvtWdfObjectContextCleanup; status = WdfDeviceCreate(&DeviceInit, &pdoAttributes, &hChild); if (!NT_SUCCESS(status)) @@ -579,48 +577,6 @@ NTSTATUS Pdo_EvtDevicePrepareHardware( return status; } -_Use_decl_annotations_ -VOID -Pdo_EvtWdfObjectContextCleanup( - WDFOBJECT Object -) -{ - PPDO_DEVICE_DATA pdoData; - ULONG index; - PXUSB_DEVICE_DATA xusb; - - PAGED_CODE(); - - TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSENUM, "%!FUNC! Entry"); - - pdoData = PdoGetData(Object); - - UNREFERENCED_PARAMETER(pdoData); - - switch (pdoData->TargetType) - { - // Free XUSB resources - case Xbox360Wired: - - xusb = XusbGetData(Object); - - for (index = 0; index < XUSB_INIT_BLOB_COUNT; index++) - { - // - // TODO: crashes... - // - ExFreePool(xusb->InterruptInitStageBlobs[index]); - } - - break; - - default: - break; - } - - TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSPDO, "%!FUNC! Exit"); -} - // // Responds to IRP_MJ_INTERNAL_DEVICE_CONTROL requests sent to PDO. // diff --git a/sys/usbpdo.c b/sys/usbpdo.c index 065f58e..68c502c 100644 --- a/sys/usbpdo.c +++ b/sys/usbpdo.c @@ -509,6 +509,7 @@ NTSTATUS UsbPdo_BulkOrInterruptTransfer(PURB urb, WDFDEVICE Device, WDFREQUEST R NTSTATUS status; PPDO_DEVICE_DATA pdoData; WDFREQUEST notifyRequest; + PUCHAR blobBuffer; pdoData = PdoGetData(Device); @@ -544,6 +545,8 @@ NTSTATUS UsbPdo_BulkOrInterruptTransfer(PURB urb, WDFDEVICE Device, WDFREQUEST R TRACE_USBPDO, ">> >> >> Incoming request, queuing..."); + blobBuffer = WdfMemoryGetBuffer(xusb->InterruptBlobStorage, NULL); + if (XUSB_IS_DATA_PIPE(pTransfer)) { // @@ -553,57 +556,57 @@ NTSTATUS UsbPdo_BulkOrInterruptTransfer(PURB urb, WDFDEVICE Device, WDFREQUEST R { case 0: pTransfer->TransferBufferLength = XUSB_INIT_STAGE_SIZE; + xusb->InterruptInitStage++; RtlCopyMemory( pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], + &blobBuffer[XUSB_BLOB_00_OFFSET], XUSB_INIT_STAGE_SIZE - ); - xusb->InterruptInitStage++; + ); return STATUS_SUCCESS; case 1: pTransfer->TransferBufferLength = XUSB_INIT_STAGE_SIZE; - RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], - XUSB_INIT_STAGE_SIZE - ); xusb->InterruptInitStage++; + RtlCopyMemory( + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_01_OFFSET], + XUSB_INIT_STAGE_SIZE + ); return STATUS_SUCCESS; case 2: pTransfer->TransferBufferLength = XUSB_INIT_STAGE_SIZE; - RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], - XUSB_INIT_STAGE_SIZE - ); xusb->InterruptInitStage++; + RtlCopyMemory( + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_02_OFFSET], + XUSB_INIT_STAGE_SIZE + ); return STATUS_SUCCESS; case 3: pTransfer->TransferBufferLength = XUSB_INIT_STAGE_SIZE; - RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], - XUSB_INIT_STAGE_SIZE - ); xusb->InterruptInitStage++; + RtlCopyMemory( + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_03_OFFSET], + XUSB_INIT_STAGE_SIZE + ); return STATUS_SUCCESS; case 4: pTransfer->TransferBufferLength = sizeof(XUSB_INTERRUPT_IN_PACKET); - RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], - sizeof(XUSB_INTERRUPT_IN_PACKET) - ); xusb->InterruptInitStage++; + RtlCopyMemory( + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_04_OFFSET], + sizeof(XUSB_INTERRUPT_IN_PACKET) + ); return STATUS_SUCCESS; case 5: pTransfer->TransferBufferLength = XUSB_INIT_STAGE_SIZE; - RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[xusb->InterruptInitStage], - XUSB_INIT_STAGE_SIZE - ); xusb->InterruptInitStage++; + RtlCopyMemory( + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_05_OFFSET], + XUSB_INIT_STAGE_SIZE + ); return STATUS_SUCCESS; default: /* This request is sent periodically and relies on data the "feeder" @@ -620,10 +623,10 @@ NTSTATUS UsbPdo_BulkOrInterruptTransfer(PURB urb, WDFDEVICE Device, WDFREQUEST R if (!xusb->ReportedCapabilities && pTransfer->TransferBufferLength >= XUSB_INIT_STAGE_SIZE) { RtlCopyMemory( - pTransfer->TransferBuffer, - xusb->InterruptInitStageBlobs[0x06], + pTransfer->TransferBuffer, + &blobBuffer[XUSB_BLOB_06_OFFSET], XUSB_INIT_STAGE_SIZE - ); + ); xusb->ReportedCapabilities = TRUE; diff --git a/sys/xusb.c b/sys/xusb.c index 2f4d1ce..5e3bea2 100644 --- a/sys/xusb.c +++ b/sys/xusb.c @@ -243,8 +243,8 @@ NTSTATUS Xusb_PrepareHardware(WDFDEVICE Device) NTSTATUS Xusb_AssignPdoContext(WDFDEVICE Device) { NTSTATUS status; - WDF_OBJECT_ATTRIBUTES attributes; - ULONG index; + WDF_OBJECT_ATTRIBUTES attributes; + PUCHAR blobBuffer; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = Device; @@ -260,68 +260,41 @@ NTSTATUS Xusb_AssignPdoContext(WDFDEVICE Device) // Packet size (20 bytes = 0x14) xusb->Packet.Size = 0x14; - // Prepare blob storage - xusb->InterruptInitStageBlobs[0] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[1] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[2] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[3] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[4] = ExAllocatePoolWithTag( - NonPagedPoolNx, sizeof(XUSB_INTERRUPT_IN_PACKET), XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[5] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - xusb->InterruptInitStageBlobs[6] = ExAllocatePoolWithTag( - NonPagedPoolNx, XUSB_INIT_STAGE_SIZE, XUSB_POOL_TAG); - - // Validate allocations - for (index = 0; index < XUSB_INIT_BLOB_COUNT; index++) + // Allocate blob storage + status = WdfMemoryCreate( + &attributes, + NonPagedPoolNx, + XUSB_POOL_TAG, + XUSB_BLOB_STORAGE_SIZE, + &xusb->InterruptBlobStorage, + &blobBuffer + ); + if (!NT_SUCCESS(status)) { - // If even one allocation failed... - if (!xusb->InterruptInitStageBlobs[index]) - { - // ...re-enumerate... - for (index = 0; index < XUSB_INIT_BLOB_COUNT; index++) - { - // ...and free the ones who succeeded... - if (xusb->InterruptInitStageBlobs[index]) - // ...to not leak memory... - ExFreePoolWithTag(xusb->InterruptInitStageBlobs[index], VIGEM_POOL_TAG); - } - - // ...and abort with error - return STATUS_INSUFFICIENT_RESOURCES; - } + TraceEvents(TRACE_LEVEL_ERROR, + TRACE_XUSB, + "WdfMemoryCreate failed with status %!STATUS!", + status); + return status; } - /* - * Fill blobs - * - * Values obtained by reversing the communication of a physical pad. - */ - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[0], P99_PROTECT({ - 0x01, 0x03, 0x0E - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[1], P99_PROTECT({ - 0x02, 0x03, 0x00 - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[2], P99_PROTECT({ - 0x03, 0x03, 0x03 - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[3], P99_PROTECT({ - 0x08, 0x03, 0x00 - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[4], P99_PROTECT({ + // Fill blob storage + COPY_BYTE_ARRAY(blobBuffer, P99_PROTECT({ + // 0 + 0x01, 0x03, 0x0E, + // 1 + 0x02, 0x03, 0x00, + // 2 + 0x03, 0x03, 0x03, + // 3 + 0x08, 0x03, 0x00, + // 4 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xf2, 0xb3, 0xf8, 0x49, 0xf3, 0xb0, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[5], P99_PROTECT({ - 0x01, 0x03, 0x03 - })); - COPY_BYTE_ARRAY(xusb->InterruptInitStageBlobs[6], P99_PROTECT({ + 0x00, 0x00, 0x00, 0x00, + // 5 + 0x01, 0x03, 0x03, + // 6 0x05, 0x03, 0x00 }));