From db734f67360cbe4750d1df7c2bea34afa12230b4 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 22 Mar 2010 04:12:02 +0000 Subject: [PATCH] [CMBATT]: CmBattIoctl: Add handling for the direct-access undocumented IOCTLs. Some PnP glue remains, as well as the ACPI routines, and the driver is done. svn path=/trunk/; revision=46338 --- reactos/drivers/bus/acpi/cmbatt/cmbatt.c | 149 ++++++++++++++++++++++- reactos/drivers/bus/acpi/cmbatt/cmbatt.h | 25 ++++ 2 files changed, 169 insertions(+), 5 deletions(-) diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbatt.c b/reactos/drivers/bus/acpi/cmbatt/cmbatt.c index 445d71f0660..2ce7b2c8ed3 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbatt.c +++ b/reactos/drivers/bus/acpi/cmbatt/cmbatt.c @@ -353,6 +353,8 @@ CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, { PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; + PIO_STACK_LOCATION IoStackLocation; + ULONG IoControlCode, OutputBufferLength, InputBufferLength; PAGED_CODE(); if (CmBattDebug & 2) DbgPrint("CmBattIoctl\n"); @@ -380,11 +382,148 @@ CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp); if (Status == STATUS_NOT_SUPPORTED) { - /* FIXME: Should handle custom codes here */ - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Read IOCTL information from IRP stack */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; + OutputBufferLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; + InputBufferLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; + if (CmBattDebug & 4) + DbgPrint("CmBattIoctl: Received Direct Access IOCTL %x\n", IoControlCode); + + /* Handle internal IOCTLs */ + switch (IoControlCode) + { + case IOCTL_BATTERY_QUERY_UNIQUE_ID: + + /* Data is 4 bytes long */ + if (OutputBufferLength == sizeof(ULONG)) + { + /* Query it */ + Status = CmBattGetUniqueId(DeviceExtension->PdoDeviceObject, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG); + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } + break; + + case IOCTL_BATTERY_QUERY_STA: + + /* Data is 4 bytes long */ + if (OutputBufferLength == sizeof(ULONG)) + { + /* Query it */ + Status = CmBattGetStaData(DeviceExtension->PdoDeviceObject, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG); + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } + break; + + case IOCTL_BATTERY_QUERY_PSR: + + /* Data is 4 bytes long */ + if (OutputBufferLength == sizeof(ULONG)) + { + /* Do we have an AC adapter? */ + if (AcAdapterPdo) + { + /* Query it */ + Status = CmBattGetPsrData(AcAdapterPdo, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG); + } + else + { + /* No adapter, just a battery, so fail */ + Status = STATUS_NO_SUCH_DEVICE; + } + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } + break; + + case IOCTL_BATTERY_SET_TRIP_POINT: + + /* Data is 4 bytes long */ + if (InputBufferLength == sizeof(ULONG)) + { + /* Query it */ + Status = CmBattSetTripPpoint(DeviceExtension, + *(PULONG)Irp->AssociatedIrp.SystemBuffer); + Irp->IoStatus.Information = 0; + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; } + break; + + case IOCTL_BATTERY_QUERY_BIF: + + /* Data is 1060 bytes long */ + if (OutputBufferLength == sizeof(ACPI_BIF_DATA)) + { + /* Query it */ + Status = CmBattGetBifData(DeviceExtension, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA); + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } + break; + + case IOCTL_BATTERY_QUERY_BST: + + /* Data is 16 bytes long */ + if (OutputBufferLength == sizeof(ACPI_BST_DATA)) + { + /* Query it */ + Status = CmBattGetBstData(DeviceExtension, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BST_DATA); + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } + break; + + default: + + /* Unknown, let us pass it on to ACPI */ + if (CmBattDebug & 0xC) + DbgPrint("CmBattIoctl: Unknown IOCTL %x\n", IoControlCode); + break; + } + + /* Did someone pick it up? */ + if (Status != STATUS_NOT_SUPPORTED) + { + /* Complete the request */ + Irp->IoStatus.Status = Status; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + { + /* Still unsupported, try ACPI */ + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } } /* Release the remove lock and return status */ diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbatt.h b/reactos/drivers/bus/acpi/cmbatt/cmbatt.h index 1b329533d69..8f952d20200 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbatt.h +++ b/reactos/drivers/bus/acpi/cmbatt/cmbatt.h @@ -14,6 +14,24 @@ #include #include +#define IOCTL_BATTERY_QUERY_UNIQUE_ID \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x101, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294404 + +#define IOCTL_BATTERY_QUERY_STA \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x102, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294408 + +#define IOCTL_BATTERY_QUERY_PSR \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x103, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x29440C + +#define IOCTL_BATTERY_SET_TRIP_POINT \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x104, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294410 + +#define IOCTL_BATTERY_QUERY_BIF \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x105, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294414 + +#define IOCTL_BATTERY_QUERY_BST \ + CTL_CODE(FILE_DEVICE_BATTERY, 0x106, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294418 + #define CMBATT_GENERIC_STATUS 0x01 #define CMBATT_GENERIC_INFO 0x02 #define CMBATT_GENERIC_WARNING 0x04 @@ -177,6 +195,13 @@ CmBattGetStaData( PULONG StaData ); +NTSTATUS +NTAPI +CmBattGetBifData( + PCMBATT_DEVICE_EXTENSION DeviceExtension, + PACPI_BIF_DATA BifData +); + NTSTATUS NTAPI CmBattSetTripPpoint(