Fixed BAD_POOL_HEADER issue

This commit is contained in:
Benjamin Höglinger-Stelzer
2018-09-30 22:53:35 +02:00
parent 31d65aa40e
commit c5a46e884b
5 changed files with 77 additions and 137 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.
//

View File

@@ -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;

View File

@@ -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
}));