mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[NTOS:PO] Implement SystemBatteryState in NtPowerInformation
This should get us proper battery status display.
This commit is contained in:
+129
-9
@@ -784,6 +784,115 @@ NtInitiatePowerAction(IN POWER_ACTION SystemAction,
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
PopQueryBatteryState(
|
||||
_Out_ PSYSTEM_BATTERY_STATE BatteryState)
|
||||
{
|
||||
static const UNICODE_STRING CompBattDeviceName =
|
||||
RTL_CONSTANT_STRING(L"\\Device\\CompositeBattery");
|
||||
OBJECT_ATTRIBUTES ObjectAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(
|
||||
&CompBattDeviceName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE);
|
||||
HANDLE CompBattHandle;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
BATTERY_QUERY_INFORMATION BatteryQueryInfo = {0};
|
||||
BATTERY_INFORMATION BatteryInfo = { 0 };
|
||||
BATTERY_STATUS BatteryStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the CompositeBattery device */
|
||||
Status = ZwOpenFile(&CompBattHandle,
|
||||
GENERIC_READ | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to open CompositeBattery device: Status: 0x%08lX\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Query the battery tag */
|
||||
ULONG Wait = 0;
|
||||
Status = ZwDeviceIoControlFile(CompBattHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
IOCTL_BATTERY_QUERY_TAG,
|
||||
&Wait,
|
||||
sizeof(Wait),
|
||||
&BatteryQueryInfo.BatteryTag,
|
||||
sizeof(BatteryQueryInfo.BatteryTag));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to query battery tag: Status: 0x%08lX\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Query the battery information */
|
||||
BatteryQueryInfo.InformationLevel = BatteryInformation;
|
||||
Status = ZwDeviceIoControlFile(CompBattHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
IOCTL_BATTERY_QUERY_INFORMATION,
|
||||
&BatteryQueryInfo,
|
||||
sizeof(BatteryQueryInfo),
|
||||
&BatteryInfo,
|
||||
sizeof(BatteryInfo));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to query battery information: Status: 0x%08lX\n", Status);
|
||||
}
|
||||
|
||||
/* Query the battery status */
|
||||
BATTERY_WAIT_STATUS BatteryWait = {0};
|
||||
BatteryWait.BatteryTag = BatteryQueryInfo.BatteryTag;
|
||||
BatteryWait.PowerState = 0xF ; // Wait for all power states
|
||||
BatteryWait.HighCapacity = MAXULONG;
|
||||
Status = ZwDeviceIoControlFile(CompBattHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
IOCTL_BATTERY_QUERY_STATUS,
|
||||
&BatteryWait,
|
||||
sizeof(BatteryWait),
|
||||
&BatteryStatus,
|
||||
sizeof(BatteryStatus));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to query battery status: Status: 0x%08lX\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
RtlZeroMemory(BatteryState, sizeof(*BatteryState));
|
||||
BatteryState->BatteryPresent = TRUE;
|
||||
BatteryState->AcOnLine = BooleanFlagOn(BatteryStatus.PowerState, BATTERY_POWER_ON_LINE);
|
||||
BatteryState->Charging = BooleanFlagOn(BatteryStatus.PowerState, BATTERY_CHARGING);
|
||||
BatteryState->Discharging = BooleanFlagOn(BatteryStatus.PowerState, BATTERY_DISCHARGING);
|
||||
BatteryState->MaxCapacity = BatteryInfo.FullChargedCapacity;
|
||||
BatteryState->RemainingCapacity = BatteryStatus.Capacity;
|
||||
BatteryState->Rate = BatteryStatus.Rate;
|
||||
if (BatteryState->Discharging && BatteryStatus.Rate < 0)
|
||||
{
|
||||
BatteryState->EstimatedTime =
|
||||
3600 * BatteryInfo.FullChargedCapacity / -BatteryStatus.Rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
BatteryState->EstimatedTime = 0;
|
||||
}
|
||||
|
||||
Exit:
|
||||
ZwClose(CompBattHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
@@ -824,23 +933,34 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel,
|
||||
{
|
||||
case SystemBatteryState:
|
||||
{
|
||||
PSYSTEM_BATTERY_STATE BatteryState = (PSYSTEM_BATTERY_STATE)OutputBuffer;
|
||||
SYSTEM_BATTERY_STATE BatteryState;
|
||||
|
||||
if (InputBuffer != NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (OutputBufferLength < sizeof(SYSTEM_BATTERY_STATE))
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
if (PopCapabilities.SystemBatteriesPresent)
|
||||
{
|
||||
/* Open the battery driver and query the battery state */
|
||||
Status = PopQueryBatteryState(&BatteryState);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to query battery state: Status: 0x%08X\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No batteries present, set defaults */
|
||||
RtlZeroMemory(&BatteryState, sizeof(BatteryState));
|
||||
BatteryState.AcOnLine = TRUE;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Just zero the struct */
|
||||
RtlZeroMemory(BatteryState, sizeof(*BatteryState));
|
||||
BatteryState->EstimatedTime = MAXULONG;
|
||||
BatteryState->BatteryPresent = PopCapabilities.SystemBatteriesPresent;
|
||||
// BatteryState->AcOnLine = TRUE;
|
||||
// BatteryState->MaxCapacity = ;
|
||||
// BatteryState->RemainingCapacity = ;
|
||||
|
||||
/* Copy the battery state to the output buffer */
|
||||
RtlCopyMemory(OutputBuffer, &BatteryState, sizeof(BatteryState));
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
||||
@@ -386,7 +386,8 @@ typedef struct {
|
||||
BOOLEAN BatteryPresent;
|
||||
BOOLEAN Charging;
|
||||
BOOLEAN Discharging;
|
||||
BOOLEAN Spare1[4];
|
||||
BOOLEAN Spare1[3];
|
||||
UCHAR Tag;
|
||||
ULONG MaxCapacity;
|
||||
ULONG RemainingCapacity;
|
||||
ULONG Rate;
|
||||
|
||||
Reference in New Issue
Block a user