mirror of
https://github.com/reactos/reactos
synced 2025-10-06 08:22:58 +02:00
[BATTC] Fix IOCTL_BATTERY_QUERY_STATUS
Previously the function waited for the conditions *after* querying the status, and then returned the old status. Also, if querying failed, it waited and when the wait timed out it returned STATUS_SUCCESS without returning any data. If the call to SetStatusNotify failed and there was no timeout, it would wait forever. This is all fixed now.
This commit is contained in:
@@ -281,25 +281,20 @@ BatteryClassIoctl(PVOID ClassData,
|
|||||||
|
|
||||||
BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer;
|
BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -10000);
|
if (BattWait.Timeout != 0)
|
||||||
|
|
||||||
BattStatus = Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
|
|
||||||
BattWait.BatteryTag,
|
|
||||||
BattStatus);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status) ||
|
|
||||||
(BattWait.PowerState == BattStatus->PowerState &&
|
|
||||||
BattWait.HighCapacity >= BattStatus->Capacity &&
|
|
||||||
BattWait.LowCapacity <= BattStatus->Capacity))
|
|
||||||
{
|
{
|
||||||
BattNotify.PowerState = BattWait.PowerState;
|
BattNotify.PowerState = BattWait.PowerState;
|
||||||
BattNotify.HighCapacity = BattWait.HighCapacity;
|
BattNotify.HighCapacity = BattWait.HighCapacity;
|
||||||
BattNotify.LowCapacity = BattWait.LowCapacity;
|
BattNotify.LowCapacity = BattWait.LowCapacity;
|
||||||
|
|
||||||
BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
|
Status = BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
|
||||||
BattWait.BatteryTag,
|
BattWait.BatteryTag,
|
||||||
&BattNotify);
|
&BattNotify);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SetStatusNotify failed (0x%x)\n", Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ExAcquireFastMutex(&BattClass->Mutex);
|
ExAcquireFastMutex(&BattClass->Mutex);
|
||||||
BattClass->EventTrigger = EVENT_BATTERY_STATUS;
|
BattClass->EventTrigger = EVENT_BATTERY_STATUS;
|
||||||
@@ -307,6 +302,7 @@ BatteryClassIoctl(PVOID ClassData,
|
|||||||
BattClass->Waiting = TRUE;
|
BattClass->Waiting = TRUE;
|
||||||
ExReleaseFastMutex(&BattClass->Mutex);
|
ExReleaseFastMutex(&BattClass->Mutex);
|
||||||
|
|
||||||
|
Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -10000);
|
||||||
Status = KeWaitForSingleObject(&BattClass->WaitEvent,
|
Status = KeWaitForSingleObject(&BattClass->WaitEvent,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
@@ -321,7 +317,15 @@ BatteryClassIoctl(PVOID ClassData,
|
|||||||
|
|
||||||
BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
|
BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Zero the output buffer to prevent leakage of kernel data */
|
||||||
|
BattStatus = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
RtlZeroMemory(BattStatus, sizeof(BATTERY_STATUS));
|
||||||
|
|
||||||
|
Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
|
||||||
|
BattWait.BatteryTag,
|
||||||
|
BattStatus);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
|
Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user