ReactOS 0.4.16-dev-555-g690643f
cmbatt.c File Reference
#include "cmbatt.h"
#include <debug.h>
Include dependency graph for cmbatt.c:

Go to the source code of this file.

Functions

VOID NTAPI CmBattPowerCallBack (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Action, IN ULONG Value)
 
VOID NTAPI CmBattWakeDpc (IN PKDPC Dpc, IN PCMBATT_DEVICE_EXTENSION FdoExtension, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
VOID NTAPI CmBattNotifyHandler (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG NotifyValue)
 
VOID NTAPI CmBattUnload (IN PDRIVER_OBJECT DriverObject)
 
static NTSTATUS CmBattGetBattStaticInfo (_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PBOOLEAN UseBix, _Outptr_ PACPI_BATT_STATIC_INFO *BattInfo)
 Retrieves the static information of the battery.
 
static VOID CmBattVerifyBixData (_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Inout_ PBATTERY_INFORMATION Info)
 Verifies the extended battery information (_BIX) and translates such data to the BATTERY_INFORMATION structure.
 
static VOID CmBattVerifyBifData (_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Inout_ PBATTERY_INFORMATION Info)
 Verifies the battery information (_BIF) and translates such data to the BATTERY_INFORMATION structure.
 
NTSTATUS NTAPI CmBattVerifyStaticInfo (_Inout_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG BatteryTag)
 
NTSTATUS NTAPI CmBattOpenClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CmBattIoctl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CmBattQueryTag (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, OUT PULONG Tag)
 
NTSTATUS NTAPI CmBattDisableStatusNotify (IN PCMBATT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI CmBattSetStatusNotify (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG BatteryTag, IN PBATTERY_NOTIFY BatteryNotify)
 
NTSTATUS NTAPI CmBattGetBatteryStatus (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag)
 
NTSTATUS NTAPI 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 NTAPI CmBattQueryStatus (IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag, IN PBATTERY_STATUS BatteryStatus)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 

Variables

ULONG CmBattDebug
 
PCALLBACK_OBJECT CmBattPowerCallBackObject
 
PVOID CmBattPowerCallBackRegistration
 
UNICODE_STRING GlobalRegistryPath
 
KTIMER CmBattWakeDpcTimerObject
 
KDPC CmBattWakeDpcObject
 
PDEVICE_OBJECT AcAdapterPdo
 
LARGE_INTEGER CmBattWakeDpcDelay
 

Function Documentation

◆ CmBattDisableStatusNotify()

NTSTATUS NTAPI CmBattDisableStatusNotify ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 884 of file cmbatt.c.

885{
887 PAGED_CODE();
888 if (CmBattDebug & 0xA) DbgPrint("CmBattDisableStatusNotify\n");
889
890 /* Do we have a trip point */
891 if (DeviceExtension->TripPointSet)
892 {
893 /* Is there a current value set? */
894 if (DeviceExtension->TripPointValue)
895 {
896 /* Reset it back to 0 */
897 DeviceExtension->TripPointValue = 0;
898 Status = CmBattSetTripPpoint(DeviceExtension, 0);
899 if (!NT_SUCCESS(Status))
900 {
901 /* If it failed, set unknown/invalid value */
902 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
903 if (CmBattDebug & 8)
904 DbgPrint("CmBattDisableStatusNotify: SetTripPoint failed - %x\n", Status);
905 }
906 }
907 else
908 {
909 /* No trip point set, so this is a successful no-op */
911 }
912 }
913 else
914 {
915 /* Nothing we can do */
917 }
918
919 /* Return status */
920 return Status;
921}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define BATTERY_UNKNOWN_CAPACITY
Definition: batclass.h:65
ULONG CmBattDebug
Definition: cmbatt.c:17
NTSTATUS NTAPI CmBattSetTripPpoint(PCMBATT_DEVICE_EXTENSION DeviceExtension, ULONG AlarmValue)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by CmBattAddBattery().

◆ CmBattGetBatteryStatus()

NTSTATUS NTAPI CmBattGetBatteryStatus ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  Tag 
)

Definition at line 1083 of file cmbatt.c.

1085{
1086 ULONG PsrData = 0;
1088 BOOLEAN WasDischarging;
1089 ULONG BstState;
1090 ULONG PowerUnit;
1091 ULONG DesignVoltage, PresentRate, RemainingCapacity;
1092 PAGED_CODE();
1094 DbgPrint("CmBattGetBatteryStatus - CmBatt (%08x) Tag (%d)\n", DeviceExtension, Tag);
1095
1096 /* Validate ACPI data */
1097 Status = CmBattVerifyStaticInfo(DeviceExtension, Tag);
1098 if (!NT_SUCCESS(Status)) return Status;
1099
1100 /* Check for delayed status notifications */
1101 if (DeviceExtension->DelayNotification)
1102 {
1103 /* Process them now and don't do any other work */
1105 return Status;
1106 }
1107
1108 /* Get _BST from ACPI */
1109 Status = CmBattGetBstData(DeviceExtension, &DeviceExtension->BstData);
1110 if (!NT_SUCCESS(Status))
1111 {
1112 /* Fail */
1113 InterlockedExchange(&DeviceExtension->ArLockValue, 0);
1114 return Status;
1115 }
1116
1117 /* Remember if the battery was discharging at the time of querying new status */
1118 WasDischarging = !!(DeviceExtension->State & BATTERY_DISCHARGING);
1119
1120 /* Clear current BST information */
1121 DeviceExtension->State = 0;
1122 DeviceExtension->RemainingCapacity = 0;
1123 DeviceExtension->PresentVoltage = 0;
1124 DeviceExtension->Rate = 0;
1125
1126 /* Get battery state */
1127 BstState = DeviceExtension->BstData.State;
1128
1129 /* Is the battery both charging and discharging? */
1130 if ((BstState & ACPI_BATT_STAT_DISCHARG) && (BstState & ACPI_BATT_STAT_CHARGING) &&
1132 DbgPrint("************************ ACPI BIOS BUG ********************\n* "
1133 "CmBattGetBatteryStatus: Invalid state: _BST method returned 0x%08x for Battery State.\n"
1134 "* One battery cannot be charging and discharging at the same time.\n",
1135 BstState);
1136
1137 /* Is the battery discharging? */
1138 if (BstState & ACPI_BATT_STAT_DISCHARG)
1139 {
1140 /* Set power state and check if it just started discharging now */
1141 DeviceExtension->State |= BATTERY_DISCHARGING;
1142 if (!WasDischarging)
1143 {
1144 /* The battery is discharging now and not before, remember the time when the state changed */
1145 DeviceExtension->InterruptTime = KeQueryInterruptTime();
1146 }
1147 }
1148 else if (BstState & ACPI_BATT_STAT_CHARGING)
1149 {
1150 /* Battery is charging, update power state */
1151 DeviceExtension->State |= (BATTERY_CHARGING | BATTERY_POWER_ON_LINE);
1152 }
1153
1154 /* Is the battery in a critical state? */
1155 if (BstState & ACPI_BATT_STAT_CRITICAL) DeviceExtension->State |= BATTERY_CRITICAL;
1156
1157 /* Read the voltage data */
1158 DeviceExtension->PresentVoltage = DeviceExtension->BstData.PresentVoltage;
1159
1160 /* Check if we have an A/C adapter */
1161 if (AcAdapterPdo)
1162 {
1163 /* Query information on it */
1164 CmBattGetPsrData(AcAdapterPdo, &PsrData);
1165 }
1166 else
1167 {
1168 /* Otherwise, check if the battery is charging */
1169 if (BstState & ACPI_BATT_STAT_CHARGING)
1170 {
1171 /* Then we'll assume there's a charger */
1172 PsrData = 1;
1173 }
1174 else
1175 {
1176 /* Assume no charger */
1177 PsrData = 0;
1178 }
1179 }
1180
1181 /* Is there a charger? */
1182 if (PsrData)
1183 {
1184 /* Set the power state flag to reflect this */
1185 DeviceExtension->State |= BATTERY_POWER_ON_LINE;
1187 DbgPrint("CmBattGetBatteryStatus: AC adapter is connected\n");
1188 }
1190 {
1191 DbgPrint("CmBattGetBatteryStatus: AC adapter is NOT connected\n");
1192 }
1193
1194 /* Is this machine supporting _BIX or _BIF? */
1195 if (DeviceExtension->BattInfo.ExtendedData)
1196 {
1197 PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit;
1198 DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage;
1199 }
1200 else
1201 {
1202 PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit;
1203 DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage;
1204 }
1205
1206 /* Get some data we'll need */
1207 PresentRate = DeviceExtension->BstData.PresentRate;
1208 RemainingCapacity = DeviceExtension->BstData.RemainingCapacity;
1209
1210 /* Check if we have battery data in Watts instead of Amps */
1211 if (PowerUnit == ACPI_BATT_POWER_UNIT_WATTS)
1212 {
1213 /* Get the data from the BST */
1214 DeviceExtension->RemainingCapacity = RemainingCapacity;
1215 DeviceExtension->Rate = PresentRate;
1216
1217 /* Check if the rate is invalid */
1218 if (PresentRate > CM_MAX_VALUE)
1219 {
1220 /* Set an unknown rate and don't touch the old value */
1221 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
1222 if ((PresentRate != CM_UNKNOWN_VALUE) && (CmBattDebug & CMBATT_ACPI_WARNING))
1223 {
1224 DbgPrint("CmBattGetBatteryStatus - Rate is greater than CM_MAX_VALUE\n");
1225 DbgPrint("---------------------- PresentRate = 0x%08x\n", PresentRate);
1226 }
1227 }
1228 }
1229 else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage != 0)) // Same as doing PowerUnit == ACPI_BATT_POWER_UNIT_AMPS
1230 {
1231 /* We have voltage data, what about capacity? */
1232 if (RemainingCapacity == CM_UNKNOWN_VALUE)
1233 {
1234 /* Unable to calculate it */
1235 DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
1237 {
1238 DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity \n");
1239 DbgPrint("---------------------- RemainingCapacity = CM_UNKNOWN_VALUE\n");
1240 }
1241 }
1242 else
1243 {
1244 /* Compute the capacity with the information we have */
1245 DeviceExtension->RemainingCapacity = (DesignVoltage * RemainingCapacity + 500) / 1000;
1246 }
1247
1248 /* Check if we have a rate */
1249 if (PresentRate != CM_UNKNOWN_VALUE)
1250 {
1251 /* Make sure the rate isn't too large */
1252 if (PresentRate > (-500 / DesignVoltage))
1253 {
1254 /* It is, so set unknown state */
1255 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
1257 {
1258 DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
1259 DbgPrint("---------------------- Overflow: PresentRate = 0x%08x\n", PresentRate);
1260 }
1261 }
1262
1263 /* Compute the rate */
1264 DeviceExtension->Rate = (PresentRate * DesignVoltage + 500) / 1000;
1265 }
1266 else
1267 {
1268 /* We don't have a rate, so set unknown value */
1269 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
1271 {
1272 DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
1273 DbgPrint("---------------------- Present Rate = CM_UNKNOWN_VALUE\n");
1274 }
1275 }
1276 }
1277 else
1278 {
1279 /* We have no rate, and no capacity, set unknown values */
1280 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
1281 DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
1283 {
1284 DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity and Rate \n");
1285 DbgPrint("---------------------- DesignVoltage = 0x%08x\n", DesignVoltage);
1286 }
1287 }
1288
1289 /* Check if we have an unknown rate */
1290 if (DeviceExtension->Rate == BATTERY_UNKNOWN_RATE)
1291 {
1292 /* The battery is discharging but we don't know by how much... this is bad! */
1293 if ((BstState & ACPI_BATT_STAT_DISCHARG) &&
1295 DbgPrint("CmBattGetBatteryStatus: battery rate is unknown when battery is not charging!\n");
1296 }
1297 else if (DeviceExtension->State & BATTERY_DISCHARGING)
1298 {
1299 /* The battery is discharging, so treat the rate as a negative rate */
1300 DeviceExtension->Rate = -(LONG)DeviceExtension->Rate;
1301 }
1302 else if (!(DeviceExtension->State & BATTERY_CHARGING) && (DeviceExtension->Rate))
1303 {
1304 /* We are not charging, not discharging, but have a rate? Ignore it! */
1306 DbgPrint("CmBattGetBatteryStatus: battery is not charging or discharging, but rate = %x\n",
1307 DeviceExtension->Rate);
1308 DeviceExtension->Rate = 0;
1309 }
1310
1311 /* Done */
1312 return STATUS_SUCCESS;
1313}
unsigned char BOOLEAN
#define InterlockedExchange
Definition: armddk.h:54
#define BATTERY_CRITICAL
Definition: batclass.h:76
#define BATTERY_POWER_ON_LINE
Definition: batclass.h:73
#define BATTERY_DISCHARGING
Definition: batclass.h:74
#define BATTERY_CHARGING
Definition: batclass.h:75
#define BATTERY_UNKNOWN_RATE
Definition: batclass.h:82
PDEVICE_OBJECT AcAdapterPdo
Definition: cmbatt.c:23
NTSTATUS NTAPI CmBattVerifyStaticInfo(_Inout_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _In_ ULONG BatteryTag)
Definition: cmbatt.c:511
VOID NTAPI CmBattNotifyHandler(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG NotifyValue)
Definition: cmbatt.c:142
#define CM_UNKNOWN_VALUE
Definition: cmbatt.h:80
#define CMBATT_GENERIC_INFO
Definition: cmbatt.h:36
#define CMBATT_ACPI_WARNING
Definition: cmbatt.h:38
#define CMBATT_GENERIC_STATUS
Definition: cmbatt.h:35
NTSTATUS NTAPI CmBattGetPsrData(PDEVICE_OBJECT DeviceObject, PULONG PsrData)
#define CM_MAX_VALUE
Definition: cmbatt.h:79
#define ACPI_BATT_POWER_UNIT_WATTS
Definition: cmbatt.h:97
#define ACPI_BATT_STAT_CRITICAL
Definition: cmbatt.h:77
#define CMBATT_GENERIC_WARNING
Definition: cmbatt.h:37
#define ACPI_BATT_STAT_DISCHARG
Definition: cmbatt.h:75
NTSTATUS NTAPI CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BST_DATA BstData)
Definition: cmexec.c:514
#define ACPI_BATT_STAT_CHARGING
Definition: cmbatt.h:76
#define ACPI_BATT_NOTIFY_STATUS
Definition: cmbatt.h:72
long LONG
Definition: pedump.c:60
#define KeQueryInterruptTime()
Definition: ke.h:37
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065

Referenced by CmBattQueryInformation(), and CmBattQueryStatus().

◆ CmBattGetBattStaticInfo()

static NTSTATUS CmBattGetBattStaticInfo ( _In_ PCMBATT_DEVICE_EXTENSION  DeviceExtension,
_Out_ PBOOLEAN  UseBix,
_Outptr_ PACPI_BATT_STATIC_INFO BattInfo 
)
static

Retrieves the static information of the battery.

Parameters
[in]DeviceExtensionA pointer to a Control Method (CM) battery device extension. It is used for debugging purposes.
[out]UseBixA pointer to a boolean value, returned to caller. This can return TRUE if this machine supports the _BIX method, FALSE otherwise.
[out]BattInfoA pointer to a structure that contains the static info of the battery. ONLY ONE type of information is filled. See Remarks.
Returns
Returns STATUS_INSUFFICIENT_RESOURCES if there is no enough memory to allocate for the static info buffer. Returns STATUS_SUCCESS if the operation has succeeded. Otherwise an error NTSTATUS code is returned.
Remarks
It is important to note that a machine can only support one method, _BIX or _BIF. Starting with ACPI 4.0, _BIF has become deprecated. The caller MUST INSPECT the boolean value, ExtendedData, in order to determine if the machine has returned the extended information data or not.

Definition at line 307 of file cmbatt.c.

311{
313 ACPI_BIF_DATA BifData;
314 ACPI_BIX_DATA BixData;
316
317 /* Allocate pool space for the static information */
319 sizeof(*Info),
321 if (Info == NULL)
322 {
324 }
325
326 /* Assume this machine supports the _BIX method */
327 *UseBix = TRUE;
328
329 /* Retrieve extended battery static info from _BIX method */
330 Status = CmBattGetBixData(DeviceExtension, &BixData);
331 if (!NT_SUCCESS(Status))
332 {
333 /*
334 * It failed. This can be expected because not every machine supports
335 * _BIX, especially the older machines which do not support ACPI 4.0.
336 * Fallback to _BIF at this point.
337 */
338 Status = CmBattGetBifData(DeviceExtension, &BifData);
339 if (!NT_SUCCESS(Status))
340 {
341 /* That failed too, time to punt */
343 return Status;
344 }
345
346 /* Acknowledge the caller it will be going to use _BIF */
347 *UseBix = FALSE;
348 Info->BifData = BifData;
349 }
350 else
351 {
352 Info->BixData = BixData;
353 }
354
355 /* Return the battery static info to caller */
356 Info->ExtendedData = *UseBix;
357 *BattInfo = Info;
358 return Status;
359}
NTSTATUS NTAPI CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BIF_DATA BifData)
Definition: cmexec.c:412
#define CMBATT_BATT_STATIC_INFO_TAG
Definition: cmbatt.h:151
NTSTATUS NTAPI CmBattGetBixData(_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PACPI_BIX_DATA BixData)
Retrieves the eXtended static battery information from the ACPI _BIX method.
Definition: cmexec.c:468
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PagedPool
Definition: env_spec_w32.h:308
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by CmBattVerifyStaticInfo().

◆ CmBattIoctl()

NTSTATUS NTAPI CmBattIoctl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 616 of file cmbatt.c.

618{
619 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
621 PIO_STACK_LOCATION IoStackLocation;
623 PAGED_CODE();
624 if (CmBattDebug & 2) DbgPrint("CmBattIoctl\n");
625
626 /* Acquire the remove lock */
627 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
628 if (!NT_SUCCESS(Status))
629 {
630 /* It's too late, fail */
631 Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
634 }
635
636 /* There's nothing to do for an AC adapter */
637 if (DeviceExtension->FdoType == CmBattAcAdapter)
638 {
639 /* Pass it down, and release the remove lock */
641 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
642 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
643 return Status;
644 }
645
646 /* Send to class driver */
647 Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp);
649 {
650 /* Read IOCTL information from IRP stack */
651 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
652 IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
653 OutputBufferLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
654 InputBufferLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
655 if (CmBattDebug & 4)
656 DbgPrint("CmBattIoctl: Received Direct Access IOCTL %x\n", IoControlCode);
657
658 /* Handle internal IOCTLs */
659 switch (IoControlCode)
660 {
662
663 /* Data is 4 bytes long */
664 if (OutputBufferLength == sizeof(ULONG))
665 {
666 /* Query it */
667 Status = CmBattGetUniqueId(DeviceExtension->PdoDeviceObject,
668 Irp->AssociatedIrp.SystemBuffer);
669 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
670 }
671 else
672 {
673 /* Buffer size invalid */
675 }
676 break;
677
679
680 /* Data is 4 bytes long */
681 if (OutputBufferLength == sizeof(ULONG))
682 {
683 /* Query it */
684 Status = CmBattGetStaData(DeviceExtension->PdoDeviceObject,
685 Irp->AssociatedIrp.SystemBuffer);
686 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
687 }
688 else
689 {
690 /* Buffer size invalid */
692 }
693 break;
694
696
697 /* Data is 4 bytes long */
698 if (OutputBufferLength == sizeof(ULONG))
699 {
700 /* Do we have an AC adapter? */
701 if (AcAdapterPdo)
702 {
703 /* Query it */
705 Irp->AssociatedIrp.SystemBuffer);
706 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
707 }
708 else
709 {
710 /* No adapter, just a battery, so fail */
712 }
713 }
714 else
715 {
716 /* Buffer size invalid */
718 }
719 break;
720
722
723 /* Data is 4 bytes long */
724 if (InputBufferLength == sizeof(ULONG))
725 {
726 /* Query it */
727 Status = CmBattSetTripPpoint(DeviceExtension,
728 *(PULONG)Irp->AssociatedIrp.SystemBuffer);
729 Irp->IoStatus.Information = 0;
730 }
731 else
732 {
733 /* Buffer size invalid */
735 }
736 break;
737
739
740 /* Return the battery static information to the caller depending on the supported ACPI method */
741 if (DeviceExtension->BattInfo.ExtendedData)
742 {
743 if (OutputBufferLength == sizeof(ACPI_BIX_DATA))
744 {
745 /* Query it */
746 Status = CmBattGetBixData(DeviceExtension,
747 Irp->AssociatedIrp.SystemBuffer);
748 if (NT_SUCCESS(Status))
749 {
750 Irp->IoStatus.Information = sizeof(ACPI_BIX_DATA);
751 }
752 }
753 else
754 {
755 /* Buffer size invalid */
757 }
758 }
759 else
760 {
761 if (OutputBufferLength == sizeof(ACPI_BIF_DATA))
762 {
763 /* Query it */
764 Status = CmBattGetBifData(DeviceExtension,
765 Irp->AssociatedIrp.SystemBuffer);
766 if (NT_SUCCESS(Status))
767 {
768 Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA);
769 }
770 }
771 else
772 {
773 /* Buffer size invalid */
775 }
776 }
777 break;
778
780
781 /* Data is 16 bytes long */
782 if (OutputBufferLength == sizeof(ACPI_BST_DATA))
783 {
784 /* Query it */
785 Status = CmBattGetBstData(DeviceExtension,
786 Irp->AssociatedIrp.SystemBuffer);
787 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BST_DATA);
788 }
789 else
790 {
791 /* Buffer size invalid */
793 }
794 break;
795
796 default:
797
798 /* Unknown, let us pass it on to ACPI */
799 if (CmBattDebug & 0xC)
800 DbgPrint("CmBattIoctl: Unknown IOCTL %x\n", IoControlCode);
801 break;
802 }
803
804 /* Did someone pick it up? */
806 {
807 /* Complete the request */
808 Irp->IoStatus.Status = Status;
810 }
811 else
812 {
813 /* Still unsupported, try ACPI */
815 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
816 }
817 }
818
819 /* Release the remove lock and return status */
820 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
821 return Status;
822}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
BCLASSAPI NTSTATUS NTAPI BatteryClassIoctl(PVOID ClassData, PIRP Irp)
Definition: battc.c:198
NTSTATUS NTAPI CmBattGetStaData(PDEVICE_OBJECT DeviceObject, PULONG StaData)
#define IOCTL_BATTERY_QUERY_STA
Definition: cmbatt.h:20
struct _ACPI_BIF_DATA ACPI_BIF_DATA
#define IOCTL_BATTERY_QUERY_BST
Definition: cmbatt.h:32
NTSTATUS NTAPI CmBattGetUniqueId(PDEVICE_OBJECT DeviceObject, PULONG UniqueId)
#define IOCTL_BATTERY_SET_TRIP_POINT
Definition: cmbatt.h:26
#define IOCTL_BATTERY_QUERY_PSR
Definition: cmbatt.h:23
#define IOCTL_BATTERY_QUERY_UNIQUE_ID
Definition: cmbatt.h:17
struct _ACPI_BST_DATA ACPI_BST_DATA
#define IOCTL_BATTERY_QUERY_BIF_BIX
Definition: cmbatt.h:29
struct _ACPI_BIX_DATA ACPI_BIX_DATA
@ CmBattAcAdapter
Definition: cmbatt.h:59
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_DEVICE_REMOVED
Definition: d3dkmdt.h:39
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
BOOLEAN ExtendedData
Definition: cmbatt.h:148
CMBATT_EXTENSION_TYPE FdoType
Definition: cmbatt.h:159
ACPI_BATT_STATIC_INFO BattInfo
Definition: cmbatt.h:183
PDEVICE_OBJECT PdoDeviceObject
Definition: cmbatt.h:162
PDEVICE_OBJECT AttachedDevice
Definition: cmbatt.h:163
IO_REMOVE_LOCK RemoveLock
Definition: cmbatt.h:170
struct _IO_STACK_LOCATION::@1583::@1584 DeviceIoControl
union _IO_STACK_LOCATION::@1583 Parameters
uint32_t * PULONG
Definition: typedefs.h:59
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_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
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by DriverEntry().

◆ CmBattNotifyHandler()

VOID NTAPI CmBattNotifyHandler ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  NotifyValue 
)

Definition at line 142 of file cmbatt.c.

144{
145 ULONG ArFlag;
148
150 DbgPrint("CmBattNotifyHandler: CmBatt 0x%08x Type %d Number %d Notify Value: %x\n",
151 DeviceExtension,
152 DeviceExtension->FdoType,
153 DeviceExtension->DeviceId,
154 NotifyValue);
155
156 /* Check what kind of notification was received */
157 switch (NotifyValue)
158 {
159 /* ACPI Specification says is sends a "Bus Check" when power source changes */
160 case ACPI_BUS_CHECK:
161
162 /* We treat it as possible physical change */
163 DeviceExtension->ArFlag |= (CMBATT_AR_NOTIFY | CMBATT_AR_INSERT);
164 if ((DeviceExtension->Tag) &&
166 DbgPrint("CmBattNotifyHandler: Received battery #%x insertion, but tag was not invalid.\n",
167 DeviceExtension->DeviceId);
168 break;
169
170 /* Status of the battery has changed */
172
173 /* All we'll do is notify the class driver */
174 DeviceExtension->ArFlag |= CMBATT_AR_NOTIFY;
175 break;
176
177 /* Information on the battery has changed, such as physical presence */
180
181 /* Reset all state and let the class driver re-evaluate it all */
182 DeviceExtension->ArFlag |= (CMBATT_AR_NOTIFY |
185 break;
186
187 default:
188
190 DbgPrint("CmBattNotifyHandler: Unknown Notify Value: %x\n", NotifyValue);
191 }
192
193 /* Check if we're supposed to delay the notification till later */
194 if (DeviceExtension->DelayNotification)
195 {
196 /* We'll handle this when we get a status query later on */
198 DbgPrint("CmBattNotifyHandler: Notification delayed: ARs = %01x\n",
199 DeviceExtension->ArFlag);
200 return;
201 }
202
203 /* We're going to handle this now */
205 DbgPrint("CmBattNotifyHandler: Performing ARs: %01x\n", DeviceExtension->ArFlag);
206
207 /* Check if this is a battery or AC adapter notification */
208 if (DeviceExtension->FdoType == CmBattBattery)
209 {
210 /* Reset the current trip point */
211 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
212
213 /* Check what ARs have to be done */
214 ArFlag = DeviceExtension->ArFlag;
215
216 /* New battery inserted, reset lock value */
217 if (ArFlag & CMBATT_AR_INSERT) InterlockedExchange(&DeviceExtension->ArLockValue, 0);
218
219 /* Check if the battery may have been removed */
220 if (ArFlag & CMBATT_AR_REMOVE) DeviceExtension->Tag = 0;
221
222 /* Check if there's been any sort of change to the battery */
223 if (ArFlag & CMBATT_AR_NOTIFY)
224 {
225 /* We'll probably end up re-evaluating _BIF and _BST */
226 DeviceExtension->NotifySent = TRUE;
227 BatteryClassStatusNotify(DeviceExtension->ClassData);
228 }
229 }
230 else if (DeviceExtension->ArFlag & CMBATT_AR_NOTIFY)
231 {
232 /* The only known notification is AC/DC change. Loop device objects. */
233 for (DeviceObject = DeviceExtension->FdoDeviceObject->DriverObject->DeviceObject;
235 DeviceObject = DeviceObject->NextDevice)
236 {
237 /* Is this a battery? */
238 FdoExtension = DeviceObject->DeviceExtension;
239 if (FdoExtension->FdoType == CmBattBattery)
240 {
241 /* Send a notification to the class driver */
242 FdoExtension->NotifySent = TRUE;
244 }
245 }
246 }
247
248 /* ARs have been processed */
249 DeviceExtension->ArFlag = 0;
250}
BCLASSAPI NTSTATUS NTAPI BatteryClassStatusNotify(_In_ PVOID ClassData)
Definition: battc.c:79
#define ACPI_BUS_CHECK
Definition: cmbatt.h:63
#define CMBATT_ACPI_ASSERT
Definition: cmbatt.h:43
#define ACPI_BATT_NOTIFY_INFO
Definition: cmbatt.h:73
#define CMBATT_AR_INSERT
Definition: cmbatt.h:154
#define CMBATT_AR_REMOVE
Definition: cmbatt.h:155
#define ACPI_DEVICE_CHECK
Definition: cmbatt.h:64
#define CMBATT_PNP_INFO
Definition: cmbatt.h:40
#define CMBATT_AR_NOTIFY
Definition: cmbatt.h:153
@ CmBattBattery
Definition: cmbatt.h:60
@ FdoExtension
Definition: precomp.h:48

Referenced by CmBattAddAcAdapter(), CmBattAddBattery(), CmBattGetBatteryStatus(), CmBattRemoveDevice(), and CmBattSetStatusNotify().

◆ CmBattOpenClose()

NTSTATUS NTAPI CmBattOpenClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 553 of file cmbatt.c.

555{
557 PIO_STACK_LOCATION IoStackLocation;
558 UCHAR Major;
559 ULONG Count;
560 PCMBATT_DEVICE_EXTENSION DeviceExtension;
561 PAGED_CODE();
562 if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattOpenClose\n");
563
564 /* Grab the device extension and lock it */
565 DeviceExtension = DeviceObject->DeviceExtension;
566 ExAcquireFastMutex(&DeviceExtension->FastMutex);
567
568 /* Check if someone is trying to open a device that doesn't exist yet */
569 Count = DeviceExtension->HandleCount;
570 if (Count == 0xFFFFFFFF)
571 {
572 /* Fail the request */
575 {
576 DbgPrint("CmBattOpenClose: Failed (UID = %x)(device being removed).\n",
577 DeviceExtension->Tag);
578 }
579 goto Complete;
580 }
581
582 /* Check if this is an open or close */
583 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
584 Major = IoStackLocation->MajorFunction;
585 if (Major == IRP_MJ_CREATE)
586 {
587 /* Increment the open count */
588 DeviceExtension->HandleCount = Count + 1;
590 {
591 DbgPrint("CmBattOpenClose: Open (DeviceNumber = %x)(count = %x).\n",
592 DeviceExtension->DeviceId, Count + 1);
593 }
594 }
595 else if (Major == IRP_MJ_CLOSE)
596 {
597 /* Decrement the open count */
598 DeviceExtension->HandleCount = Count - 1;
600 {
601 DbgPrint("CmBattOpenClose: Close (DeviceNumber = %x)(count = %x).\n",
602 DeviceExtension->DeviceId, Count + 1);
603 }
604 }
605
607 /* Release lock and complete request */
608 ExReleaseFastMutex(&DeviceExtension->FastMutex);
609 Irp->IoStatus.Status = Status;
611 return Status;
612}
pRequest Complete(RequestStatus)
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
int Count
Definition: noreturn.cpp:7
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define DPRINT
Definition: sndvol32.h:73
FAST_MUTEX FastMutex
Definition: cmbatt.h:164
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DriverEntry().

◆ CmBattPowerCallBack()

VOID NTAPI CmBattPowerCallBack ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  Action,
IN ULONG  Value 
)

Definition at line 30 of file cmbatt.c.

33{
34 BOOLEAN Cancelled;
36 if (CmBattDebug & 0x10)
37 DbgPrint("CmBattPowerCallBack: action: %d, value: %d \n", Action, Value);
38
39 /* Check if a transition is going to happen */
41 {
42 /* We have just re-entered S0: call the wake DPC in 10 seconds */
43 if (Value == 1)
44 {
45 if (CmBattDebug & 0x10)
46 DbgPrint("CmBattPowerCallBack: Calling CmBattWakeDpc after 10 seconds.\n");
48 if (CmBattDebug & 0x10)
49 DbgPrint("CmBattPowerCallBack: timerCanceled = %d.\n", Cancelled);
50 }
51 else if (Value == 0)
52 {
53 /* We are exiting the S0 state: loop all devices to set the delay flag */
54 if (CmBattDebug & 0x10)
55 DbgPrint("CmBattPowerCallBack: Delaying Notifications\n");
56 for (DeviceObject = DeviceExtension->DeviceObject;
58 DeviceObject = DeviceObject->NextDevice)
59 {
60 /* Set the delay flag */
61 DeviceExtension = DeviceObject->DeviceExtension;
62 DeviceExtension->DelayNotification = TRUE;
63 }
64 }
65 else if (CmBattDebug & 0x10)
66 {
67 /* Unknown value */
68 DbgPrint("CmBattPowerCallBack: unknown argument2 = %08x\n", Value);
69 }
70 }
71}
KDPC CmBattWakeDpcObject
Definition: cmbatt.c:22
KTIMER CmBattWakeDpcTimerObject
Definition: cmbatt.c:21
LARGE_INTEGER CmBattWakeDpcDelay
Definition: cmbatt.c:24
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define PO_CB_SYSTEM_STATE_LOCK

Referenced by DriverEntry().

◆ CmBattQueryInformation()

NTSTATUS NTAPI 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 
)

Definition at line 1317 of file cmbatt.c.

1324{
1326 PVOID QueryData = NULL;
1327 ULONG QueryLength = 0;
1328 ULONG RemainingTime = 0;
1329 ANSI_STRING TempString;
1330 UNICODE_STRING TempString2;
1331 WCHAR InfoBuffer[256];
1332 WCHAR TempBuffer[256];
1333 UNICODE_STRING InfoString;
1334 ULONG RemainingCapacity;
1335 BATTERY_REPORTING_SCALE BatteryReportingScale[2];
1336 LONG Rate;
1337 PAGED_CODE();
1339 DbgPrint("CmBattQueryInformation - Tag (%d) Device %d, Informationlevel %d\n",
1340 Tag,
1341 FdoExtension->DeviceId,
1342 InfoLevel);
1343
1344 /* Check ACPI Data */
1346 if (!NT_SUCCESS(Status)) return Status;
1347
1348 /* Check what caller wants */
1349 switch (InfoLevel)
1350 {
1351 case BatteryInformation:
1352 /* Just return our static information */
1353 QueryData = &FdoExtension->BatteryInformation;
1354 QueryLength = sizeof(BATTERY_INFORMATION);
1355 break;
1356
1358
1359 /* Return our static information, we have two scales */
1360 BatteryReportingScale[0].Granularity = FdoExtension->BatteryCapacityGranularity1;
1361 BatteryReportingScale[0].Capacity = FdoExtension->BatteryInformation.DefaultAlert1;
1362 BatteryReportingScale[1].Granularity = FdoExtension->BatteryCapacityGranularity2;
1363 BatteryReportingScale[1].Capacity = FdoExtension->BatteryInformation.DesignedCapacity;
1364 QueryData = BatteryReportingScale;
1365 QueryLength = sizeof(BATTERY_REPORTING_SCALE) * 2;
1366 break;
1367
1369
1370 /* Check if it's been more than 15 seconds since the last change */
1371 if (KeQueryInterruptTime() > (FdoExtension->InterruptTime + CMBATT_DISCHARGE_TIME))
1372 {
1373 /* Get new battery status */
1375
1376 /* If the caller didn't specify a rate, use our static one */
1377 Rate = AtRate;
1378 if (!Rate) Rate = FdoExtension->Rate;
1379
1380 /* If we don't have a valid negative rate, use unknown value */
1381 if (Rate >= 0) Rate = BATTERY_UNKNOWN_RATE;
1382
1383 /* Grab the remaining capacity */
1384 RemainingCapacity = FdoExtension->RemainingCapacity;
1385
1386 /* Default time to unknown if we fail the request later */
1387 RemainingTime = BATTERY_UNKNOWN_TIME;
1388
1389 /* See if we don't know one or the other */
1390 if ((Rate == BATTERY_UNKNOWN_RATE) ||
1391 (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY))
1392 {
1393 /* If the battery is discharging, we can't give out a time */
1394 if ((FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG) &&
1396 DbgPrint("CmBattQueryInformation: Can't calculate EstimatedTime.\n");
1397
1398 /* Check if we don't have a rate and capacity is going down */
1399 if ((FdoExtension->Rate == BATTERY_UNKNOWN_RATE) &&
1400 (FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG))
1401 {
1402 /* We have to fail, since we lack data */
1405 DbgPrint("---------------------- PresentRate = BATTERY_UNKNOWN_RATE\n");
1406 }
1407
1408 /* If we don't have capacity, the rate is useless */
1409 if (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)
1410 {
1411 /* We have to fail the request */
1414 DbgPrint("---------------------- RemainingCapacity = BATTERY_UNKNOWN_CAPACITY\n");
1415 }
1416 }
1417 else
1418 {
1419 /* We have data, but is it valid? */
1420 if (RemainingCapacity > CMBATT_CAPACITY_BOGUS)
1421 {
1422 /* The capacity seems bogus, so don't use it */
1424 DbgPrint("CmBattQueryInformation: Data Overflow in calculating Remaining Capacity.\n");
1425 }
1426 else
1427 {
1428 /* Compute the remaining time in seconds, based on rate */
1429 RemainingTime = (RemainingCapacity * 3600) / -Rate;
1430 }
1431 }
1432 }
1433 else
1434 {
1435 RemainingTime = BATTERY_UNKNOWN_TIME;
1436 }
1437
1438 /* Return the remaining time */
1439 QueryData = &RemainingTime;
1440 QueryLength = sizeof(ULONG);
1441 break;
1442
1443 case BatteryDeviceName:
1444
1445 /* Build the model number string */
1446 if (FdoExtension->BattInfo.ExtendedData)
1447 {
1448 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber);
1449 }
1450 else
1451 {
1452 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber);
1453 }
1454
1455 /* Convert it to Unicode */
1456 InfoString.Buffer = InfoBuffer;
1457 InfoString.MaximumLength = sizeof(InfoBuffer);
1458 Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1459
1460 /* Return the unicode buffer */
1461 QueryData = InfoString.Buffer;
1462 QueryLength = InfoString.Length;
1463 break;
1464
1465 case BatteryTemperature:
1467
1468 /* We don't support these */
1470 break;
1471
1473
1474 /* Build the OEM info string */
1475 if (FdoExtension->BattInfo.ExtendedData)
1476 {
1477 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo);
1478 }
1479 else
1480 {
1481 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo);
1482 }
1483
1484 /* Convert it to Unicode */
1485 InfoString.Buffer = InfoBuffer;
1486 InfoString.MaximumLength = sizeof(InfoBuffer);
1487 Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1488
1489 /* Return the unicode buffer */
1490 QueryData = InfoString.Buffer;
1491 QueryLength = InfoString.Length;
1492 break;
1493
1494 case BatteryUniqueID:
1495
1496 /* Build the serial number string */
1497 if (FdoExtension->BattInfo.ExtendedData)
1498 {
1499 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.SerialNumber);
1500 }
1501 else
1502 {
1503 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.SerialNumber);
1504 }
1505
1506 /* Convert it to Unicode */
1507 InfoString.Buffer = InfoBuffer;
1508 InfoString.MaximumLength = sizeof(InfoBuffer);
1509 RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1510
1511 /* Setup a temporary string for concatenation */
1512 TempString2.Buffer = TempBuffer;
1513 TempString2.MaximumLength = sizeof(TempBuffer);
1514
1515 /* Check if there's an OEM string */
1516 if ((FdoExtension->BattInfo.ExtendedData && FdoExtension->BattInfo.BixData.OemInfo[0]) ||
1517 FdoExtension->BattInfo.BifData.OemInfo[0])
1518 {
1519 /* Build the OEM info string */
1520 if (FdoExtension->BattInfo.ExtendedData)
1521 {
1522 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo);
1523 }
1524 else
1525 {
1526 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo);
1527 }
1528
1529 /* Convert it to Unicode and append it */
1530 RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1531 RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1532 }
1533
1534 /* Build the model number string */
1535 if (FdoExtension->BattInfo.ExtendedData)
1536 {
1537 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber);
1538 }
1539 else
1540 {
1541 RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber);
1542 }
1543
1544 /* Convert it to Unicode and append it */
1545 RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1546 RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1547
1548 /* Return the final appended string */
1549 QueryData = InfoString.Buffer;
1550 QueryLength = InfoString.Length;
1551 break;
1552
1553 default:
1554
1555 /* Everything else is unknown */
1557 break;
1558 }
1559
1560 /* Return the required length and check if the caller supplied enough */
1561 *ReturnedLength = QueryLength;
1562 if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
1563
1564 /* Copy the data if there's enough space and it exists */
1565 if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength);
1566
1567 /* Return function result */
1568 return Status;
1569}
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG AtRate
Definition: batclass.h:185
struct _BATTERY_INFORMATION BATTERY_INFORMATION
@ BatteryInformation
Definition: batclass.h:97
@ BatteryManufactureName
Definition: batclass.h:103
@ BatteryGranularityInformation
Definition: batclass.h:98
@ BatteryUniqueID
Definition: batclass.h:104
@ BatteryEstimatedTime
Definition: batclass.h:100
@ BatteryDeviceName
Definition: batclass.h:101
@ BatteryTemperature
Definition: batclass.h:99
@ BatteryManufactureDate
Definition: batclass.h:102
#define BATTERY_UNKNOWN_TIME
Definition: batclass.h:68
Definition: bufpool.h:45
NTSTATUS NTAPI CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag)
Definition: cmbatt.c:1083
#define CMBATT_CAPACITY_BOGUS
Definition: cmbatt.h:55
#define CMBATT_DISCHARGE_TIME
Definition: cmbatt.h:49
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CmBattAddBattery().

◆ CmBattQueryStatus()

NTSTATUS NTAPI CmBattQueryStatus ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  Tag,
IN PBATTERY_STATUS  BatteryStatus 
)

Definition at line 1573 of file cmbatt.c.

1576{
1578 PAGED_CODE();
1580 DbgPrint("CmBattQueryStatus - Tag (%d) Device %x\n", Tag, DeviceExtension->DeviceId);
1581
1582 /* Query ACPI information */
1583 Status = CmBattGetBatteryStatus(DeviceExtension, Tag);
1584 if (NT_SUCCESS(Status))
1585 {
1586 BatteryStatus->PowerState = DeviceExtension->State;
1587 BatteryStatus->Capacity = DeviceExtension->RemainingCapacity;
1588 BatteryStatus->Voltage = DeviceExtension->PresentVoltage;
1589 BatteryStatus->Rate = DeviceExtension->Rate;
1590 }
1591
1592 /* Return status */
1594 DbgPrint("CmBattQueryStatus: Returning [%#08lx][%#08lx][%#08lx][%#08lx]\n",
1599 return Status;
1600}
_In_ ULONG _Out_ PBATTERY_STATUS BatteryStatus
Definition: batclass.h:199
ULONG PowerState
Definition: batclass.h:154
ULONG Capacity
Definition: batclass.h:155

Referenced by CmBattAddBattery().

◆ CmBattQueryTag()

NTSTATUS NTAPI CmBattQueryTag ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
OUT PULONG  Tag 
)

Definition at line 826 of file cmbatt.c.

828{
829 PDEVICE_OBJECT PdoDevice;
830 ULONG StaData;
832 PAGED_CODE();
834 DbgPrint("CmBattQueryTag - Tag (%d), Battery %x, Device %d\n",
835 *Tag, DeviceExtension, DeviceExtension->DeviceId);
836
837 /* Get PDO and clear notification flag */
838 PdoDevice = DeviceExtension->PdoDeviceObject;
839 DeviceExtension->NotifySent = 0;
840
841 /* Get _STA from PDO (we need the machine status, not the battery status) */
842 Status = CmBattGetStaData(PdoDevice, &StaData);
843 if (NT_SUCCESS(Status))
844 {
845 /* Is a battery present? */
846 if (StaData & ACPI_STA_BATTERY_PRESENT)
847 {
848 /* Do we not have a tag yet? */
849 if (DeviceExtension->Tag == BATTERY_TAG_INVALID)
850 {
851 /* Set the new tag value, reset tags if we reached the maximum */
852 if (++DeviceExtension->TagData == BATTERY_TAG_INVALID)
853 DeviceExtension->TagData = 1;
854 DeviceExtension->Tag = DeviceExtension->TagData;
856 DbgPrint("CmBattQueryTag - New Tag: (%d)\n", DeviceExtension->Tag);
857
858 /* Reset trip point data */
859 DeviceExtension->TripPointOld = 0;
860 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
861
862 /* Clear AR lock and set new interrupt time */
863 InterlockedExchange(&DeviceExtension->ArLockValue, 0);
864 DeviceExtension->InterruptTime = KeQueryInterruptTime();
865 }
866 }
867 else
868 {
869 /* No battery, so no tag */
870 DeviceExtension->Tag = BATTERY_TAG_INVALID;
872 }
873 }
874
875 /* Return the tag and status result */
876 *Tag = DeviceExtension->Tag;
878 DbgPrint("CmBattQueryTag: Returning Tag: 0x%x, status 0x%x\n", *Tag, Status);
879 return Status;
880}
#define ACPI_STA_BATTERY_PRESENT
Definition: actypes.h:1344
#define BATTERY_TAG_INVALID
Definition: batclass.h:94

Referenced by CmBattAddBattery().

◆ CmBattSetStatusNotify()

NTSTATUS NTAPI CmBattSetStatusNotify ( IN PCMBATT_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  BatteryTag,
IN PBATTERY_NOTIFY  BatteryNotify 
)

Definition at line 925 of file cmbatt.c.

928{
930 ACPI_BST_DATA BstData;
931 ULONG PowerUnit, Capacity, NewTripPoint, TripPoint, DesignVoltage;
932 BOOLEAN Charging;
933 PAGED_CODE();
935 DbgPrint("CmBattSetStatusNotify: Tag (%d) Target(0x%x)\n",
937
938 /* Update any ACPI evaluations */
939 Status = CmBattVerifyStaticInfo(DeviceExtension, BatteryTag);
940 if (!NT_SUCCESS(Status)) return Status;
941
942 /* Trip point not supported, fail */
943 if (!DeviceExtension->TripPointSet) return STATUS_OBJECT_NAME_NOT_FOUND;
944
945 /* Are both capacities known? */
948 {
949 /* We can't set trip points without these */
951 DbgPrint("CmBattSetStatusNotify: Failing request because of BATTERY_UNKNOWN_CAPACITY.\n");
953 }
954
955 /* Is the battery charging? */
956 Charging = DeviceExtension->BstData.State & ACPI_BATT_STAT_CHARGING;
957 if (Charging)
958 {
959 /* Then the trip point is when we hit the cap */
960 Capacity = BatteryNotify->HighCapacity;
961 NewTripPoint = BatteryNotify->HighCapacity;
962 }
963 else
964 {
965 /* Otherwise it's when we discharge to the bottom */
966 Capacity = BatteryNotify->LowCapacity;
967 NewTripPoint = BatteryNotify->LowCapacity;
968 }
969
970 /* Is this machine supporting _BIX or _BIF? */
971 if (DeviceExtension->BattInfo.ExtendedData)
972 {
973 PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit;
974 DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage;
975 }
976 else
977 {
978 PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit;
979 DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage;
980 }
981
982 /* Do we have data in Amps or Watts? */
983 if (PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
984 {
985 /* We need the voltage to do the conversion */
986 if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage))
987 {
988 /* Convert from mAh into Ah */
989 TripPoint = 1000 * NewTripPoint;
990 if (Charging)
991 {
992 /* Scale the high trip point */
993 NewTripPoint = (TripPoint + 500) / DesignVoltage + ((TripPoint + 500) % DesignVoltage != 0);
994 }
995 else
996 {
997 /* Scale the low trip point */
998 NewTripPoint = (TripPoint - 500) / DesignVoltage - ((TripPoint - 500) % DesignVoltage == 0);
999 }
1000 }
1001 else
1002 {
1003 /* Without knowing the voltage, Amps are not enough data on consumption */
1006 DbgPrint("CmBattSetStatusNotify: Can't calculate BTP, DesignVoltage = 0x%08x\n",
1007 DesignVoltage);
1008 }
1009 }
1010 else if (Charging)
1011 {
1012 /* Make it trip just one past the charge cap */
1013 ++NewTripPoint;
1014 }
1015 else if (NewTripPoint > 0)
1016 {
1017 /* Make it trip just one below the drain cap */
1018 --NewTripPoint;
1019 }
1020
1021 /* Do we actually have a new trip point? */
1022 if (NewTripPoint == DeviceExtension->TripPointValue)
1023 {
1024 /* No, so there is no work to be done */
1026 DbgPrint("CmBattSetStatusNotify: Keeping original setting: %X\n", DeviceExtension->TripPointValue);
1027 return STATUS_SUCCESS;
1028 }
1029
1030 /* Set the trip point with ACPI and check for success */
1031 DeviceExtension->TripPointValue = NewTripPoint;
1032 Status = CmBattSetTripPpoint(DeviceExtension, NewTripPoint);
1033 if (!(NewTripPoint) && (Capacity)) Status = STATUS_NOT_SUPPORTED;
1034 if (!NT_SUCCESS(Status))
1035 {
1036 /* We failed to set the trip point, or there wasn't one settable */
1037 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
1039 DbgPrint("CmBattSetStatusNotify: SetTripPoint failed - %x\n", Status);
1040 return Status;
1041 }
1042
1043 /* Read the new BST data to see the latest state */
1044 Status = CmBattGetBstData(DeviceExtension, &BstData);
1045 if (!NT_SUCCESS(Status))
1046 {
1047 /* We'll return failure to the caller */
1049 DbgPrint("CmBattSetStatusNotify: GetBstData - %x\n", Status);
1050 }
1051 else if ((Charging) && (BstData.RemainingCapacity >= NewTripPoint))
1052 {
1053 /* We are charging and our capacity is past the trip point, so trip now */
1055 DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
1056 NewTripPoint, BstData.RemainingCapacity);
1058 }
1059 else if ((BstData.RemainingCapacity) && (Capacity))
1060 {
1061 /* We are discharging, and our capacity is below the trip point, trip now */
1063 DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
1064 NewTripPoint, BstData.RemainingCapacity);
1066 }
1067
1068 /* All should've went well if we got here, unless BST failed... return! */
1070 DbgPrint("CmBattSetStatusNotify: Want %X CurrentCap %X\n",
1071 Capacity, DeviceExtension->RemainingCapacity);
1073 DbgPrint("CmBattSetStatusNotify: Set to: [%#08lx][%#08lx][%#08lx] Status %lx\n",
1077 Status);
1078 return Status;
1079}
_In_ ULONG _In_ PBATTERY_NOTIFY BatteryNotify
Definition: batclass.h:216
_Out_ PULONG BatteryTag
Definition: batclass.h:173
#define BATTERY_UNKNOWN_VOLTAGE
Definition: batclass.h:79
#define ACPI_BATT_POWER_UNIT_AMPS
Definition: cmbatt.h:98
ULONG RemainingCapacity
Definition: cmbatt.h:93
ULONG LowCapacity
Definition: batclass.h:204
ULONG HighCapacity
Definition: batclass.h:205
ULONG PowerState
Definition: batclass.h:203

Referenced by CmBattAddBattery().

◆ CmBattUnload()

VOID NTAPI CmBattUnload ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 254 of file cmbatt.c.

255{
256 if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattUnload: \n");
257
258 /* Check if we have a registered power callback */
260 {
261 /* Get rid of it */
264 }
265
266 /* Free the registry buffer if it exists */
268
269 /* Make sure we don't still have references to the DO */
270 if ((DriverObject->DeviceObject) && (CmBattDebug & CMBATT_GENERIC_WARNING))
271 {
272 DbgPrint("Unload called before all devices removed.\n");
273 }
274}
PCALLBACK_OBJECT CmBattPowerCallBackObject
Definition: cmbatt.c:18
PVOID CmBattPowerCallBackRegistration
Definition: cmbatt.c:19
UNICODE_STRING GlobalRegistryPath
Definition: cmbatt.c:20
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
Definition: callback.c:636
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by DriverEntry().

◆ CmBattVerifyBifData()

static VOID CmBattVerifyBifData ( _In_ PCMBATT_DEVICE_EXTENSION  DeviceExtension,
_Inout_ PBATTERY_INFORMATION  Info 
)
static

Verifies the battery information (_BIF) and translates such data to the BATTERY_INFORMATION structure.

Parameters
[in]DeviceExtensionA pointer to a Control Method (CM) battery device extension. It is used to gather _BIF data.
[in,out]InfoA pointer to a structure of which this function fills in battery information that can be by other battery miniport drivers, such as the Composite Battery driver.

Definition at line 451 of file cmbatt.c.

454{
455 ULONG DesignVoltage;
456 ACPI_BIF_DATA BifData = DeviceExtension->BattInfo.BifData;
457
458 /* Copy the battery info data, CycleCount is not supported in _BIF */
459 Info->Technology = BifData.BatteryTechnology;
460 Info->CycleCount = 0;
461 RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4);
462
463 /* Check if the power stats are reported in ampere or watts */
465 {
466 /*
467 * We have got power stats in milli-ampere but ReactOS expects the values
468 * to be reported in milli-watts, so we have to convert them.
469 * In order to do so we must expect the design voltage of the battery
470 * is not unknown.
471 */
472 DesignVoltage = BifData.DesignVoltage;
473 if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0))
474 {
475 /* Convert the design capacity */
476 Info->DesignedCapacity = CONVERT_BATT_INFO(BifData.DesignCapacity, DesignVoltage);
477
478 /* Convert the full charged capacity */
479 Info->FullChargedCapacity = CONVERT_BATT_INFO(BifData.LastFullCapacity, DesignVoltage);
480
481 /* Convert the low capacity alarm (DefaultAlert1) */
482 Info->DefaultAlert1 = CONVERT_BATT_INFO(BifData.DesignCapacityLow, DesignVoltage);
483
484 /* Convert the designed capacity warning alarm (DefaultAlert2) */
485 Info->DefaultAlert2 = CONVERT_BATT_INFO(BifData.DesignCapacityWarning, DesignVoltage);
486 }
487 else
488 {
489 /*
490 * Without knowing the nominal designed voltage of the battery
491 * we cannot determine the power consumption of this battery.
492 */
493 Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
494 Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
495 Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
496 Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
497 }
498 }
499 else
500 {
501 /* The stats are in milli-watts, use them directly */
502 Info->DesignedCapacity = BifData.DesignCapacity;
503 Info->FullChargedCapacity = BifData.LastFullCapacity;
504 Info->DefaultAlert1 = BifData.DesignCapacityLow;
505 Info->DefaultAlert2 = BifData.DesignCapacityWarning;
506 }
507}
#define CONVERT_BATT_INFO(Capacity, DesignVoltage)
Definition: cmbatt.h:84
ULONG DesignCapacityLow
Definition: cmbatt.h:110
ULONG DesignVoltage
Definition: cmbatt.h:108
ULONG LastFullCapacity
Definition: cmbatt.h:106
ULONG DesignCapacity
Definition: cmbatt.h:105
ULONG BatteryTechnology
Definition: cmbatt.h:107
CHAR BatteryType[ASCIIZ_MAX_LENGTH]
Definition: cmbatt.h:115
ULONG DesignCapacityWarning
Definition: cmbatt.h:109
ULONG PowerUnit
Definition: cmbatt.h:104

Referenced by CmBattVerifyStaticInfo().

◆ CmBattVerifyBixData()

static VOID CmBattVerifyBixData ( _In_ PCMBATT_DEVICE_EXTENSION  DeviceExtension,
_Inout_ PBATTERY_INFORMATION  Info 
)
static

Verifies the extended battery information (_BIX) and translates such data to the BATTERY_INFORMATION structure.

Parameters
[in]DeviceExtensionA pointer to a Control Method (CM) battery device extension. It is used to gather _BIX data.
[in,out]InfoA pointer to a structure of which this function fills in battery information that can be by other battery miniport drivers, such as the Composite Battery driver.

Definition at line 377 of file cmbatt.c.

380{
381 ULONG DesignVoltage;
382 ACPI_BIX_DATA BixData = DeviceExtension->BattInfo.BixData;
383
384 /* Copy the battery info data */
385 Info->Technology = BixData.BatteryTechnology;
386 Info->CycleCount = BixData.CycleCount;
387 RtlCopyMemory(Info->Chemistry, BixData.BatteryType, 4);
388
389 /* Check if the power stats are reported in ampere or watts */
391 {
392 /*
393 * We have got power stats in milli-ampere but ReactOS expects the values
394 * to be reported in milli-watts, so we have to convert them.
395 * In order to do so we must expect the design voltage of the battery
396 * is not unknown.
397 */
398 DesignVoltage = BixData.DesignVoltage;
399 if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0))
400 {
401 /* Convert the design capacity */
402 Info->DesignedCapacity = CONVERT_BATT_INFO(BixData.DesignCapacity, DesignVoltage);
403
404 /* Convert the full charged capacity */
405 Info->FullChargedCapacity = CONVERT_BATT_INFO(BixData.LastFullCapacity, DesignVoltage);
406
407 /* Convert the low capacity alarm (DefaultAlert1) */
408 Info->DefaultAlert1 = CONVERT_BATT_INFO(BixData.DesignCapacityLow, DesignVoltage);
409
410 /* Convert the designed capacity warning alarm (DefaultAlert2) */
411 Info->DefaultAlert2 = CONVERT_BATT_INFO(BixData.DesignCapacityWarning, DesignVoltage);
412 }
413 else
414 {
415 /*
416 * Without knowing the nominal designed voltage of the battery
417 * we cannot determine the power consumption of this battery.
418 */
419 Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
420 Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
421 Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
422 Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
423 }
424 }
425 else
426 {
427 /* The stats are in milli-watts, use them directly */
428 Info->DesignedCapacity = BixData.DesignCapacity;
429 Info->FullChargedCapacity = BixData.LastFullCapacity;
430 Info->DefaultAlert1 = BixData.DesignCapacityLow;
431 Info->DefaultAlert2 = BixData.DesignCapacityWarning;
432 }
433}
CHAR BatteryType[ASCIIZ_MAX_LENGTH]
Definition: cmbatt.h:139
ULONG PowerUnit
Definition: cmbatt.h:122
ULONG BatteryTechnology
Definition: cmbatt.h:125
ULONG DesignCapacityLow
Definition: cmbatt.h:128
ULONG DesignVoltage
Definition: cmbatt.h:126
ULONG LastFullCapacity
Definition: cmbatt.h:124
ULONG DesignCapacity
Definition: cmbatt.h:123
ULONG DesignCapacityWarning
Definition: cmbatt.h:127
ULONG CycleCount
Definition: cmbatt.h:129

Referenced by CmBattVerifyStaticInfo().

◆ CmBattVerifyStaticInfo()

NTSTATUS NTAPI CmBattVerifyStaticInfo ( _Inout_ PCMBATT_DEVICE_EXTENSION  DeviceExtension,
_In_ ULONG  BatteryTag 
)

Definition at line 511 of file cmbatt.c.

514{
516 BOOLEAN UseBix;
517 PACPI_BATT_STATIC_INFO BattInfo;
518 PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation;
519
520 /* FIXME: This function is not fully implemented, more checks need to be implemented */
522
523 /* Retrieve the battery static info */
524 Status = CmBattGetBattStaticInfo(DeviceExtension, &UseBix, &BattInfo);
525 if (NT_SUCCESS(Status))
526 {
527 /* Initialize the battery information data */
528 RtlZeroMemory(Info, sizeof(*Info));
529 Info->Capabilities = BATTERY_SYSTEM_BATTERY;
530
531 /* Copy the static information to the device extension of the battery */
532 RtlCopyMemory(&DeviceExtension->BattInfo, BattInfo, sizeof(*BattInfo));
533
534 /* Check if the data from _BIX has to be used or not */
535 if (UseBix)
536 {
537 CmBattVerifyBixData(DeviceExtension, Info);
538 }
539 else
540 {
541 CmBattVerifyBifData(DeviceExtension, Info);
542 }
543
544 /* Free the static information buffer as we already copied it */
546 }
547
548 return Status;
549}
#define BATTERY_SYSTEM_BATTERY
Definition: batclass.h:62
static VOID CmBattVerifyBixData(_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Inout_ PBATTERY_INFORMATION Info)
Verifies the extended battery information (_BIX) and translates such data to the BATTERY_INFORMATION ...
Definition: cmbatt.c:377
static NTSTATUS CmBattGetBattStaticInfo(_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Out_ PBOOLEAN UseBix, _Outptr_ PACPI_BATT_STATIC_INFO *BattInfo)
Retrieves the static information of the battery.
Definition: cmbatt.c:307
static VOID CmBattVerifyBifData(_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, _Inout_ PBATTERY_INFORMATION Info)
Verifies the battery information (_BIF) and translates such data to the BATTERY_INFORMATION structure...
Definition: cmbatt.c:451
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by CmBattGetBatteryStatus(), CmBattQueryInformation(), and CmBattSetStatusNotify().

◆ CmBattWakeDpc()

VOID NTAPI CmBattWakeDpc ( IN PKDPC  Dpc,
IN PCMBATT_DEVICE_EXTENSION  FdoExtension,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 75 of file cmbatt.c.

79{
80 PDEVICE_OBJECT CurrentObject;
81 BOOLEAN AcNotify = FALSE;
82 PCMBATT_DEVICE_EXTENSION DeviceExtension;
83 ULONG ArFlag;
84 if (CmBattDebug & 2) DbgPrint("CmBattWakeDpc: Entered.\n");
85
86 /* Loop all device objects */
87 for (CurrentObject = FdoExtension->DeviceObject;
88 CurrentObject;
89 CurrentObject = CurrentObject->NextDevice)
90 {
91 /* Turn delay flag off, we're back in S0 */
92 DeviceExtension = CurrentObject->DeviceExtension;
93 DeviceExtension->DelayNotification = 0;
94
95 /* Check if this is an AC adapter */
96 if (DeviceExtension->FdoType == CmBattAcAdapter)
97 {
98 /* Was there a pending notify? */
99 if (DeviceExtension->ArFlag & CMBATT_AR_NOTIFY)
100 {
101 /* We'll send a notify on the next pass */
102 AcNotify = TRUE;
103 DeviceExtension->ArFlag = 0;
104 if (CmBattDebug & 0x20)
105 DbgPrint("CmBattWakeDpc: AC adapter notified\n");
106 }
107 }
108 }
109
110 /* Loop the device objects again */
111 for (CurrentObject = FdoExtension->DeviceObject;
112 CurrentObject;
113 CurrentObject = CurrentObject->NextDevice)
114 {
115 /* Check if this is a battery */
116 DeviceExtension = CurrentObject->DeviceExtension;
117 if (DeviceExtension->FdoType == CmBattBattery)
118 {
119 /* Check what ARs are pending */
120 ArFlag = DeviceExtension->ArFlag;
121 if (CmBattDebug & 0x20)
122 DbgPrint("CmBattWakeDpc: Performing delayed ARs: %01x\n", ArFlag);
123
124 /* Insert notification, clear the lock value */
125 if (ArFlag & CMBATT_AR_INSERT) InterlockedExchange(&DeviceExtension->ArLockValue, 0);
126
127 /* Removal, clear the battery tag */
128 if (ArFlag & CMBATT_AR_REMOVE) DeviceExtension->Tag = 0;
129
130 /* Notification (or AC/DC adapter change from first pass above) */
131 if ((ArFlag & CMBATT_AR_NOTIFY) || (AcNotify))
132 {
133 /* Notify the class driver */
134 BatteryClassStatusNotify(DeviceExtension->ClassData);
135 }
136 }
137 }
138}
BOOLEAN DelayNotification
Definition: cmbatt.h:174
PVOID DeviceExtension
Definition: env_spec_w32.h:418

Referenced by DriverEntry().

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 1604 of file cmbatt.c.

1606{
1610 UNICODE_STRING CallbackName;
1611
1612 /* Allocate registry path */
1617 'MtaB');
1619 {
1620 /* Fail if we're out of memory this early */
1622 DbgPrint("CmBatt: Couldn't allocate pool for registry path.");
1624 }
1625
1626 /* Buffer allocated, copy the string */
1629 DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%wZ\"\n",
1631 RegistryPath);
1632
1633 /* Setup the major dispatchers */
1634 DriverObject->MajorFunction[IRP_MJ_CREATE] = CmBattOpenClose;
1635 DriverObject->MajorFunction[IRP_MJ_CLOSE] = CmBattOpenClose;
1638 DriverObject->MajorFunction[IRP_MJ_PNP] = CmBattPnpDispatch;
1640
1641 /* And the unload routine */
1642 DriverObject->DriverUnload = CmBattUnload;
1643
1644 /* And the add device routine */
1645 DriverExtension = DriverObject->DriverExtension;
1646 DriverExtension->AddDevice = CmBattAddDevice;
1647
1648 /* Create a power callback */
1649 RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
1651 &CallbackName,
1653 NULL,
1654 NULL);
1656 if (!NT_SUCCESS(Status))
1657 {
1658 /* No callback, fail */
1661 DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status);
1662 }
1663 else
1664 {
1665 /* Register the power callback now */
1668 DriverObject);
1670 {
1671 /* Last thing: setup our DPC and timer for battery wake */
1674 }
1675 else
1676 {
1679 DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n");
1680 }
1681
1682 /* All good */
1684 }
1685
1686 /* Return failure or success */
1687 return Status;
1688}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
VOID NTAPI CmBattUnload(IN PDRIVER_OBJECT DriverObject)
Definition: cmbatt.c:254
NTSTATUS NTAPI CmBattOpenClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbatt.c:553
NTSTATUS NTAPI CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbatt.c:616
VOID NTAPI CmBattWakeDpc(IN PKDPC Dpc, IN PCMBATT_DEVICE_EXTENSION FdoExtension, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: cmbatt.c:75
VOID NTAPI CmBattPowerCallBack(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Action, IN ULONG Value)
Definition: cmbatt.c:30
NTSTATUS NTAPI CmBattPowerDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS NTAPI CmBattPnpDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS NTAPI CmBattAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject)
NTSTATUS NTAPI CmBattSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNICODE_NULL
PVOID NTAPI ExRegisterCallback(IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext)
Definition: callback.c:556
NTSTATUS NTAPI ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
Definition: callback.c:361
#define L(x)
Definition: ntvdm.h:50
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_POWER

Variable Documentation

◆ AcAdapterPdo

PDEVICE_OBJECT AcAdapterPdo

◆ CmBattDebug

◆ CmBattPowerCallBackObject

PCALLBACK_OBJECT CmBattPowerCallBackObject

Definition at line 18 of file cmbatt.c.

Referenced by CmBattUnload(), and DriverEntry().

◆ CmBattPowerCallBackRegistration

PVOID CmBattPowerCallBackRegistration

Definition at line 19 of file cmbatt.c.

Referenced by CmBattUnload(), and DriverEntry().

◆ CmBattWakeDpcDelay

LARGE_INTEGER CmBattWakeDpcDelay

Definition at line 24 of file cmbatt.c.

Referenced by CmBattPowerCallBack().

◆ CmBattWakeDpcObject

KDPC CmBattWakeDpcObject

Definition at line 22 of file cmbatt.c.

Referenced by CmBattPowerCallBack(), and DriverEntry().

◆ CmBattWakeDpcTimerObject

KTIMER CmBattWakeDpcTimerObject

Definition at line 21 of file cmbatt.c.

Referenced by CmBattPowerCallBack(), and DriverEntry().

◆ GlobalRegistryPath

UNICODE_STRING GlobalRegistryPath

Definition at line 20 of file cmbatt.c.

Referenced by CmBattUnload(), and DriverEntry().