ReactOS 0.4.16-dev-737-g3368adc
compbatt.h File Reference
#include <wdm.h>
#include <batclass.h>
Include dependency graph for compbatt.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _COMPBATT_BATTERY_DATA
 
struct  _COMPBATT_DEVICE_EXTENSION
 

Macros

#define COMPBATT_TAG   'aBoC'
 
#define COMPBATT_BATTERY_INFORMATION_PRESENT   0x04
 
#define COMPBATT_STATUS_NOTIFY_SET   0x10
 
#define COMPBATT_TAG_ASSIGNED   0x80
 
#define COMPBATT_QUERY_TAG   1
 
#define COMPBATT_READ_STATUS   2
 
#define COMPBATT_WAIT_MIN_LOW_CAPACITY   0
 
#define COMPBATT_WAIT_MAX_HIGH_CAPACITY   0x7FFFFFFF
 
#define COMPBATT_ATRATE_HOUR_IN_SECS   3600
 
#define COMPBATT_FRESH_STATUS_TIME   50000000
 
#define COMPUTE_BATT_CAP_DELTA(LowDiff, Batt, TotalRate)    ((ULONG)(((LONGLONG)LowDiff * (Batt)->BatteryStatus.Rate) / TotalRate))
 
#define COMPUTE_ATRATE_DRAIN(Batt, Time)    ((LONG)((Batt)->BatteryStatus.Capacity) * COMPBATT_ATRATE_HOUR_IN_SECS / Time)
 
#define COMPBATT_DEBUG_INFO   0x1
 
#define COMPBATT_DEBUG_TRACE   0x2
 
#define COMPBATT_DEBUG_WARN   0x4
 
#define COMPBATT_DEBUG_ERR   0x10
 
#define COMPBATT_DEBUG_ALL_LEVELS   (COMPBATT_DEBUG_INFO | COMPBATT_DEBUG_TRACE | COMPBATT_DEBUG_WARN | COMPBATT_DEBUG_ERR)
 

Typedefs

typedef struct _COMPBATT_BATTERY_DATA COMPBATT_BATTERY_DATA
 
typedef struct _COMPBATT_BATTERY_DATAPCOMPBATT_BATTERY_DATA
 
typedef struct _COMPBATT_DEVICE_EXTENSION COMPBATT_DEVICE_EXTENSION
 
typedef struct _COMPBATT_DEVICE_EXTENSIONPCOMPBATT_DEVICE_EXTENSION
 

Functions

NTSTATUS NTAPI CompBattAddDevice (_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PdoDeviceObject)
 
NTSTATUS NTAPI CompBattPowerDispatch (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI CompBattPnpDispatch (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI CompBattQueryInformation (_In_ PCOMPBATT_DEVICE_EXTENSION FdoExtension, _In_ ULONG Tag, _In_ BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, _In_opt_ LONG AtRate, _In_ PVOID Buffer, _In_ ULONG BufferLength, _Out_ PULONG ReturnedLength)
 
NTSTATUS NTAPI CompBattQueryStatus (_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Tag, _Out_ PBATTERY_STATUS BatteryStatus)
 Queries the battery status of each individiual connected battery with the composite battery and combines all the retrieved data as one single battery status for the composite battery.
 
NTSTATUS NTAPI CompBattGetEstimatedTime (_Out_ PULONG Time, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
 Retrieves the estimated time of the composite battery based on the power drain rate of all the batteries present in the system.
 
NTSTATUS NTAPI CompBattSetStatusNotify (_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG BatteryTag, _In_ PBATTERY_NOTIFY BatteryNotify)
 Sets a new configuration battery wait status settings of each battery. The purpose of this is so that the composite battery gets notified of new battery status as if it was a single battery.
 
NTSTATUS NTAPI CompBattDisableStatusNotify (_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI CompBattQueryTag (_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG Tag)
 
NTSTATUS NTAPI CompBattMonitorIrpComplete (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PVOID Context)
 Queues a work item thread worker which is bound to the individual CM (Control Method) ACPI battery to handle the IRP.
 
VOID NTAPI CompBattMonitorIrpCompleteWorker (_In_ PCOMPBATT_BATTERY_DATA BatteryData)
 The brains of the battery IRP worker. It monitors the state of the IRP as well as sends the IRP down the device stack to gather battery related data, such tag and status. It also serves as the I/O completion routine of which it elaborates the gathered data.
 
NTSTATUS NTAPI CompBattGetDeviceObjectPointer (_In_ PUNICODE_STRING DeviceName, _In_ ACCESS_MASK DesiredAccess, _Out_ PFILE_OBJECT *FileObject, _Out_ PDEVICE_OBJECT *DeviceObject)
 
NTSTATUS NTAPI BatteryIoctl (_In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_ PVOID OutputBuffer, _Inout_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl)
 
NTSTATUS NTAPI CompBattRemoveBattery (_In_ PUNICODE_STRING BatteryName, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
 

Variables

ULONG CompBattDebug
 

Macro Definition Documentation

◆ COMPBATT_ATRATE_HOUR_IN_SECS

#define COMPBATT_ATRATE_HOUR_IN_SECS   3600

Definition at line 46 of file compbatt.h.

◆ COMPBATT_BATTERY_INFORMATION_PRESENT

#define COMPBATT_BATTERY_INFORMATION_PRESENT   0x04

Definition at line 27 of file compbatt.h.

◆ COMPBATT_DEBUG_ALL_LEVELS

Definition at line 72 of file compbatt.h.

◆ COMPBATT_DEBUG_ERR

#define COMPBATT_DEBUG_ERR   0x10

Definition at line 71 of file compbatt.h.

◆ COMPBATT_DEBUG_INFO

#define COMPBATT_DEBUG_INFO   0x1

Definition at line 68 of file compbatt.h.

◆ COMPBATT_DEBUG_TRACE

#define COMPBATT_DEBUG_TRACE   0x2

Definition at line 69 of file compbatt.h.

◆ COMPBATT_DEBUG_WARN

#define COMPBATT_DEBUG_WARN   0x4

Definition at line 70 of file compbatt.h.

◆ COMPBATT_FRESH_STATUS_TIME

#define COMPBATT_FRESH_STATUS_TIME   50000000

Definition at line 51 of file compbatt.h.

◆ COMPBATT_QUERY_TAG

#define COMPBATT_QUERY_TAG   1

Definition at line 34 of file compbatt.h.

◆ COMPBATT_READ_STATUS

#define COMPBATT_READ_STATUS   2

Definition at line 35 of file compbatt.h.

◆ COMPBATT_STATUS_NOTIFY_SET

#define COMPBATT_STATUS_NOTIFY_SET   0x10

Definition at line 28 of file compbatt.h.

◆ COMPBATT_TAG

#define COMPBATT_TAG   'aBoC'

Definition at line 22 of file compbatt.h.

◆ COMPBATT_TAG_ASSIGNED

#define COMPBATT_TAG_ASSIGNED   0x80

Definition at line 29 of file compbatt.h.

◆ COMPBATT_WAIT_MAX_HIGH_CAPACITY

#define COMPBATT_WAIT_MAX_HIGH_CAPACITY   0x7FFFFFFF

Definition at line 41 of file compbatt.h.

◆ COMPBATT_WAIT_MIN_LOW_CAPACITY

#define COMPBATT_WAIT_MIN_LOW_CAPACITY   0

Definition at line 40 of file compbatt.h.

◆ COMPUTE_ATRATE_DRAIN

#define COMPUTE_ATRATE_DRAIN (   Batt,
  Time 
)     ((LONG)((Batt)->BatteryStatus.Capacity) * COMPBATT_ATRATE_HOUR_IN_SECS / Time)

Definition at line 62 of file compbatt.h.

◆ COMPUTE_BATT_CAP_DELTA

#define COMPUTE_BATT_CAP_DELTA (   LowDiff,
  Batt,
  TotalRate 
)     ((ULONG)(((LONGLONG)LowDiff * (Batt)->BatteryStatus.Rate) / TotalRate))

Definition at line 56 of file compbatt.h.

Typedef Documentation

◆ COMPBATT_BATTERY_DATA

◆ COMPBATT_DEVICE_EXTENSION

◆ PCOMPBATT_BATTERY_DATA

◆ PCOMPBATT_DEVICE_EXTENSION

Function Documentation

◆ BatteryIoctl()

NTSTATUS NTAPI BatteryIoctl ( _In_ ULONG  IoControlCode,
_In_ PDEVICE_OBJECT  DeviceObject,
_In_ PVOID  InputBuffer,
_In_ ULONG  InputBufferLength,
_Out_ PVOID  OutputBuffer,
_Inout_ ULONG  OutputBufferLength,
_In_ BOOLEAN  InternalDeviceIoControl 
)

Definition at line 16 of file compmisc.c.

24{
28 PIRP Irp;
29 PAGED_CODE();
30 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING BatteryIoctl\n");
31
32 /* Initialize the event and IRP */
41 &Event,
43 if (Irp)
44 {
45 /* Call the class driver miniport */
48 {
49 /* Wait for result */
52 }
53
54 /* Print failure */
56 DbgPrint("BatteryIoctl: Irp failed - %x\n", Status);
57
58 /* Done */
59 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING BatteryIoctl\n");
60 }
61 else
62 {
63 /* Out of memory */
64 if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("BatteryIoctl: couldn't create Irp\n");
66 }
67
68 /* Return status */
69 return Status;
70}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
ULONG CompBattDebug
Definition: compbatt.c:17
#define COMPBATT_DEBUG_ERR
Definition: compbatt.h:71
#define COMPBATT_DEBUG_TRACE
Definition: compbatt.h:69
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define KernelMode
Definition: asm.h:38
@ SynchronizationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720
@ Executive
Definition: ketypes.h:415

Referenced by CompBattCalculateAtRateTime(), CompBattGetBatteryGranularity(), CompBattGetBatteryInformation(), CompBattGetEstimatedTime(), and CompBattQueryStatus().

◆ CompBattAddDevice()

NTSTATUS NTAPI CompBattAddDevice ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PDEVICE_OBJECT  PdoDeviceObject 
)

Definition at line 328 of file comppnp.c.

331{
334 PCOMPBATT_DEVICE_EXTENSION DeviceExtension;
337 BATTERY_MINIPORT_INFO MiniportInfo;
338 if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject);
339
340 /* Create the device */
341 RtlInitUnicodeString(&DeviceName, L"\\Device\\CompositeBattery");
344 &DeviceName,
347 FALSE,
348 &DeviceObject);
349 if (!NT_SUCCESS(Status)) return Status;
350
351 /* Setup symbolic link for Win32 access */
352 RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\CompositeBattery");
354
355 /* Initialize the device extension */
356 DeviceExtension = DeviceObject->DeviceExtension;
357 RtlZeroMemory(DeviceExtension, sizeof(COMPBATT_DEVICE_EXTENSION));
358
359 /* Attach to device stack and set DO pointers */
362 DeviceExtension->DeviceObject = DeviceObject;
363 if (!DeviceExtension->AttachedDevice)
364 {
365 /* Fail */
367 DbgPrint("CompBattAddDevice: Could not attach to LowerDevice.\n");
369 return STATUS_UNSUCCESSFUL;
370 }
371
372 /* Set device object flags */
374 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
375
376 /* Setup the device extension */
377 ExInitializeFastMutex(&DeviceExtension->Lock);
378 InitializeListHead(&DeviceExtension->BatteryList);
379 DeviceExtension->Flags = 0;
380 DeviceExtension->NextTag = 1;
381
382 /* Setup the miniport data */
383 RtlZeroMemory(&MiniportInfo, sizeof(MiniportInfo));
386 MiniportInfo.Context = DeviceExtension;
387 MiniportInfo.DeviceName = &DeviceName;
390 MiniportInfo.SetInformation = NULL;
394 MiniportInfo.Pdo = NULL;
395
396 /* Register with the class driver */
397 Status = BatteryClassInitializeDevice(&MiniportInfo,
398 &DeviceExtension->ClassData);
399 if (!NT_SUCCESS(Status))
400 {
401 /* Undo everything */
402 IoDetachDevice(DeviceExtension->AttachedDevice);
404 }
405
406 /* Return status */
407 return Status;
408}
#define BATTERY_CLASS_MAJOR_VERSION
Definition: batclass.h:163
PBCLASS_QUERY_INFORMATION_CALLBACK BCLASS_QUERY_INFORMATION
Definition: batclass.h:241
PBCLASS_SET_STATUS_NOTIFY_CALLBACK BCLASS_SET_STATUS_NOTIFY
Definition: batclass.h:243
PBCLASS_DISABLE_STATUS_NOTIFY_CALLBACK BCLASS_DISABLE_STATUS_NOTIFY
Definition: batclass.h:245
#define BATTERY_CLASS_MINOR_VERSION
Definition: batclass.h:164
PBCLASS_QUERY_STATUS_CALLBACK BCLASS_QUERY_STATUS
Definition: batclass.h:242
PBCLASS_QUERY_TAG_CALLBACK BCLASS_QUERY_TAG
Definition: batclass.h:240
BCLASSAPI NTSTATUS NTAPI BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo, PVOID *ClassData)
Definition: battc.c:146
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
NTSTATUS NTAPI CompBattQueryInformation(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Tag, _In_ BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, _In_opt_ LONG AtRate, _In_ PVOID Buffer, _In_ ULONG BufferLength, _Out_ PULONG ReturnedLength)
Definition: compbatt.c:1656
NTSTATUS NTAPI CompBattQueryStatus(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Tag, _Out_ PBATTERY_STATUS BatteryStatus)
Queries the battery status of each individiual connected battery with the composite battery and combi...
Definition: compbatt.c:932
NTSTATUS NTAPI CompBattQueryTag(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG Tag)
Definition: compbatt.c:453
NTSTATUS NTAPI CompBattSetStatusNotify(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG BatteryTag, _In_ PBATTERY_NOTIFY BatteryNotify)
Sets a new configuration battery wait status settings of each battery. The purpose of this is so that...
Definition: compbatt.c:676
NTSTATUS NTAPI CompBattDisableStatusNotify(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: compbatt.c:489
#define COMPBATT_DEBUG_WARN
Definition: compbatt.h:70
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT _In_ PUSB_PORT_PATH _Out_ PUSB_CD_ERROR_INFORMATION _In_ USHORT _In_ PDEVICE_OBJECT PdoDeviceObject
Definition: hubbusif.h:95
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define L(x)
Definition: ntvdm.h:50
#define FILE_DEVICE_BATTERY
Definition: winioctl.h:86
BCLASS_QUERY_INFORMATION QueryInformation
Definition: batclass.h:252
PDEVICE_OBJECT Pdo
Definition: batclass.h:257
BCLASS_SET_STATUS_NOTIFY SetStatusNotify
Definition: batclass.h:255
BCLASS_SET_INFORMATION SetInformation
Definition: batclass.h:253
PUNICODE_STRING DeviceName
Definition: batclass.h:258
BCLASS_DISABLE_STATUS_NOTIFY DisableStatusNotify
Definition: batclass.h:256
BCLASS_QUERY_STATUS QueryStatus
Definition: batclass.h:254
BCLASS_QUERY_TAG QueryTag
Definition: batclass.h:251
PDEVICE_OBJECT DeviceObject
Definition: compbatt.h:208
PDEVICE_OBJECT AttachedDevice
Definition: compbatt.h:207
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define DO_POWER_PAGABLE

Referenced by DriverEntry().

◆ CompBattDisableStatusNotify()

NTSTATUS NTAPI CompBattDisableStatusNotify ( _In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 489 of file compbatt.c.

491{
492 PCOMPBATT_BATTERY_DATA BatteryData;
493 PLIST_ENTRY ListHead, NextEntry;
494 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n");
495
496 /* Loop the battery list */
497 ExAcquireFastMutex(&DeviceExtension->Lock);
498 ListHead = &DeviceExtension->BatteryList;
499 NextEntry = ListHead->Flink;
500 while (NextEntry != ListHead)
501 {
502 /* Get the battery information and clear capacity data */
503 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
504 BatteryData->WaitStatus.LowCapacity = 0;
505 BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF;
506 NextEntry = NextEntry->Flink;
507 }
508
509 /* Done */
510 ExReleaseFastMutex(&DeviceExtension->Lock);
511 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING DisableStatusNotify\n");
512 return STATUS_SUCCESS;
513}
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
BATTERY_WAIT_STATUS WaitStatus
Definition: compbatt.h:112
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by CompBattAddDevice().

◆ CompBattGetDeviceObjectPointer()

NTSTATUS NTAPI CompBattGetDeviceObjectPointer ( _In_ PUNICODE_STRING  DeviceName,
_In_ ACCESS_MASK  DesiredAccess,
_Out_ PFILE_OBJECT FileObject,
_Out_ PDEVICE_OBJECT DeviceObject 
)

Definition at line 74 of file compmisc.c.

79{
83 PFILE_OBJECT LocalFileObject;
85 PAGED_CODE();
86
87 /* Open a file object handle to the device */
91 NULL,
92 NULL);
93 Status = ZwCreateFile(&DeviceHandle,
97 NULL,
98 0,
100 FILE_OPEN,
101 0,
102 NULL,
103 0);
104 if (NT_SUCCESS(Status))
105 {
106 /* Reference the file object */
108 0,
111 (PVOID)&LocalFileObject,
112 NULL);
113 if (NT_SUCCESS(Status))
114 {
115 /* Return the FO and the associated DO */
116 *FileObject = LocalFileObject;
117 *DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
118 }
119
120 /* Close the handle */
122 }
123
124 /* Return status */
125 return Status;
126}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
#define FILE_OPEN
Definition: from_kernel.h:54
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by CompBattAddNewBattery().

◆ CompBattGetEstimatedTime()

NTSTATUS NTAPI CompBattGetEstimatedTime ( _Out_ PULONG  Time,
_In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension 
)

Retrieves the estimated time of the composite battery based on the power drain rate of all the batteries present in the system.

Parameters
[out]TimeA pointer to the computed estimated time of the composite battery, returned to caller. Note that if there are not any batteries that are draining power, or if the system is powered by external AC source, the estimated time is unknown
[in]DeviceExtensionA pointer to a device extension which describes the composite battery itself. It is used to gather each connected battery in the list with the composite battery.
Returns
Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match with that of the cached composite battery's tag or if the composite battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS is returned.

Definition at line 1500 of file compbatt.c.

1503{
1505 PCOMPBATT_BATTERY_DATA BatteryData;
1507 BATTERY_QUERY_INFORMATION QueryInformation;
1508 PLIST_ENTRY ListHead, NextEntry;
1509 ULONG ReturnedTime;
1510 LONG ComputedAtRate;
1511
1512 /* Assume the battery time is not estimated yet */
1514
1515 /*
1516 * Before we are querying the composite estimated battery time we must
1517 * refresh the battery status cache if we have not done it so.
1518 */
1519 Status = CompBattQueryStatus(DeviceExtension,
1520 DeviceExtension->Tag,
1521 &BatteryStatus);
1522 if (!NT_SUCCESS(Status))
1523 {
1525 DbgPrint("CompBatt: Failed to refresh composite battery's status (Status 0x%08lx)\n", Status);
1526
1527 return Status;
1528 }
1529
1530 /* Print out battery status data that has been polled */
1532 DbgPrint("CompBatt: Latest composite battery status (when querying for estimated time)\n"
1533 " PowerState -> 0x%lx\n"
1534 " Capacity -> %u\n"
1535 " Voltage -> %u\n"
1536 " Rate -> %d\n",
1541
1542 /*
1543 * If the batteries are not being discharged and the system is directly
1544 * being powered by external AC source then it makes no sense to
1545 * compute the battery estimated time because that construct is for
1546 * WHEN the system is powered directly from batteries and it drains power.
1547 */
1548 if (DeviceExtension->BatteryStatus.PowerState & BATTERY_POWER_ON_LINE)
1549 {
1551 {
1552 DbgPrint("CompBatt: The system is powered by AC source, estimated time is not available\n");
1553 }
1554
1555 return STATUS_SUCCESS;
1556 }
1557
1558 /* Determine the draining "At Rate" counter for all batteries */
1559 ComputedAtRate = CompBattCalculateAtRateTime(DeviceExtension);
1560
1561 /*
1562 * A rate of 0 indicates none of the batteries that are linked with
1563 * the composite are being drained therefore we cannot estimate the
1564 * run time of the composite as it is not discharging.
1565 */
1566 if (ComputedAtRate == 0)
1567 {
1569 DbgPrint("CompBatt: No battery is discharging and no power is being drained, cannot estimate the run time\n");
1570
1571 return STATUS_SUCCESS;
1572 }
1573
1574 /* Walk over the linked batteries list and determine the exact estimated time */
1575 ExAcquireFastMutex(&DeviceExtension->Lock);
1576 ListHead = &DeviceExtension->BatteryList;
1577 for (NextEntry = ListHead->Flink;
1578 NextEntry != ListHead;
1579 NextEntry = NextEntry->Flink)
1580 {
1581 /* Acquire the remove lock so this battery does not disappear under us */
1582 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
1583 if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp)))
1584 continue;
1585
1586 /* Now release the device lock since the battery can't go away */
1587 ExReleaseFastMutex(&DeviceExtension->Lock);
1588
1589 /* Build the necessary information in order to query the battery estimated time */
1590 QueryInformation.BatteryTag = BatteryData->Tag;
1591 QueryInformation.InformationLevel = BatteryEstimatedTime;
1592 QueryInformation.AtRate = ComputedAtRate;
1593
1594 /* Make sure this battery has a valid tag before issuing the IOCTL */
1595 if (BatteryData->Tag != BATTERY_TAG_INVALID)
1596 {
1598 BatteryData->DeviceObject,
1599 &QueryInformation,
1600 sizeof(QueryInformation),
1601 &ReturnedTime,
1602 sizeof(ReturnedTime),
1603 FALSE);
1604 if (!NT_SUCCESS(Status))
1605 {
1606 /*
1607 * If the device is being suddenly removed then we must invalidate
1608 * both this battery and composite tags.
1609 */
1611 {
1613 }
1614
1615 ExAcquireFastMutex(&DeviceExtension->Lock);
1616 IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp);
1617
1618 /*
1619 * In other places we are ceasing the execution of the loop but
1620 * here we want to continue looking for other linked batteries.
1621 * This is because we are querying for the estimated battery time
1622 * at the time the last battery status was valid. Also bear in
1623 * mind IOCTL_BATTERY_QUERY_INFORMATION with InformationLevel as
1624 * BatteryEstimatedTime might not be a valid request supported
1625 * by this battery.
1626 */
1627 continue;
1628 }
1629
1630 /* Now sum up the estimated battery time */
1631 if (ReturnedTime != BATTERY_UNKNOWN_TIME)
1632 {
1633 if (*Time != BATTERY_UNKNOWN_TIME)
1634 {
1635 *Time += ReturnedTime;
1636 }
1637 else
1638 {
1639 *Time = ReturnedTime;
1640 }
1641 }
1642 }
1643
1644 /* We are done with this battery */
1645 ExAcquireFastMutex(&DeviceExtension->Lock);
1646 IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp);
1647 }
1648
1649 /* Release the lock as we are no longer poking through the batteries list */
1650 ExReleaseFastMutex(&DeviceExtension->Lock);
1651 return Status;
1652}
_In_ ULONG _Out_ PBATTERY_STATUS BatteryStatus
Definition: batclass.h:199
#define BATTERY_POWER_ON_LINE
Definition: batclass.h:73
@ BatteryEstimatedTime
Definition: batclass.h:100
#define IOCTL_BATTERY_QUERY_INFORMATION
Definition: batclass.h:86
#define BATTERY_TAG_INVALID
Definition: batclass.h:94
#define BATTERY_UNKNOWN_TIME
Definition: batclass.h:68
static LONG CompBattCalculateAtRateTime(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Calculates the "At Rate" flow of the composite battery based on the sum of all connected batteries,...
Definition: compbatt.c:1409
NTSTATUS NTAPI BatteryIoctl(_In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_ PVOID OutputBuffer, _Inout_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl)
Definition: compmisc.c:16
#define COMPBATT_DEBUG_INFO
Definition: compbatt.h:68
#define STATUS_DEVICE_REMOVED
Definition: d3dkmdt.h:39
static PLARGE_INTEGER Time
Definition: time.c:105
long LONG
Definition: pedump.c:60
BATTERY_QUERY_INFORMATION_LEVEL InformationLevel
Definition: batclass.h:110
ULONG PowerState
Definition: batclass.h:154
ULONG Capacity
Definition: batclass.h:155
PDEVICE_OBJECT DeviceObject
Definition: compbatt.h:91
IO_REMOVE_LOCK RemoveLock
Definition: compbatt.h:85
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764

Referenced by CompBattQueryInformation().

◆ CompBattMonitorIrpComplete()

NTSTATUS NTAPI CompBattMonitorIrpComplete ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_ PVOID  Context 
)

Queues a work item thread worker which is bound to the individual CM (Control Method) ACPI battery to handle the IRP.

Parameters
[in]DeviceObjectA pointer to a device object, this parameter is unused.
[in]IrpA pointer to an I/O request packet. It is used to gather the I/O stack location which contains the data of the individual battery.
[in]ContextAn aribtrary pointer that points to context data, this paramater is unused.
Returns
Returns STATUS_MORE_PROCESSING_REQUIRED to indicate the I/O request is still in action, therefore the IRP is not freed.

Definition at line 92 of file compbatt.c.

96{
97 PIO_STACK_LOCATION IoStackLocation;
98 PCOMPBATT_BATTERY_DATA BatteryData;
99
100 /* We do not care about the device object */
102
103 /* Grab the composite battery data from the I/O stack packet */
104 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
105 BatteryData = IoStackLocation->Parameters.Others.Argument2;
106
107 /* Request the IRP complete worker to do the deed */
110}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
WORK_QUEUE_ITEM WorkItem
Definition: compbatt.h:98
struct _IO_STACK_LOCATION::@4024::@4063 Others
union _IO_STACK_LOCATION::@1584 Parameters
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by CompBattAddNewBattery(), and CompBattMonitorIrpCompleteWorker().

◆ CompBattMonitorIrpCompleteWorker()

VOID NTAPI CompBattMonitorIrpCompleteWorker ( _In_ PCOMPBATT_BATTERY_DATA  BatteryData)

The brains of the battery IRP worker. It monitors the state of the IRP as well as sends the IRP down the device stack to gather battery related data, such tag and status. It also serves as the I/O completion routine of which it elaborates the gathered data.

Parameters
[in]BatteryDataA pointer to battery data of an individual battery that contains the IRP to be send down the device stack.

Definition at line 125 of file compbatt.c.

127{
129 PIRP Irp;
130 UCHAR Mode;
131 ULONG PrevPowerState;
134 PIO_STACK_LOCATION IoStackLocation;
135 PCOMPBATT_DEVICE_EXTENSION DeviceExtension;
136
137 /* Cache the necessary battery data */
138 Irp = BatteryData->Irp;
139 DeviceObject = BatteryData->DeviceObject;
140 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
141 DeviceExtension = IoStackLocation->Parameters.Others.Argument1;
142
143 /* Switch to the next stack as we have to setup the control function data there */
144 IoStackLocation = IoGetNextIrpStackLocation(Irp);
145
146 /* Has the I/O composite battery request succeeded? */
147 Status = Irp->IoStatus.Status;
149 {
150 /*
151 * This battery is being removed from the composite, perform
152 * cleanups and do not inquire I/O requests again on this battery.
153 */
155 {
157 DbgPrint("CompBatt: Battery (0x%p) is being removed from composite battery\n", BatteryData);
158
159 IoFreeIrp(Irp);
160 CompBattRemoveBattery(&BatteryData->BatteryName, DeviceExtension);
161 return;
162 }
163
164 /*
165 * This is the first time a battery is being added into the composite
166 * (we understand that if Status was STATUS_DEVICE_NOT_CONNECTED).
167 * We must invalidate the composite tag and request a recalculation
168 * of the battery tag.
169 */
171 DbgPrint("CompBatt: Battery arrived for first time or disappeared (Status 0x%08lx)\n", Status);
172
173 BatteryData->Tag = BATTERY_TAG_INVALID;
174
175 /*
176 * Invalidate the last read status interrupt time as well since the last
177 * battery status data no longer applies. Same for the composite battery
178 * as well.
179 */
180 BatteryData->InterruptTime = 0;
181 DeviceExtension->InterruptTime = 0;
182
183 /* Notify Battery Class the battery status incurs in a change */
184 BatteryClassStatusNotify(DeviceExtension->ClassData);
185
186 /* Setup the necessary I/O data to query the battery tag */
187 IoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOCTL_BATTERY_QUERY_TAG;
188 IoStackLocation->Parameters.DeviceIoControl.InputBufferLength = sizeof(ULONG);
189 IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ULONG);
190 BatteryData->Mode = COMPBATT_QUERY_TAG;
191 BatteryData->WorkerBuffer.WorkerTag = 0xFFFFFFFF;
192
193 /* Dispatch our request now to the battery's driver */
194 goto DispatchRequest;
195 }
196
197 /* Our I/O request has been completed successfully, check what did we get */
198 Mode = BatteryData->Mode;
199 switch (Mode)
200 {
202 {
203 /*
204 * This battery has just gotten a tag, acknowledge the composite battery
205 * about that so it can recalculate its own composite tag.
206 */
208 DbgPrint("CompBatt: Battery (Device 0x%p) has a tag of %lu\n", DeviceObject, BatteryData->WorkerBuffer.WorkerTag);
209
210 /* Ensure the battery tag is not bogus, getting a tag of 0 is illegal */
211 ASSERT(BatteryData->WorkerBuffer.WorkerTag != 0);
212
213 /* Assign the battery tag */
214 BatteryData->Tag = BatteryData->WorkerBuffer.WorkerTag;
215 BatteryData->Flags |= COMPBATT_TAG_ASSIGNED;
216
217 /* Punt the composite battery flags, as the previous cached data no longer applies */
218 DeviceExtension->Flags = 0;
219
220 /* Notify the Battery Class driver this battery has got a tag */
221 BatteryClassStatusNotify(DeviceExtension->ClassData);
222 break;
223 }
224
226 {
227 /*
228 * Read the battery status only if the IRP has not been cancelled,
229 * otherwise the request must be re-issued again. This typically
230 * happens if the wait values are in conflict which it might
231 * end up in inconsistent battery status results.
232 */
233 if (Status != STATUS_CANCELLED && !Irp->Cancel)
234 {
235 /*
236 * If we reach here then the battery has entered into a change of
237 * power state or its charge capacity has changed.
238 */
240 DbgPrint("CompBatt: Battery state (Device 0x%p) has changed\n", DeviceObject);
241
242 /* Copy the battery status of this battery */
243 RtlCopyMemory(&BatteryData->BatteryStatus,
244 &BatteryData->WorkerBuffer.WorkerStatus,
245 sizeof(BatteryData->BatteryStatus));
246
247 /* Update the interrupt time as this is the most recent read of the battery status */
248 BatteryData->InterruptTime = KeQueryInterruptTime();
249
250 /*
251 * Ensure we have not gotten unknown capacities while we waited for new
252 * battery status. The battery might have malfunctioned or something.
253 */
254 if (BatteryData->WorkerBuffer.WorkerStatus.Capacity == BATTERY_UNKNOWN_CAPACITY)
255 {
256 /* We do not know the capacity of this battery, default the low and high capacities */
257 BatteryData->WaitStatus.LowCapacity = BATTERY_UNKNOWN_CAPACITY;
258 BatteryData->WaitStatus.HighCapacity = BATTERY_UNKNOWN_CAPACITY;
259 }
260 else
261 {
262 /* We know the capacity, adjust the low and high capacities accordingly */
263 if (BatteryData->WaitStatus.LowCapacity >
264 BatteryData->WorkerBuffer.WorkerStatus.Capacity)
265 {
266 BatteryData->WaitStatus.LowCapacity = BatteryData->WorkerBuffer.WorkerStatus.Capacity;
267 }
268
269 if (BatteryData->WaitStatus.HighCapacity <
270 BatteryData->WorkerBuffer.WorkerStatus.Capacity)
271 {
272 BatteryData->WaitStatus.HighCapacity = BatteryData->WorkerBuffer.WorkerStatus.Capacity;
273 }
274 }
275
276 /* Copy the current last read power state for the next wait */
277 BatteryData->WaitStatus.PowerState = BatteryData->WorkerBuffer.WorkerStatus.PowerState;
278
279 /*
280 * Cache the previous power state of the composite battery and invalidate
281 * the last computed battery status interrupt time. This is because,
282 * logically, this specific battery incurred in a state change therefore
283 * the previous composite status is no longer consistent.
284 */
285 PrevPowerState = DeviceExtension->BatteryStatus.PowerState;
286 DeviceExtension->InterruptTime = 0;
287
288 /* Compute a new battery status for the composite battery */
289 Status = CompBattQueryStatus(DeviceExtension,
290 DeviceExtension->Tag,
292
293 /* Print out the current battery status of the composite to the debugger */
295 DbgPrint("CompBatt: Latest composite battery status\n"
296 " PowerState -> 0x%lx\n"
297 " Capacity -> %u\n"
298 " Voltage -> %u\n"
299 " Rate -> %d\n",
304
305 /*
306 * Now determine whether should we notify the Battery Class driver due to
307 * changes in power state settings in the composite battery. This could
308 * happen in two following conditions:
309 *
310 * 1. The status notify flag was set for the respective power notification
311 * settings, and the composite battery incurred in a change of such
312 * settings. In this case we have to probe the current settings that
313 * they have changed.
314 *
315 * 2. The status notify flag was not set, therefore we do not know the
316 * exact configuration of the notification settings. We only care that
317 * the power state has changed at this point.
318 *
319 * Why do we have to do this is because we have to warn the Battery Class
320 * about the data that has changed.
321 */
322 if (!(DeviceExtension->Flags & COMPBATT_STATUS_NOTIFY_SET))
323 {
324 if (PrevPowerState != DeviceExtension->BatteryStatus.PowerState)
325 {
326 /* The previous power state is no longer valid, notify Battery Class */
327 BatteryClassStatusNotify(DeviceExtension->ClassData);
328 }
329 }
330 else
331 {
332 /*
333 * Unlike the condition above, we check for power state change against
334 * the current notify wait set since the notify set flag bit is assigned.
335 */
336 if (DeviceExtension->WaitNotifyStatus.PowerState != DeviceExtension->BatteryStatus.PowerState ||
337 DeviceExtension->WaitNotifyStatus.LowCapacity > DeviceExtension->BatteryStatus.Capacity ||
338 DeviceExtension->WaitNotifyStatus.HighCapacity < DeviceExtension->BatteryStatus.Capacity)
339 {
340 /* The following configuration settings have changed, notify Battery Class */
341 BatteryClassStatusNotify(DeviceExtension->ClassData);
342 }
343 }
344 }
345
346 break;
347 }
348
349 default:
350 {
351 ASSERTMSG("CompBatt: BAD!!! WE SHOULD NOT BE HERE!\n", FALSE);
353 }
354 }
355
356 /* Setup the necessary data to read battery status */
357 BatteryData->WaitStatus.BatteryTag = BatteryData->Tag;
358 BatteryData->WaitStatus.Timeout = 3000; // FIXME: Hardcoded (wait for 3 seconds) because we do not have ACPI notifications implemented yet...
359
360 RtlCopyMemory(&BatteryData->WorkerBuffer.WorkerWaitStatus,
361 &BatteryData->WaitStatus,
362 sizeof(BatteryData->WaitStatus));
363
364 IoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOCTL_BATTERY_QUERY_STATUS;
365 IoStackLocation->Parameters.DeviceIoControl.InputBufferLength = sizeof(BatteryData->WorkerBuffer.WorkerWaitStatus);
366 IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength = sizeof(BatteryData->WorkerBuffer.WorkerStatus);
367 BatteryData->Mode = COMPBATT_READ_STATUS;
368
369DispatchRequest:
370 /* Setup the system buffer to that of the battery data which it will hold the returned data */
371 IoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
372 Irp->AssociatedIrp.SystemBuffer = &BatteryData->WorkerBuffer;
373 Irp->Cancel = FALSE;
374 Irp->PendingReturned = FALSE;
375
376 /* Setup the worker completion routine which it will invoke the worker later on */
379 NULL,
380 TRUE,
381 TRUE,
382 TRUE);
383
384 /* Dispatch the I/O request now */
386}
#define IOCTL_BATTERY_QUERY_TAG
Definition: batclass.h:84
#define BATTERY_UNKNOWN_CAPACITY
Definition: batclass.h:65
#define IOCTL_BATTERY_QUERY_STATUS
Definition: batclass.h:90
BCLASSAPI NTSTATUS NTAPI BatteryClassStatusNotify(_In_ PVOID ClassData)
Definition: battc.c:79
NTSTATUS NTAPI CompBattMonitorIrpComplete(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PVOID Context)
Queues a work item thread worker which is bound to the individual CM (Control Method) ACPI battery to...
Definition: compbatt.c:92
NTSTATUS NTAPI CompBattRemoveBattery(_In_ PUNICODE_STRING BatteryName, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: comppnp.c:226
#define COMPBATT_QUERY_TAG
Definition: compbatt.h:34
#define COMPBATT_TAG_ASSIGNED
Definition: compbatt.h:29
#define COMPBATT_STATUS_NOTIFY_SET
Definition: compbatt.h:28
#define COMPBATT_READ_STATUS
Definition: compbatt.h:35
#define TRUE
Definition: types.h:120
_In_ ULONG Mode
Definition: hubbusif.h:303
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define ASSERT(a)
Definition: mode.c:44
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREACHABLE
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define KeQueryInterruptTime()
Definition: ke.h:37
BATTERY_WAIT_STATUS WaitNotifyStatus
Definition: compbatt.h:198
BATTERY_STATUS BatteryStatus
Definition: compbatt.h:197
struct _IO_STACK_LOCATION::@1584::@1585 DeviceIoControl
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by CompBattAddNewBattery().

◆ CompBattPnpDispatch()

NTSTATUS NTAPI CompBattPnpDispatch ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 412 of file comppnp.c.

415{
418 PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
419 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING PnpDispatch\n");
420
421 /* Set default error */
423
424 /* Check what kind of PnP function this is */
425 switch (IoStackLocation->MinorFunction)
426 {
428
429 /* Device is starting, register for new batteries and pick up current ones */
431 0,
432 (PVOID)&GUID_DEVICE_BATTERY,
433 DeviceObject->DriverObject,
435 DeviceExtension,
436 &DeviceExtension->NotificationEntry);
437 if (NT_SUCCESS(Status))
438 {
439 /* Now go get the batteries */
441 DbgPrint("CompBatt: Successfully registered for PnP notification\n");
442 Status = CompBattGetBatteries(DeviceExtension);
443 }
444 else
445 {
446 /* We failed */
448 DbgPrint("CompBatt: Couldn't register for PnP notification - %x\n",
449 Status);
450 }
451 break;
453
454 /* Explicitly say ok */
456 break;
457
459
460 /* Explicitly say ok */
462 break;
463
465
466 /* Explicitly say ok */
468 break;
469
471
472 /* Add this in */
473 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
475 break;
476
477 default:
478
479 /* Not supported */
480 break;
481 }
482
483 /* Set IRP status if we have one */
484 if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
485
486 /* Did someone pick it up? */
488 {
489 /* Still unsupported, try ACPI */
491 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
492 }
493 else
494 {
495 /* Complete the request */
496 Status = Irp->IoStatus.Status;
498 }
499
500 /* Release the remove lock and return status */
501 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING PnpDispatch\n");
502 return Status;
503}
NTSTATUS NTAPI CompBattPnpEventHandler(_In_ PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: comppnp.c:294
NTSTATUS NTAPI CompBattGetBatteries(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: comppnp.c:252
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI IoRegisterPlugPlayNotification(_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
Definition: pnpnotify.c:346
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
@ EventCategoryDeviceInterfaceChange
Definition: iotypes.h:1226
#define IRP_MN_CANCEL_REMOVE_DEVICE
DRIVER_NOTIFICATION_CALLBACK_ROUTINE * PDRIVER_NOTIFICATION_CALLBACK_ROUTINE
Definition: iotypes.h:1247

Referenced by DriverEntry().

◆ CompBattPowerDispatch()

NTSTATUS NTAPI CompBattPowerDispatch ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 18 of file comppnp.c.

21{
22 PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
23 if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: PowerDispatch received power IRP.\n");
24
25 /* Start the next IRP */
27
28 /* Call the next driver in the stack */
30 return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
31}
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758

Referenced by DriverEntry().

◆ CompBattQueryInformation()

NTSTATUS NTAPI CompBattQueryInformation ( _In_ PCOMPBATT_DEVICE_EXTENSION  FdoExtension,
_In_ ULONG  Tag,
_In_ BATTERY_QUERY_INFORMATION_LEVEL  InfoLevel,
_In_opt_ LONG  AtRate,
_In_ PVOID  Buffer,
_In_ ULONG  BufferLength,
_Out_ PULONG  ReturnedLength 
)

Definition at line 1656 of file compbatt.c.

1664{
1665 BATTERY_INFORMATION BatteryInfo;
1666 BATTERY_REPORTING_SCALE BatteryGranularity[4];
1667 PWCHAR BatteryName = L"Composite Battery";
1668 //BATTERY_MANUFACTURE_DATE Date;
1669 ULONG Dummy, Time;
1670 PVOID QueryData = NULL;
1671 ULONG QueryLength = 0;
1673 PAGED_CODE();
1674 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING QueryInformation\n");
1675
1676 /* Check for valid/correct tag */
1677 if ((Tag != DeviceExtension->Tag) ||
1678 (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED)))
1679 {
1680 /* Not right, so fail */
1681 return STATUS_NO_SUCH_DEVICE;
1682 }
1683
1684 /* Check what caller wants */
1685 switch (InfoLevel)
1686 {
1687 case BatteryInformation:
1688
1689 /* Query combined battery information */
1690 RtlZeroMemory(&BatteryInfo, sizeof(BatteryInfo));
1691 Status = CompBattGetBatteryInformation(&BatteryInfo, DeviceExtension);
1692 if (NT_SUCCESS(Status))
1693 {
1694 /* Return the data if successful */
1695 QueryData = &BatteryInfo;
1696 QueryLength = sizeof(BatteryInfo);
1697 }
1698 break;
1699
1701
1702 /* Query combined granularity information */
1703 RtlZeroMemory(&BatteryGranularity, sizeof(BatteryGranularity));
1704 Status = CompBattGetBatteryGranularity(BatteryGranularity, DeviceExtension);
1705 if (NT_SUCCESS(Status))
1706 {
1707 /* Return the data if successful */
1708 QueryLength = sizeof(BatteryGranularity);
1709 QueryData = &BatteryGranularity;
1710 }
1711 break;
1712
1714
1715 /* Query combined time estimate information */
1716 RtlZeroMemory(&Time, sizeof(Time));
1717 Status = CompBattGetEstimatedTime(&Time, DeviceExtension);
1718 if (NT_SUCCESS(Status))
1719 {
1720 /* Return the data if successful */
1721 QueryLength = sizeof(Time);
1722 QueryData = &Time;
1723 }
1724 break;
1725
1727 case BatteryDeviceName:
1728
1729 /* Return the static buffer */
1730 QueryData = BatteryName;
1731 QueryLength = sizeof(L"Composite Battery");
1732 break;
1733
1735
1736 /* Static data */
1737 //Date.Day = 26;
1738 //Date.Month = 06;
1739 //Date.Year = 1997;
1740 break;
1741
1742 case BatteryTemperature:
1743 case BatteryUniqueID:
1744
1745 /* Return zero */
1746 Dummy = 0;
1747 QueryData = &Dummy;
1748 QueryLength = sizeof(Dummy);
1749 break;
1750
1751 default:
1752 /* Everything else is unknown */
1754 break;
1755 }
1756
1757 /* Return the required length and check if the caller supplied enough */
1758 *ReturnedLength = QueryLength;
1759 if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
1760
1761 /* Copy the data if there's enough space and it exists */
1762 if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength);
1763
1764 /* Return function result */
1765 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING QueryInformation\n");
1766 return Status;
1767}
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
@ BatteryInformation
Definition: batclass.h:97
@ BatteryManufactureName
Definition: batclass.h:103
@ BatteryGranularityInformation
Definition: batclass.h:98
@ BatteryUniqueID
Definition: batclass.h:104
@ BatteryDeviceName
Definition: batclass.h:101
@ BatteryTemperature
Definition: batclass.h:99
@ BatteryManufactureDate
Definition: batclass.h:102
Definition: bufpool.h:45
NTSTATUS NTAPI CompBattGetBatteryGranularity(_Out_ PBATTERY_REPORTING_SCALE ReportingScale, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: compbatt.c:1308
NTSTATUS NTAPI CompBattGetEstimatedTime(_Out_ PULONG Time, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Retrieves the estimated time of the composite battery based on the power drain rate of all the batter...
Definition: compbatt.c:1500
NTSTATUS NTAPI CompBattGetBatteryInformation(_Out_ PBATTERY_INFORMATION BatteryInfo, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: compbatt.c:1151
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

Referenced by CompBattAddDevice().

◆ CompBattQueryStatus()

NTSTATUS NTAPI CompBattQueryStatus ( _In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension,
_In_ ULONG  Tag,
_Out_ PBATTERY_STATUS  BatteryStatus 
)

Queries the battery status of each individiual connected battery with the composite battery and combines all the retrieved data as one single battery status for the composite battery.

Parameters
[in]DeviceExtensionA pointer to a device extension which describes the composite battery itself. It is used to gather each connected battery in the list with the composite battery.
[in]TagA battery tag supplied by the caller. This is typically the tag of the composite battery which is used to check against the cached tag of the composite battery if it has changed or not.
[out]BatteryStatusA pointer to a battery status that contains the combined data, returned to the caller. It serves as the battery status for the composite battery.
Returns
Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match with that of the cached composite battery's tag or if the composite battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS is returned, which it will also return success if the composite battery's cached battery status is fresh which indicates it has already been computed.

Definition at line 932 of file compbatt.c.

936{
937 PCOMPBATT_BATTERY_DATA BatteryData;
939 PLIST_ENTRY ListHead, NextEntry;
940 ULONGLONG LastReadTime, CurrentReadTime;
942
943 /*
944 * The caller wants to update the composite battery status but the composite
945 * itself does not have a valid tag assigned, or the tag does not actually match.
946 */
947 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) ||
948 (DeviceExtension->Tag != Tag))
949 {
951 DbgPrint("CompBatt: Composite battery tag not assigned or not matching (Tag -> %lu, Composite Tag -> %lu)\n",
952 Tag, DeviceExtension->Tag);
953
955 }
956
957 /* Initialize the status and wait fields with zeros */
959 RtlZeroMemory(&Wait, sizeof(Wait));
960
961 /*
962 * The battery status was already updated when the caller queried for new
963 * status. We do not need to update the status again for no reason.
964 * Just give them the data outright.
965 */
966 CurrentReadTime = KeQueryInterruptTime();
967 LastReadTime = CurrentReadTime - DeviceExtension->InterruptTime;
968 if (LastReadTime < COMPBATT_FRESH_STATUS_TIME)
969 {
971 DbgPrint("CompBatt: Composite battery status data is fresh, no need to update it again\n");
972
973 RtlCopyMemory(BatteryStatus, &DeviceExtension->BatteryStatus, sizeof(BATTERY_STATUS));
974 return STATUS_SUCCESS;
975 }
976
977 /*
978 * Initialize the battery status context with unknown defaults, until we get
979 * to retrieve the real data from each battery and compute the exact status.
980 * Assume the system is powered by AC source for now until we find out it is
981 * not the case.
982 */
987
988 /* Iterate over all the present linked batteries and retrieve their status */
989 ExAcquireFastMutex(&DeviceExtension->Lock);
990 ListHead = &DeviceExtension->BatteryList;
991 for (NextEntry = ListHead->Flink;
992 NextEntry != ListHead;
993 NextEntry = NextEntry->Flink)
994 {
995 /* Acquire the remove lock so this battery does not disappear under us */
996 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
997 if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp)))
998 continue;
999
1000 /* Now release the device lock since the battery can't go away */
1001 ExReleaseFastMutex(&DeviceExtension->Lock);
1002
1003 /* Setup the battery tag for the status wait which is needed to send off the IOCTL */
1004 Wait.BatteryTag = BatteryData->Tag;
1005
1006 /* Make sure this battery has a tag before we send off the IOCTL */
1007 if (BatteryData->Tag != BATTERY_TAG_INVALID)
1008 {
1009 /* Only query new battery status data if it is no longer fresh */
1010 LastReadTime = CurrentReadTime - BatteryData->InterruptTime;
1011 if (LastReadTime > COMPBATT_FRESH_STATUS_TIME)
1012 {
1013 RtlZeroMemory(&BatteryData->BatteryStatus,
1014 sizeof(BatteryData->BatteryStatus));
1016 BatteryData->DeviceObject,
1017 &Wait,
1018 sizeof(Wait),
1019 &BatteryData->BatteryStatus,
1020 sizeof(BatteryData->BatteryStatus),
1021 FALSE);
1022 if (!NT_SUCCESS(Status))
1023 {
1024 /*
1025 * If the device is being suddenly removed then we must invalidate
1026 * both this battery and composite tags.
1027 */
1029 {
1031 }
1032
1033 ExAcquireFastMutex(&DeviceExtension->Lock);
1034 IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp);
1035 break;
1036 }
1037
1038 /* Update the timestamp of the current read of battery status */
1039 BatteryData->InterruptTime = CurrentReadTime;
1040 }
1041
1042 /*
1043 * Now it is time to combine the data into the composite status.
1044 * The battery is either charging or discharging. AC is present
1045 * only if the charger supplies current to all batteries. And
1046 * the composite is deemed as critical if at least one battery
1047 * is discharging and it is in crtitical state.
1048 */
1050 BatteryStatus->PowerState &= (BatteryData->BatteryStatus.PowerState | ~BATTERY_POWER_ON_LINE);
1051 if ((BatteryData->BatteryStatus.PowerState & BATTERY_CRITICAL) &&
1053 {
1055 }
1056
1057 /* Add up the battery capacity if it is not unknown */
1059 {
1061 {
1063 }
1064 else
1065 {
1067 }
1068 }
1069
1070 /* Always pick up the greatest voltage for the composite battery */
1071 if (BatteryData->BatteryStatus.Voltage != BATTERY_UNKNOWN_VOLTAGE)
1072 {
1074 {
1076 BatteryData->BatteryStatus.Voltage);
1077 }
1078 else
1079 {
1081 }
1082 }
1083
1084 /* Add up the battery discharge rate if it is not unknown */
1085 if (BatteryData->BatteryStatus.Rate != BATTERY_UNKNOWN_RATE)
1086 {
1088 {
1089 BatteryStatus->Rate += BatteryData->BatteryStatus.Rate;
1090 }
1091 else
1092 {
1093 BatteryStatus->Rate = BatteryData->BatteryStatus.Rate;
1094 }
1095 }
1096 }
1097
1098 /* We are done combining data from this battery */
1099 ExAcquireFastMutex(&DeviceExtension->Lock);
1100 IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp);
1101 }
1102
1103 /* Release the lock as we are no longer poking through the batteries list */
1104 ExReleaseFastMutex(&DeviceExtension->Lock);
1105
1106 /* Ensure the composite battery did not incur in drastic changes of tag */
1107 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) ||
1108 (DeviceExtension->Tag != Tag))
1109 {
1110 /*
1111 * Either the last battery was removed (in this case the composite is no
1112 * longer existing) or a battery was removed of which the whole battery
1113 * information must be recomputed and such.
1114 */
1116 DbgPrint("CompBatt: Last battery or a battery was removed, the whole composite data must be recomputed\n");
1117
1118 return STATUS_NO_SUCH_DEVICE;
1119 }
1120
1121 /*
1122 * If there is a battery that is charging while another one discharging,
1123 * then tell the caller the composite battery is actually discharging.
1124 * This is less likely to happen on a multi-battery system like laptops
1125 * as the charger would provide electricity to all the batteries.
1126 * Perhaps the most likely case scenario would be if the system were
1127 * to be powered by a UPS.
1128 */
1131 {
1132 BatteryStatus->PowerState &= ~BATTERY_CHARGING;
1133 }
1134
1135 /* Copy the combined status information to the composite battery */
1136 if (NT_SUCCESS(Status))
1137 {
1138 RtlCopyMemory(&DeviceExtension->BatteryStatus,
1140 sizeof(DeviceExtension->BatteryStatus));
1141
1142 /* Update the last read battery status timestamp as well */
1143 DeviceExtension->InterruptTime = CurrentReadTime;
1144 }
1145
1146 return Status;
1147}
#define BATTERY_CRITICAL
Definition: batclass.h:76
#define BATTERY_UNKNOWN_VOLTAGE
Definition: batclass.h:79
#define BATTERY_DISCHARGING
Definition: batclass.h:74
#define BATTERY_CHARGING
Definition: batclass.h:75
#define BATTERY_UNKNOWN_RATE
Definition: batclass.h:82
#define COMPBATT_FRESH_STATUS_TIME
Definition: compbatt.h:51
BATTERY_STATUS BatteryStatus
Definition: compbatt.h:142
ULONGLONG InterruptTime
Definition: compbatt.h:145
#define max(a, b)
Definition: svc.c:63
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by CompBattAddDevice(), CompBattGetEstimatedTime(), CompBattMonitorIrpCompleteWorker(), and CompBattSetStatusNotify().

◆ CompBattQueryTag()

NTSTATUS NTAPI CompBattQueryTag ( _In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension,
_Out_ PULONG  Tag 
)

Definition at line 453 of file compbatt.c.

456{
458 PAGED_CODE();
459 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING QueryTag\n");
460
461 /* Was a tag assigned? */
462 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED))
463 {
464 /* Assign one */
465 CompBattRecalculateTag(DeviceExtension);
466 }
467
468 /* Do we have a tag now? */
469 if ((DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) && DeviceExtension->Tag != BATTERY_TAG_INVALID)
470 {
471 /* Return the tag */
472 *Tag = DeviceExtension->Tag;
474 }
475 else
476 {
477 /* No tag */
480 }
481
482 /* Return status */
483 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING QueryTag\n");
484 return Status;
485}
VOID NTAPI CompBattRecalculateTag(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: compbatt.c:390

Referenced by CompBattAddDevice().

◆ CompBattRemoveBattery()

NTSTATUS NTAPI CompBattRemoveBattery ( _In_ PUNICODE_STRING  BatteryName,
_In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension 
)

Definition at line 226 of file comppnp.c.

229{
230 PCOMPBATT_BATTERY_DATA BatteryData;
231 if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: RemoveBattery\n");
232
233 /* Remove the entry */
234 BatteryData = RemoveBatteryFromList(BatteryName, DeviceExtension);
235 if (BatteryData)
236 {
237 /* Dereference and free it */
238 ObDereferenceObject(BatteryData->DeviceObject);
239 ExFreePool(BatteryData);
240
241 /* Notify class driver */
242 DeviceExtension->Flags = 0;
243 BatteryClassStatusNotify(DeviceExtension->ClassData);
244 }
245
246 /* It's done */
247 return STATUS_SUCCESS;
248}
PCOMPBATT_BATTERY_DATA NTAPI RemoveBatteryFromList(_In_ PCUNICODE_STRING BatteryName, _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
Definition: comppnp.c:35
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by CompBattMonitorIrpCompleteWorker().

◆ CompBattSetStatusNotify()

NTSTATUS NTAPI CompBattSetStatusNotify ( _In_ PCOMPBATT_DEVICE_EXTENSION  DeviceExtension,
_In_ ULONG  BatteryTag,
_In_ PBATTERY_NOTIFY  BatteryNotify 
)

Sets a new configuration battery wait status settings of each battery. The purpose of this is so that the composite battery gets notified of new battery status as if it was a single battery.

Parameters
[in]DeviceExtensionA pointer to a device extension which describes the composite battery itself. It is used to gather each connected battery in the list with the composite battery.
[in]BatteryTagA battery tag supplied by the caller. This is typically the tag of the composite battery which is used to check against the cached tag of the composite battery if it has changed or not.
[in]BatteryNotifyA pointer to a structure filled with battery notification settings, supplied by the caller. It is used as the new values for the configuration wait settings.
Returns
Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match with that of the cached composite battery's tag or if the composite battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS is returned.

Definition at line 676 of file compbatt.c.

680{
682 BOOLEAN BadBattery;
683 ULONG TotalRate;
684 ULONG BatteriesCount;
685 ULONG HighestCapacity;
686 ULONG LowCapDifference, HighCapDifference, LowDelta, HighDelta;
688 PCOMPBATT_BATTERY_DATA BatteryData;
689 PLIST_ENTRY ListHead, NextEntry;
690
691 /*
692 * The caller wants to set new status notification settings but the composite
693 * battery does not have a valid tag assigned, or the tag does not actually match.
694 */
695 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) ||
696 (DeviceExtension->Tag != BatteryTag))
697 {
699 DbgPrint("CompBatt: Composite battery tag not assigned or not matching (Tag -> %lu, Composite Tag -> %lu)\n",
700 BatteryTag, DeviceExtension->Tag);
701
703 }
704
705 /*
706 * Before we are setting up new status wait notification points we need to
707 * refresh the composite status so that we get to know what values should be
708 * set for the current notification wait status.
709 */
710 Status = CompBattQueryStatus(DeviceExtension,
713 if (!NT_SUCCESS(Status))
714 {
716 DbgPrint("CompBatt: Failed to refresh composite battery's status (Status 0x%08lx)\n", Status);
717
718 return Status;
719 }
720
721 /* Print out battery status data that has been polled */
723 DbgPrint("CompBatt: Latest composite battery status (when setting notify status)\n"
724 " PowerState -> 0x%lx\n"
725 " Capacity -> %u\n"
726 " Voltage -> %u\n"
727 " Rate -> %d\n",
732
733 /* Calculate the high and low capacity differences based on the real summed capacity of the composite */
734 LowCapDifference = DeviceExtension->BatteryStatus.Capacity - BatteryNotify->LowCapacity;
735 HighCapDifference = BatteryNotify->HighCapacity - DeviceExtension->BatteryStatus.Capacity;
736
737 /* Cache the notification parameters provided for later usage when polling for battery status */
738 DeviceExtension->WaitNotifyStatus.PowerState = BatteryNotify->PowerState;
739 DeviceExtension->WaitNotifyStatus.LowCapacity = BatteryNotify->LowCapacity;
740 DeviceExtension->WaitNotifyStatus.HighCapacity = BatteryNotify->HighCapacity;
741
742 /* Toggle the valid notify flag as these are the newer notification settings */
743 DeviceExtension->Flags |= COMPBATT_STATUS_NOTIFY_SET;
744
745 /*
746 * Get the number of currently linked batteries to composite and total rate,
747 * we will use these counters later to determine the wait values for each
748 * individual battery.
749 */
750 BadBattery = CompBattCalculateTotalRateAndLinkedBatteries(DeviceExtension,
751 &TotalRate,
752 &BatteriesCount);
753
754 /*
755 * Of course we have to be sure that we have at least one battery linked
756 * with the composite battery at this time of getting invoked to set new
757 * notification wait settings.
758 */
759 ASSERT(BatteriesCount != 0);
760
761 /* Walk over the linked batteries list and set up new wait configuration settings */
762 ExAcquireFastMutex(&DeviceExtension->Lock);
763 ListHead = &DeviceExtension->BatteryList;
764 for (NextEntry = ListHead->Flink;
765 NextEntry != ListHead;
766 NextEntry = NextEntry->Flink)
767 {
768 /* Acquire the remove lock so this battery does not disappear under us */
769 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
770 if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp)))
771 continue;
772
773 /* Now release the device lock since the battery can't go away */
774 ExReleaseFastMutex(&DeviceExtension->Lock);
775
776 /* Make sure this battery has a tag before setting new wait values */
777 if (BatteryData->Tag != BATTERY_TAG_INVALID)
778 {
779 /*
780 * And also make sure this battery does not have an unknown
781 * capacity, we cannot set up new configuration wait settings
782 * based on that. Default the low and high wait capacities.
783 */
785 {
786 /*
787 * Calculate the low capacity wait setting. If at least one
788 * bad battery was found while we computed the total composite
789 * rate, then divide the difference between the total batteries.
790 * Otherwise compute the battery deltas of the composite based
791 * on total summed capacity rate. Otherwise if the total rate
792 * is 0, then the real wait low and high capacities will be on
793 * par with the real capacity.
794 */
795 if (BadBattery)
796 {
797 LowDelta = LowCapDifference / BatteriesCount;
798 HighDelta = HighCapDifference / BatteriesCount;
799 }
800 else
801 {
802 if (TotalRate)
803 {
804 LowDelta = COMPUTE_BATT_CAP_DELTA(LowCapDifference, BatteryData, TotalRate);
805 HighDelta = COMPUTE_BATT_CAP_DELTA(HighCapDifference, BatteryData, TotalRate);
806 }
807 else
808 {
809 LowDelta = 0;
810 HighDelta = 0;
811 }
812 }
813
814 /*
815 * Assign the wait low capacity setting ONLY if the battery delta
816 * is not high. Otherwise it has overflowed and we cannot use that
817 * for low capacity, of which we have to default it to 0.
818 */
819 if (BatteryData->BatteryStatus.Capacity > LowDelta)
820 {
821 BatteryData->WaitStatus.LowCapacity = BatteryData->BatteryStatus.Capacity - LowDelta;
822 }
823 else
824 {
826 }
827
828 /*
829 * Assign the wait high capacity setting ONLY if the real capacity
830 * is not above the maximum highest capacity constant.
831 */
832 HighestCapacity = COMPBATT_WAIT_MAX_HIGH_CAPACITY - HighDelta;
833 if (HighestCapacity < BatteryData->BatteryStatus.Capacity)
834 {
835 BatteryData->WaitStatus.HighCapacity = HighestCapacity;
836 }
837 else
838 {
839 BatteryData->WaitStatus.HighCapacity = BatteryData->BatteryStatus.Capacity + HighDelta;
840 }
841
842 /*
843 * We have set up the wait values but they are in conflict with the
844 * ones set up by the IRP complete worker. We have to cancel the IRP
845 * so the worker will copy our wait configuration values.
846 */
847 if ((BatteryData->Mode == COMPBATT_READ_STATUS) &&
848 (BatteryData->WaitStatus.PowerState != BatteryData->WorkerBuffer.WorkerWaitStatus.PowerState ||
849 BatteryData->WaitStatus.LowCapacity != BatteryData->WorkerBuffer.WorkerWaitStatus.LowCapacity ||
851 {
853 DbgPrint("CompBatt: Configuration wait values are in conflict\n"
854 " BatteryData->WaitStatus.PowerState -> 0x%lx\n"
855 " BatteryData->WorkerBuffer.WorkerWaitStatus.PowerState -> 0x%lx\n"
856 " BatteryData->WaitStatus.LowCapacity -> %u\n"
857 " BatteryData->WorkerBuffer.WorkerWaitStatus.LowCapacity -> %u\n"
858 " BatteryData->WaitStatus.HighCapacity -> %u\n"
859 " BatteryData->WorkerBuffer.WorkerWaitStatus.HighCapacity -> %u\n",
860 BatteryData->WaitStatus.PowerState,
862 BatteryData->WaitStatus.LowCapacity,
864 BatteryData->WaitStatus.HighCapacity,
866
867 IoCancelIrp(BatteryData->Irp);
868 }
869 }
870 else
871 {
874 }
875 }
876
877 /* We are done with this battery */
878 ExAcquireFastMutex(&DeviceExtension->Lock);
879 IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp);
880 }
881
882 /* Release the lock as we are no longer poking through the batteries list */
883 ExReleaseFastMutex(&DeviceExtension->Lock);
884
885 /* Ensure the composite battery did not incur in drastic changes of tag */
886 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) ||
887 (DeviceExtension->Tag != BatteryTag))
888 {
889 /*
890 * Either the last battery was removed (in this case the composite is no
891 * longer existing) or a battery was removed of which the whole battery
892 * information must be recomputed and such.
893 */
895 DbgPrint("CompBatt: Last battery or a battery was removed, the whole composite data must be recomputed\n");
896
898 }
899
900 return STATUS_SUCCESS;
901}
unsigned char BOOLEAN
_In_ ULONG _In_ PBATTERY_NOTIFY BatteryNotify
Definition: batclass.h:216
_Out_ PULONG BatteryTag
Definition: batclass.h:173
static BOOLEAN CompBattCalculateTotalRateAndLinkedBatteries(_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG TotalRate, _Out_ PULONG BatteriesCount)
Calculates the total discharging/charging rate flow of each individual battery linked with the compos...
Definition: compbatt.c:540
#define COMPUTE_BATT_CAP_DELTA(LowDiff, Batt, TotalRate)
Definition: compbatt.h:56
#define COMPBATT_WAIT_MAX_HIGH_CAPACITY
Definition: compbatt.h:41
#define COMPBATT_WAIT_MIN_LOW_CAPACITY
Definition: compbatt.h:40
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
ULONG LowCapacity
Definition: batclass.h:204
ULONG HighCapacity
Definition: batclass.h:205
ULONG PowerState
Definition: batclass.h:203
BATTERY_WAIT_STATUS WorkerWaitStatus
Definition: compbatt.h:120
union _COMPBATT_BATTERY_DATA::@619 WorkerBuffer

Referenced by CompBattAddDevice().

Variable Documentation

◆ CompBattDebug