Author: sir_richard Date: Sat Mar 20 22:25:40 2010 New Revision: 46288
URL: http://svn.reactos.org/svn/reactos?rev=46288&view=rev Log: [CMBATT]: Implement CmBattQueryInformation and CmBattQueryStatus.
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/cmbatt/cmb... ============================================================================== --- trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c [iso-8859-1] Sat Mar 20 22:25:40 2010 @@ -74,7 +74,7 @@
NTSTATUS NTAPI -CmBattVerifyStaticInfo(ULONG StaData, +CmBattVerifyStaticInfo(PCMBATT_DEVICE_EXTENSION DeviceExtension, ULONG BatteryTag) { UNIMPLEMENTED; @@ -191,26 +191,246 @@
NTSTATUS NTAPI -CmBattQueryInformation(PCMBATT_DEVICE_EXTENSION DeviceExtension, - ULONG BatteryTag, - BATTERY_QUERY_INFORMATION_LEVEL Level, - OPTIONAL LONG AtRate, - PVOID Buffer, - ULONG BufferLength, - PULONG ReturnedLength) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -CmBattQueryStatus(PCMBATT_DEVICE_EXTENSION DeviceExtension, - ULONG BatteryTag, - PBATTERY_STATUS BatteryStatus) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; +CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, + IN ULONG Tag, + IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, + IN OPTIONAL LONG AtRate, + IN PVOID Buffer, + IN ULONG BufferLength, + OUT PULONG ReturnedLength) +{ + NTSTATUS Status; + PVOID QueryData = NULL; + ULONG QueryLength = 0; + ULONG RemainingTime = 0; + ANSI_STRING TempString; + UNICODE_STRING TempString2; + WCHAR InfoBuffer[256]; + WCHAR TempBuffer[256]; + UNICODE_STRING InfoString; + ULONG RemainingCapacity; + BATTERY_REPORTING_SCALE BatteryReportingScale[2]; + LONG Rate; + PAGED_CODE(); + if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO)) + DbgPrint("CmBattQueryInformation - Tag (%d) Device %d, Informationlevel %d\n", + Tag, + FdoExtension->DeviceId, + InfoLevel); + + /* Check ACPI Data */ + Status = CmBattVerifyStaticInfo(FdoExtension, Tag); + if (!NT_SUCCESS(Status)) return Status; + + /* Check what caller wants */ + switch (InfoLevel) + { + case BatteryInformation: + /* Just return our static information */ + QueryData = &FdoExtension->BatteryInformation; + QueryLength = sizeof(BATTERY_INFORMATION); + break; + + case BatteryGranularityInformation: + + /* Return our static information, we have two scales */ + BatteryReportingScale[0].Granularity = FdoExtension->BatteryCapacityGranularity1; + BatteryReportingScale[0].Capacity = FdoExtension->BatteryInformation.DefaultAlert1; + BatteryReportingScale[1].Granularity = FdoExtension->BatteryCapacityGranularity2; + BatteryReportingScale[1].Capacity = FdoExtension->BatteryInformation.DesignedCapacity; + QueryData = BatteryReportingScale; + QueryLength = sizeof(BATTERY_REPORTING_SCALE) * 2; + break; + + case BatteryEstimatedTime: + + /* Check if it's been more than 2 1/2 minutes since the last change */ + if ((KeQueryInterruptTime() - 150000000) > (FdoExtension->InterruptTime)) + { + /* Get new battery status */ + CmBattGetBatteryStatus(FdoExtension, FdoExtension->Tag); + + /* If the caller didn't specify a rate, use our static one */ + Rate = AtRate; + if (!Rate) Rate = FdoExtension->Rate; + + /* If we don't have a valid negative rate, use unknown value */ + if (Rate >= 0) Rate = BATTERY_UNKNOWN_RATE; + + /* Grab the remaining capacity */ + RemainingCapacity = FdoExtension->RemainingCapacity; + + /* See if we don't know one or the other */ + if ((Rate == BATTERY_UNKNOWN_RATE) || + (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)) + { + /* If the battery is discharging, we can't give out a time */ + if ((FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG) && + (CmBattDebug & CMBATT_GENERIC_WARNING)) + DbgPrint("CmBattQueryInformation: Can't calculate EstimatedTime.\n"); + + /* Check if we don't have a rate and capacity is going down */ + if ((FdoExtension->Rate == BATTERY_UNKNOWN_RATE) && + (FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG)) + { + /* We have to fail, since we lack data */ + Status = STATUS_INVALID_DEVICE_REQUEST; + if (CmBattDebug & CMBATT_GENERIC_WARNING) + DbgPrint("---------------------- PresentRate = BATTERY_UNKNOWN_RATE\n"); + } + + /* If we don't have capacity, the rate is useless */ + if (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY) + { + /* We have to fail the request */ + Status = STATUS_INVALID_DEVICE_REQUEST; + if (CmBattDebug & CMBATT_GENERIC_WARNING) + DbgPrint("---------------------- RemainingCapacity = BATTERY_UNKNOWN_CAPACITY\n"); + } + } + else + { + /* We have data, but is it valid? */ + if (RemainingCapacity > 0x123456) + { + /* The capacity seems bogus, so don't use it */ + if (CmBattDebug & CMBATT_ACPI_WARNING) + DbgPrint("CmBattQueryInformation: Data Overflow in calculating Remaining Capacity.\n"); + } + else + { + /* Compute the remaining time in seconds, based on rate */ + RemainingTime = (RemainingCapacity * 3600) / -Rate; + } + } + } + + /* Return the remaining time */ + QueryData = &RemainingTime; + QueryLength = sizeof(ULONG); + break; + + case BatteryDeviceName: + + /* Build the model number string */ + RtlInitAnsiString(&TempString, FdoExtension->ModelNumber); + + /* Convert it to Unicode */ + InfoString.Buffer = InfoBuffer; + InfoString.MaximumLength = sizeof(InfoBuffer); + Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0); + + /* Return the unicode buffer */ + QueryData = InfoString.Buffer; + QueryLength = InfoString.Length; + break; + + case BatteryTemperature: + case BatteryManufactureDate: + + /* We don't support these */ + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + + case BatteryManufactureName: + + /* Build the OEM info string */ + RtlInitAnsiString(&TempString, FdoExtension->OemInfo); + + /* Convert it to Unicode */ + InfoString.Buffer = InfoBuffer; + InfoString.MaximumLength = sizeof(InfoBuffer); + Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0); + + /* Return the unicode buffer */ + QueryData = InfoString.Buffer; + QueryLength = InfoString.Length; + break; + + case BatteryUniqueID: + + /* Build the serial number string */ + RtlInitAnsiString(&TempString, FdoExtension->SerialNumber); + + /* Convert it to Unicode */ + InfoString.Buffer = InfoBuffer; + InfoString.MaximumLength = sizeof(InfoBuffer); + RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0); + + /* Setup a temporary string for concatenation */ + TempString2.Buffer = TempBuffer; + TempString2.MaximumLength = sizeof(TempBuffer); + + /* Check if there's an OEM string */ + if (FdoExtension->OemInfo[0]) + { + /* Build the OEM info string */ + RtlInitAnsiString(&TempString, FdoExtension->OemInfo); + + /* Convert it to Unicode and append it */ + RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0); + RtlAppendUnicodeStringToString(&InfoString, &TempString2); + } + + /* Build the model number string */ + RtlInitAnsiString(&TempString, FdoExtension->ModelNumber); + + /* Convert it to Unicode and append it */ + RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0); + RtlAppendUnicodeStringToString(&InfoString, &TempString2); + + /* Return the final appended string */ + QueryData = InfoString.Buffer; + QueryLength = InfoString.Length; + break; + + default: + + /* Everything else is unknown */ + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Return the required length and check if the caller supplied enough */ + *ReturnedLength = QueryLength; + if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL; + + /* Copy the data if there's enough space and it exists */ + if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength); + + /* Return function result */ + return Status; +} + +NTSTATUS +NTAPI +CmBattQueryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, + IN ULONG Tag, + IN PBATTERY_STATUS BatteryStatus) +{ + NTSTATUS Status; + PAGED_CODE(); + if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO)) + DbgPrint("CmBattQueryStatus - Tag (%d) Device %x\n", Tag, DeviceExtension->DeviceId); + + /* Query ACPI information */ + Status = CmBattGetBatteryStatus(DeviceExtension, Tag); + if (NT_SUCCESS(Status)) + { + BatteryStatus->PowerState = DeviceExtension->State; + BatteryStatus->Capacity = DeviceExtension->RemainingCapacity; + BatteryStatus->Voltage = DeviceExtension->PresentVoltage; + BatteryStatus->Rate = DeviceExtension->Rate; + } + + /* Return status */ + if (CmBattDebug & (CMBATT_GENERIC_INFO)) + DbgPrint("CmBattQueryStatus: Returning [%#08lx][%#08lx][%#08lx][%#08lx]\n", + BatteryStatus->PowerState, + BatteryStatus->Capacity, + BatteryStatus->Voltage, + BatteryStatus->Rate); + return Status; }
NTSTATUS @@ -233,20 +453,16 @@ { /* Fail if we're out of memory this early */ if (CmBattDebug & CMBATT_GENERIC_WARNING) - { DbgPrint("CmBatt: Couldn't allocate pool for registry path."); - } return STATUS_INSUFFICIENT_RESOURCES; }
/* Buffer allocated, copy the string */ RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath); if (CmBattDebug & CMBATT_GENERIC_INFO) - { DbgPrint("CmBatt DriverEntry - Obj (%08x) Path "%ws"\n", DriverObject, RegistryPath->Buffer); - }
/* Setup the major dispatchers */ DriverObject->MajorFunction[0] = CmBattOpenClose; @@ -276,9 +492,7 @@ /* No callback, fail */ CmBattPowerCallBackObject = 0; if (CmBattDebug & CMBATT_GENERIC_WARNING) - { DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status); - } } else { @@ -296,9 +510,7 @@ { ObfDereferenceObject(CmBattPowerCallBackObject); if (CmBattDebug & CMBATT_GENERIC_WARNING) - { DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n"); - } }
/* All good */
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/cmbatt/cmb... ============================================================================== --- trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h [iso-8859-1] Sat Mar 20 22:25:40 2010 @@ -28,6 +28,12 @@ CmBattAcAdapter, CmBattBattery } CMBATT_EXTENSION_TYPE; + +#define ACPI_BATT_STAT_DISCHARG 0x0001 +#define ACPI_BATT_STAT_CHARGING 0x0002 +#define ACPI_BATT_STAT_CRITICAL 0x0004 +#define ACPI_BATT_STAT_NOT_PRESENT 0x0007 +#define ACPI_BATT_STAT_MAX 0x0007
typedef struct _ACPI_BST_DATA { @@ -93,7 +99,7 @@ ULONG RemainingCapacity; ULONG PresentVoltage; ULONG Rate; - BATTERY_INFORMATION StaticBatteryInformation; + BATTERY_INFORMATION BatteryInformation; ULONG BatteryCapacityGranularity1; ULONG BatteryCapacityGranularity2; BOOLEAN TripPointSet;