ReactOS 0.4.16-dev-125-g798ea90
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)
 
NTSTATUS NTAPI CmBattVerifyStaticInfo (PCMBATT_DEVICE_EXTENSION DeviceExtension, 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 625 of file cmbatt.c.

626{
628 PAGED_CODE();
629 if (CmBattDebug & 0xA) DbgPrint("CmBattDisableStatusNotify\n");
630
631 /* Do we have a trip point */
632 if (DeviceExtension->TripPointSet)
633 {
634 /* Is there a current value set? */
635 if (DeviceExtension->TripPointValue)
636 {
637 /* Reset it back to 0 */
638 DeviceExtension->TripPointValue = 0;
639 Status = CmBattSetTripPpoint(DeviceExtension, 0);
640 if (!NT_SUCCESS(Status))
641 {
642 /* If it failed, set unknown/invalid value */
643 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
644 if (CmBattDebug & 8)
645 DbgPrint("CmBattDisableStatusNotify: SetTripPoint failed - %x\n", Status);
646 }
647 }
648 else
649 {
650 /* No trip point set, so this is a successful no-op */
652 }
653 }
654 else
655 {
656 /* Nothing we can do */
658 }
659
660 /* Return status */
661 return Status;
662}
#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 813 of file cmbatt.c.

815{
816 ULONG PsrData = 0;
818 ULONG BstState;
819 ULONG DesignVoltage, PresentRate, RemainingCapacity;
820 PAGED_CODE();
822 DbgPrint("CmBattGetBatteryStatus - CmBatt (%08x) Tag (%d)\n", DeviceExtension, Tag);
823
824 /* Validate ACPI data */
825 Status = CmBattVerifyStaticInfo(DeviceExtension, Tag);
826 if (!NT_SUCCESS(Status)) return Status;
827
828 /* Check for delayed status notifications */
829 if (DeviceExtension->DelayNotification)
830 {
831 /* Process them now and don't do any other work */
833 return Status;
834 }
835
836 /* Get _BST from ACPI */
837 Status = CmBattGetBstData(DeviceExtension, &DeviceExtension->BstData);
838 if (!NT_SUCCESS(Status))
839 {
840 /* Fail */
841 InterlockedExchange(&DeviceExtension->ArLockValue, 0);
842 return Status;
843 }
844
845 /* Clear current BST information */
846 DeviceExtension->State = 0;
847 DeviceExtension->RemainingCapacity = 0;
848 DeviceExtension->PresentVoltage = 0;
849 DeviceExtension->Rate = 0;
850
851 /* Get battery state */
852 BstState = DeviceExtension->BstData.State;
853
854 /* Is the battery both charging and discharging? */
855 if ((BstState & ACPI_BATT_STAT_DISCHARG) && (BstState & ACPI_BATT_STAT_CHARGING) &&
857 DbgPrint("************************ ACPI BIOS BUG ********************\n* "
858 "CmBattGetBatteryStatus: Invalid state: _BST method returned 0x%08x for Battery State.\n"
859 "* One battery cannot be charging and discharging at the same time.\n",
860 BstState);
861
862 /* Is the battery discharging? */
863 if (BstState & ACPI_BATT_STAT_DISCHARG)
864 {
865 /* Set power state and check if it just started discharging now */
866 DeviceExtension->State |= BATTERY_DISCHARGING;
867 if (!(DeviceExtension->State & ACPI_BATT_STAT_DISCHARG))
868 {
869 /* Remember the time when the state changed */
870 DeviceExtension->InterruptTime = KeQueryInterruptTime();
871 }
872 }
873 else if (BstState & ACPI_BATT_STAT_CHARGING)
874 {
875 /* Battery is charging, update power state */
876 DeviceExtension->State |= (BATTERY_CHARGING | BATTERY_POWER_ON_LINE);
877 }
878
879 /* Is the battery in a critical state? */
880 if (BstState & ACPI_BATT_STAT_CRITICAL) DeviceExtension->State |= BATTERY_CRITICAL;
881
882 /* Read the voltage data */
883 DeviceExtension->PresentVoltage = DeviceExtension->BstData.PresentVoltage;
884
885 /* Check if we have an A/C adapter */
886 if (AcAdapterPdo)
887 {
888 /* Query information on it */
890 }
891 else
892 {
893 /* Otherwise, check if the battery is charging */
894 if (BstState & ACPI_BATT_STAT_CHARGING)
895 {
896 /* Then we'll assume there's a charger */
897 PsrData = 1;
898 }
899 else
900 {
901 /* Assume no charger */
902 PsrData = 0;
903 }
904 }
905
906 /* Is there a charger? */
907 if (PsrData)
908 {
909 /* Set the power state flag to reflect this */
910 DeviceExtension->State |= BATTERY_POWER_ON_LINE;
912 DbgPrint("CmBattGetBatteryStatus: AC adapter is connected\n");
913 }
915 {
916 DbgPrint("CmBattGetBatteryStatus: AC adapter is NOT connected\n");
917 }
918
919 /* Get some data we'll need */
920 DesignVoltage = DeviceExtension->BifData.DesignVoltage;
921 PresentRate = DeviceExtension->BstData.PresentRate;
922 RemainingCapacity = DeviceExtension->BstData.RemainingCapacity;
923
924 /* Check if we have battery data in Watts instead of Amps */
925 if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_WATTS)
926 {
927 /* Get the data from the BST */
928 DeviceExtension->RemainingCapacity = RemainingCapacity;
929 DeviceExtension->Rate = PresentRate;
930
931 /* Check if the rate is invalid */
932 if (PresentRate > CM_MAX_VALUE)
933 {
934 /* Set an unknown rate and don't touch the old value */
935 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
936 if ((PresentRate != CM_UNKNOWN_VALUE) && (CmBattDebug & CMBATT_ACPI_WARNING))
937 {
938 DbgPrint("CmBattGetBatteryStatus - Rate is greater than CM_MAX_VALUE\n");
939 DbgPrint("---------------------- PresentRate = 0x%08x\n", PresentRate);
940 }
941 }
942 }
943 else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage))
944 {
945 /* We have voltage data, what about capacity? */
946 if (RemainingCapacity == CM_UNKNOWN_VALUE)
947 {
948 /* Unable to calculate it */
949 DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
951 {
952 DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity \n");
953 DbgPrint("---------------------- RemainingCapacity = CM_UNKNOWN_VALUE\n");
954 }
955 }
956 else
957 {
958 /* Compute the capacity with the information we have */
959 DeviceExtension->RemainingCapacity = (DesignVoltage * RemainingCapacity + 500) / 1000;
960 }
961
962 /* Check if we have a rate */
963 if (PresentRate != CM_UNKNOWN_VALUE)
964 {
965 /* Make sure the rate isn't too large */
966 if (PresentRate > (-500 / DesignVoltage))
967 {
968 /* It is, so set unknown state */
969 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
971 {
972 DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
973 DbgPrint("---------------------- Overflow: PresentRate = 0x%08x\n", PresentRate);
974 }
975 }
976
977 /* Compute the rate */
978 DeviceExtension->Rate = (PresentRate * DesignVoltage + 500) / 1000;
979 }
980 else
981 {
982 /* We don't have a rate, so set unknown value */
983 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
985 {
986 DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
987 DbgPrint("---------------------- Present Rate = CM_UNKNOWN_VALUE\n");
988 }
989 }
990 }
991 else
992 {
993 /* We have no rate, and no capacity, set unknown values */
994 DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
995 DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
997 {
998 DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity and Rate \n");
999 DbgPrint("---------------------- DesignVoltage = 0x%08x\n", DesignVoltage);
1000 }
1001 }
1002
1003 /* Check if we have an unknown rate */
1004 if (DeviceExtension->Rate == BATTERY_UNKNOWN_RATE)
1005 {
1006 /* The battery is discharging but we don't know by how much... this is bad! */
1007 if ((BstState & ACPI_BATT_STAT_DISCHARG) &&
1009 DbgPrint("CmBattGetBatteryStatus: battery rate is unknown when battery is not charging!\n");
1010 }
1011 else if (DeviceExtension->State & BATTERY_DISCHARGING)
1012 {
1013 /* The battery is discharging, so treat the rate as a negative rate */
1014 DeviceExtension->Rate = -(LONG)DeviceExtension->Rate;
1015 }
1016 else if (!(DeviceExtension->State & BATTERY_CHARGING) && (DeviceExtension->Rate))
1017 {
1018 /* We are not charging, not discharging, but have a rate? Ignore it! */
1020 DbgPrint("CmBattGetBatteryStatus: battery is not charging or discharging, but rate = %x\n",
1021 DeviceExtension->Rate);
1022 DeviceExtension->Rate = 0;
1023 }
1024
1025 /* Done */
1026 return STATUS_SUCCESS;
1027}
#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
VOID NTAPI CmBattNotifyHandler(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG NotifyValue)
Definition: cmbatt.c:142
NTSTATUS NTAPI CmBattVerifyStaticInfo(PCMBATT_DEVICE_EXTENSION DeviceExtension, ULONG BatteryTag)
Definition: cmbatt.c:278
#define CM_UNKNOWN_VALUE
Definition: cmbatt.h:68
#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:67
#define ACPI_BATT_POWER_UNIT_WATTS
Definition: cmbatt.h:78
#define ACPI_BATT_STAT_CRITICAL
Definition: cmbatt.h:65
#define CMBATT_GENERIC_WARNING
Definition: cmbatt.h:37
#define ACPI_BATT_STAT_DISCHARG
Definition: cmbatt.h:63
NTSTATUS NTAPI CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BST_DATA BstData)
Definition: cmexec.c:450
#define ACPI_BATT_STAT_CHARGING
Definition: cmbatt.h:64
#define ACPI_BATT_NOTIFY_STATUS
Definition: cmbatt.h:60
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().

◆ CmBattIoctl()

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

Definition at line 380 of file cmbatt.c.

382{
383 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
385 PIO_STACK_LOCATION IoStackLocation;
387 PAGED_CODE();
388 if (CmBattDebug & 2) DbgPrint("CmBattIoctl\n");
389
390 /* Acquire the remove lock */
391 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
392 if (!NT_SUCCESS(Status))
393 {
394 /* It's too late, fail */
395 Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
398 }
399
400 /* There's nothing to do for an AC adapter */
401 if (DeviceExtension->FdoType == CmBattAcAdapter)
402 {
403 /* Pass it down, and release the remove lock */
405 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
406 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
407 return Status;
408 }
409
410 /* Send to class driver */
411 Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp);
413 {
414 /* Read IOCTL information from IRP stack */
415 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
416 IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
417 OutputBufferLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
418 InputBufferLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
419 if (CmBattDebug & 4)
420 DbgPrint("CmBattIoctl: Received Direct Access IOCTL %x\n", IoControlCode);
421
422 /* Handle internal IOCTLs */
423 switch (IoControlCode)
424 {
426
427 /* Data is 4 bytes long */
428 if (OutputBufferLength == sizeof(ULONG))
429 {
430 /* Query it */
431 Status = CmBattGetUniqueId(DeviceExtension->PdoDeviceObject,
432 Irp->AssociatedIrp.SystemBuffer);
433 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
434 }
435 else
436 {
437 /* Buffer size invalid */
439 }
440 break;
441
443
444 /* Data is 4 bytes long */
445 if (OutputBufferLength == sizeof(ULONG))
446 {
447 /* Query it */
448 Status = CmBattGetStaData(DeviceExtension->PdoDeviceObject,
449 Irp->AssociatedIrp.SystemBuffer);
450 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
451 }
452 else
453 {
454 /* Buffer size invalid */
456 }
457 break;
458
460
461 /* Data is 4 bytes long */
462 if (OutputBufferLength == sizeof(ULONG))
463 {
464 /* Do we have an AC adapter? */
465 if (AcAdapterPdo)
466 {
467 /* Query it */
469 Irp->AssociatedIrp.SystemBuffer);
470 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
471 }
472 else
473 {
474 /* No adapter, just a battery, so fail */
476 }
477 }
478 else
479 {
480 /* Buffer size invalid */
482 }
483 break;
484
486
487 /* Data is 4 bytes long */
488 if (InputBufferLength == sizeof(ULONG))
489 {
490 /* Query it */
491 Status = CmBattSetTripPpoint(DeviceExtension,
492 *(PULONG)Irp->AssociatedIrp.SystemBuffer);
493 Irp->IoStatus.Information = 0;
494 }
495 else
496 {
497 /* Buffer size invalid */
499 }
500 break;
501
503
504 /* Data is 1060 bytes long */
505 if (OutputBufferLength == sizeof(ACPI_BIF_DATA))
506 {
507 /* Query it */
508 Status = CmBattGetBifData(DeviceExtension,
509 Irp->AssociatedIrp.SystemBuffer);
510 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA);
511 }
512 else
513 {
514 /* Buffer size invalid */
516 }
517 break;
518
520
521 /* Data is 16 bytes long */
522 if (OutputBufferLength == sizeof(ACPI_BST_DATA))
523 {
524 /* Query it */
525 Status = CmBattGetBstData(DeviceExtension,
526 Irp->AssociatedIrp.SystemBuffer);
527 if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BST_DATA);
528 }
529 else
530 {
531 /* Buffer size invalid */
533 }
534 break;
535
536 default:
537
538 /* Unknown, let us pass it on to ACPI */
539 if (CmBattDebug & 0xC)
540 DbgPrint("CmBattIoctl: Unknown IOCTL %x\n", IoControlCode);
541 break;
542 }
543
544 /* Did someone pick it up? */
546 {
547 /* Complete the request */
548 Irp->IoStatus.Status = Status;
550 }
551 else
552 {
553 /* Still unsupported, try ACPI */
555 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
556 }
557 }
558
559 /* Release the remove lock and return status */
560 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
561 return Status;
562}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
BCLASSAPI NTSTATUS NTAPI BatteryClassIoctl(PVOID ClassData, PIRP Irp)
Definition: battc.c:189
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
NTSTATUS NTAPI CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BIF_DATA BifData)
Definition: cmexec.c:412
#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
Definition: cmbatt.h:29
@ CmBattAcAdapter
Definition: cmbatt.h:47
_In_ PIRP Irp
Definition: csq.h:116
#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
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:809
CMBATT_EXTENSION_TYPE FdoType
Definition: cmbatt.h:104
PDEVICE_OBJECT PdoDeviceObject
Definition: cmbatt.h:107
PDEVICE_OBJECT AttachedDevice
Definition: cmbatt.h:108
IO_REMOVE_LOCK RemoveLock
Definition: cmbatt.h:115
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 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(PVOID ClassData)
Definition: battc.c:79
#define ACPI_BUS_CHECK
Definition: cmbatt.h:51
#define CMBATT_ACPI_ASSERT
Definition: cmbatt.h:43
#define ACPI_BATT_NOTIFY_INFO
Definition: cmbatt.h:61
#define CMBATT_AR_INSERT
Definition: cmbatt.h:99
#define CMBATT_AR_REMOVE
Definition: cmbatt.h:100
#define ACPI_DEVICE_CHECK
Definition: cmbatt.h:52
#define CMBATT_PNP_INFO
Definition: cmbatt.h:40
#define CMBATT_AR_NOTIFY
Definition: cmbatt.h:98
@ CmBattBattery
Definition: cmbatt.h:48
#define TRUE
Definition: types.h:120
@ 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 317 of file cmbatt.c.

319{
321 PIO_STACK_LOCATION IoStackLocation;
322 UCHAR Major;
323 ULONG Count;
324 PCMBATT_DEVICE_EXTENSION DeviceExtension;
325 PAGED_CODE();
326 if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattOpenClose\n");
327
328 /* Grab the device extension and lock it */
329 DeviceExtension = DeviceObject->DeviceExtension;
330 ExAcquireFastMutex(&DeviceExtension->FastMutex);
331
332 /* Check if someone is trying to open a device that doesn't exist yet */
333 Count = DeviceExtension->HandleCount;
334 if (Count == 0xFFFFFFFF)
335 {
336 /* Fail the request */
339 {
340 DbgPrint("CmBattOpenClose: Failed (UID = %x)(device being removed).\n",
341 DeviceExtension->Tag);
342 }
343 goto Complete;
344 }
345
346 /* Check if this is an open or close */
347 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
348 Major = IoStackLocation->MajorFunction;
349 if (Major == IRP_MJ_CREATE)
350 {
351 /* Increment the open count */
352 DeviceExtension->HandleCount = Count + 1;
354 {
355 DbgPrint("CmBattOpenClose: Open (DeviceNumber = %x)(count = %x).\n",
356 DeviceExtension->DeviceId, Count + 1);
357 }
358 }
359 else if (Major == IRP_MJ_CLOSE)
360 {
361 /* Decrement the open count */
362 DeviceExtension->HandleCount = Count - 1;
364 {
365 DbgPrint("CmBattOpenClose: Close (DeviceNumber = %x)(count = %x).\n",
366 DeviceExtension->DeviceId, Count + 1);
367 }
368 }
369
371 /* Release lock and complete request */
372 ExReleaseFastMutex(&DeviceExtension->FastMutex);
373 Irp->IoStatus.Status = Status;
375 return Status;
376}
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:109
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}
unsigned char BOOLEAN
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 1031 of file cmbatt.c.

1038{
1040 PVOID QueryData = NULL;
1041 ULONG QueryLength = 0;
1042 ULONG RemainingTime = 0;
1043 ANSI_STRING TempString;
1044 UNICODE_STRING TempString2;
1045 WCHAR InfoBuffer[256];
1046 WCHAR TempBuffer[256];
1047 UNICODE_STRING InfoString;
1048 ULONG RemainingCapacity;
1049 BATTERY_REPORTING_SCALE BatteryReportingScale[2];
1050 LONG Rate;
1051 PAGED_CODE();
1053 DbgPrint("CmBattQueryInformation - Tag (%d) Device %d, Informationlevel %d\n",
1054 Tag,
1055 FdoExtension->DeviceId,
1056 InfoLevel);
1057
1058 /* Check ACPI Data */
1060 if (!NT_SUCCESS(Status)) return Status;
1061
1062 /* Check what caller wants */
1063 switch (InfoLevel)
1064 {
1065 case BatteryInformation:
1066 /* Just return our static information */
1067 QueryData = &FdoExtension->BatteryInformation;
1068 QueryLength = sizeof(BATTERY_INFORMATION);
1069 break;
1070
1072
1073 /* Return our static information, we have two scales */
1074 BatteryReportingScale[0].Granularity = FdoExtension->BatteryCapacityGranularity1;
1075 BatteryReportingScale[0].Capacity = FdoExtension->BatteryInformation.DefaultAlert1;
1076 BatteryReportingScale[1].Granularity = FdoExtension->BatteryCapacityGranularity2;
1077 BatteryReportingScale[1].Capacity = FdoExtension->BatteryInformation.DesignedCapacity;
1078 QueryData = BatteryReportingScale;
1079 QueryLength = sizeof(BATTERY_REPORTING_SCALE) * 2;
1080 break;
1081
1083
1084 /* Check if it's been more than 2 1/2 minutes since the last change */
1085 if ((KeQueryInterruptTime() - 150000000) > (FdoExtension->InterruptTime))
1086 {
1087 /* Get new battery status */
1089
1090 /* If the caller didn't specify a rate, use our static one */
1091 Rate = AtRate;
1092 if (!Rate) Rate = FdoExtension->Rate;
1093
1094 /* If we don't have a valid negative rate, use unknown value */
1095 if (Rate >= 0) Rate = BATTERY_UNKNOWN_RATE;
1096
1097 /* Grab the remaining capacity */
1098 RemainingCapacity = FdoExtension->RemainingCapacity;
1099
1100 /* See if we don't know one or the other */
1101 if ((Rate == BATTERY_UNKNOWN_RATE) ||
1102 (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY))
1103 {
1104 /* If the battery is discharging, we can't give out a time */
1105 if ((FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG) &&
1107 DbgPrint("CmBattQueryInformation: Can't calculate EstimatedTime.\n");
1108
1109 /* Check if we don't have a rate and capacity is going down */
1110 if ((FdoExtension->Rate == BATTERY_UNKNOWN_RATE) &&
1111 (FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG))
1112 {
1113 /* We have to fail, since we lack data */
1116 DbgPrint("---------------------- PresentRate = BATTERY_UNKNOWN_RATE\n");
1117 }
1118
1119 /* If we don't have capacity, the rate is useless */
1120 if (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)
1121 {
1122 /* We have to fail the request */
1125 DbgPrint("---------------------- RemainingCapacity = BATTERY_UNKNOWN_CAPACITY\n");
1126 }
1127 }
1128 else
1129 {
1130 /* We have data, but is it valid? */
1131 if (RemainingCapacity > 0x123456)
1132 {
1133 /* The capacity seems bogus, so don't use it */
1135 DbgPrint("CmBattQueryInformation: Data Overflow in calculating Remaining Capacity.\n");
1136 }
1137 else
1138 {
1139 /* Compute the remaining time in seconds, based on rate */
1140 RemainingTime = (RemainingCapacity * 3600) / -Rate;
1141 }
1142 }
1143 }
1144
1145 /* Return the remaining time */
1146 QueryData = &RemainingTime;
1147 QueryLength = sizeof(ULONG);
1148 break;
1149
1150 case BatteryDeviceName:
1151
1152 /* Build the model number string */
1153 RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber);
1154
1155 /* Convert it to Unicode */
1156 InfoString.Buffer = InfoBuffer;
1157 InfoString.MaximumLength = sizeof(InfoBuffer);
1158 Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1159
1160 /* Return the unicode buffer */
1161 QueryData = InfoString.Buffer;
1162 QueryLength = InfoString.Length;
1163 break;
1164
1165 case BatteryTemperature:
1167
1168 /* We don't support these */
1170 break;
1171
1173
1174 /* Build the OEM info string */
1175 RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo);
1176
1177 /* Convert it to Unicode */
1178 InfoString.Buffer = InfoBuffer;
1179 InfoString.MaximumLength = sizeof(InfoBuffer);
1180 Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1181
1182 /* Return the unicode buffer */
1183 QueryData = InfoString.Buffer;
1184 QueryLength = InfoString.Length;
1185 break;
1186
1187 case BatteryUniqueID:
1188
1189 /* Build the serial number string */
1190 RtlInitAnsiString(&TempString, FdoExtension->BifData.SerialNumber);
1191
1192 /* Convert it to Unicode */
1193 InfoString.Buffer = InfoBuffer;
1194 InfoString.MaximumLength = sizeof(InfoBuffer);
1195 RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1196
1197 /* Setup a temporary string for concatenation */
1198 TempString2.Buffer = TempBuffer;
1199 TempString2.MaximumLength = sizeof(TempBuffer);
1200
1201 /* Check if there's an OEM string */
1202 if (FdoExtension->BifData.OemInfo[0])
1203 {
1204 /* Build the OEM info string */
1205 RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo);
1206
1207 /* Convert it to Unicode and append it */
1208 RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1209 RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1210 }
1211
1212 /* Build the model number string */
1213 RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber);
1214
1215 /* Convert it to Unicode and append it */
1216 RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1217 RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1218
1219 /* Return the final appended string */
1220 QueryData = InfoString.Buffer;
1221 QueryLength = InfoString.Length;
1222 break;
1223
1224 default:
1225
1226 /* Everything else is unknown */
1228 break;
1229 }
1230
1231 /* Return the required length and check if the caller supplied enough */
1232 *ReturnedLength = QueryLength;
1233 if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
1234
1235 /* Copy the data if there's enough space and it exists */
1236 if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength);
1237
1238 /* Return function result */
1239 return Status;
1240}
_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
Definition: bufpool.h:45
NTSTATUS NTAPI CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag)
Definition: cmbatt.c:813
#define NULL
Definition: types.h:112
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 1244 of file cmbatt.c.

1247{
1249 PAGED_CODE();
1251 DbgPrint("CmBattQueryStatus - Tag (%d) Device %x\n", Tag, DeviceExtension->DeviceId);
1252
1253 /* Query ACPI information */
1254 Status = CmBattGetBatteryStatus(DeviceExtension, Tag);
1255 if (NT_SUCCESS(Status))
1256 {
1257 BatteryStatus->PowerState = DeviceExtension->State;
1258 BatteryStatus->Capacity = DeviceExtension->RemainingCapacity;
1259 BatteryStatus->Voltage = DeviceExtension->PresentVoltage;
1260 BatteryStatus->Rate = DeviceExtension->Rate;
1261 }
1262
1263 /* Return status */
1265 DbgPrint("CmBattQueryStatus: Returning [%#08lx][%#08lx][%#08lx][%#08lx]\n",
1270 return Status;
1271}
_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 566 of file cmbatt.c.

568{
569 PDEVICE_OBJECT PdoDevice;
570 ULONG StaData;
571 ULONG NewTag;
573 PAGED_CODE();
575 DbgPrint("CmBattQueryTag - Tag (%d), Battery %x, Device %d\n",
576 *Tag, DeviceExtension, DeviceExtension->DeviceId);
577
578 /* Get PDO and clear notification flag */
579 PdoDevice = DeviceExtension->PdoDeviceObject;
580 DeviceExtension->NotifySent = 0;
581
582 /* Get _STA from PDO (we need the machine status, not the battery status) */
583 Status = CmBattGetStaData(PdoDevice, &StaData);
584 if (NT_SUCCESS(Status))
585 {
586 /* Is a battery present? */
587 if (StaData & ACPI_STA_BATTERY_PRESENT)
588 {
589 /* Do we not have a tag yet? */
590 if (!DeviceExtension->Tag)
591 {
592 /* Set the new tag value, reset tags if we reached the maximum */
593 NewTag = DeviceExtension->TagData;
594 if (DeviceExtension->TagData++ == 0xFFFFFFFF) NewTag = 1;
595 DeviceExtension->Tag = NewTag;
597 DbgPrint("CmBattQueryTag - New Tag: (%d)\n", DeviceExtension->Tag);
598
599 /* Reset trip point data */
600 DeviceExtension->TripPointOld = 0;
601 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
602
603 /* Clear AR lock and set new interrupt time */
604 InterlockedExchange(&DeviceExtension->ArLockValue, 0);
605 DeviceExtension->InterruptTime = KeQueryInterruptTime();
606 }
607 }
608 else
609 {
610 /* No battery, so no tag */
611 DeviceExtension->Tag = 0;
613 }
614 }
615
616 /* Return the tag and status result */
617 *Tag = DeviceExtension->Tag;
619 DbgPrint("CmBattQueryTag: Returning Tag: 0x%x, status 0x%x\n", *Tag, Status);
620 return Status;
621}
#define ACPI_STA_BATTERY_PRESENT
Definition: actypes.h:1344

Referenced by CmBattAddBattery().

◆ CmBattSetStatusNotify()

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

Definition at line 666 of file cmbatt.c.

669{
671 ACPI_BST_DATA BstData;
672 ULONG Capacity, NewTripPoint, TripPoint, DesignVoltage;
673 BOOLEAN Charging;
674 PAGED_CODE();
676 DbgPrint("CmBattSetStatusNotify: Tag (%d) Target(0x%x)\n",
678
679 /* Update any ACPI evaluations */
680 Status = CmBattVerifyStaticInfo(DeviceExtension, BatteryTag);
681 if (!NT_SUCCESS(Status)) return Status;
682
683 /* Trip point not supported, fail */
684 if (!DeviceExtension->TripPointSet) return STATUS_OBJECT_NAME_NOT_FOUND;
685
686 /* Are both capacities known? */
689 {
690 /* We can't set trip points without these */
692 DbgPrint("CmBattSetStatusNotify: Failing request because of BATTERY_UNKNOWN_CAPACITY.\n");
694 }
695
696 /* Is the battery charging? */
697 Charging = DeviceExtension->BstData.State & ACPI_BATT_STAT_CHARGING;
698 if (Charging)
699 {
700 /* Then the trip point is when we hit the cap */
701 Capacity = BatteryNotify->HighCapacity;
702 NewTripPoint = BatteryNotify->HighCapacity;
703 }
704 else
705 {
706 /* Otherwise it's when we discharge to the bottom */
707 Capacity = BatteryNotify->LowCapacity;
708 NewTripPoint = BatteryNotify->LowCapacity;
709 }
710
711 /* Do we have data in Amps or Watts? */
712 if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
713 {
714 /* We need the voltage to do the conversion */
715 DesignVoltage = DeviceExtension->BifData.DesignVoltage;
716 if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage))
717 {
718 /* Convert from mAh into Ah */
719 TripPoint = 1000 * NewTripPoint;
720 if (Charging)
721 {
722 /* Scale the high trip point */
723 NewTripPoint = (TripPoint + 500) / DesignVoltage + ((TripPoint + 500) % DesignVoltage != 0);
724 }
725 else
726 {
727 /* Scale the low trip point */
728 NewTripPoint = (TripPoint - 500) / DesignVoltage - ((TripPoint - 500) % DesignVoltage == 0);
729 }
730 }
731 else
732 {
733 /* Without knowing the voltage, Amps are not enough data on consumption */
736 DbgPrint("CmBattSetStatusNotify: Can't calculate BTP, DesignVoltage = 0x%08x\n",
737 DesignVoltage);
738 }
739 }
740 else if (Charging)
741 {
742 /* Make it trip just one past the charge cap */
743 ++NewTripPoint;
744 }
745 else if (NewTripPoint > 0)
746 {
747 /* Make it trip just one below the drain cap */
748 --NewTripPoint;
749 }
750
751 /* Do we actually have a new trip point? */
752 if (NewTripPoint == DeviceExtension->TripPointValue)
753 {
754 /* No, so there is no work to be done */
756 DbgPrint("CmBattSetStatusNotify: Keeping original setting: %X\n", DeviceExtension->TripPointValue);
757 return STATUS_SUCCESS;
758 }
759
760 /* Set the trip point with ACPI and check for success */
761 DeviceExtension->TripPointValue = NewTripPoint;
762 Status = CmBattSetTripPpoint(DeviceExtension, NewTripPoint);
763 if (!(NewTripPoint) && (Capacity)) Status = STATUS_NOT_SUPPORTED;
764 if (!NT_SUCCESS(Status))
765 {
766 /* We failed to set the trip point, or there wasn't one settable */
767 DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
769 DbgPrint("CmBattSetStatusNotify: SetTripPoint failed - %x\n", Status);
770 return Status;
771 }
772
773 /* Read the new BST data to see the latest state */
774 Status = CmBattGetBstData(DeviceExtension, &BstData);
775 if (!NT_SUCCESS(Status))
776 {
777 /* We'll return failure to the caller */
779 DbgPrint("CmBattSetStatusNotify: GetBstData - %x\n", Status);
780 }
781 else if ((Charging) && (BstData.RemainingCapacity >= NewTripPoint))
782 {
783 /* We are charging and our capacity is past the trip point, so trip now */
785 DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
786 NewTripPoint, BstData.RemainingCapacity);
788 }
789 else if ((BstData.RemainingCapacity) && (Capacity))
790 {
791 /* We are discharging, and our capacity is below the trip point, trip now */
793 DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
794 NewTripPoint, BstData.RemainingCapacity);
796 }
797
798 /* All should've went well if we got here, unless BST failed... return! */
800 DbgPrint("CmBattSetStatusNotify: Want %X CurrentCap %X\n",
801 Capacity, DeviceExtension->RemainingCapacity);
803 DbgPrint("CmBattSetStatusNotify: Set to: [%#08lx][%#08lx][%#08lx] Status %lx\n",
807 Status);
808 return Status;
809}
_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:79
ULONG RemainingCapacity
Definition: cmbatt.h:74
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().

◆ CmBattVerifyStaticInfo()

NTSTATUS NTAPI CmBattVerifyStaticInfo ( PCMBATT_DEVICE_EXTENSION  DeviceExtension,
ULONG  BatteryTag 
)

Definition at line 278 of file cmbatt.c.

280{
281 ACPI_BIF_DATA BifData;
282 PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation;
284
285 Status = CmBattGetBifData(DeviceExtension, &BifData);
286 if (NT_SUCCESS(Status))
287 {
288 RtlZeroMemory(Info, sizeof(*Info));
289 Info->Capabilities = BATTERY_SYSTEM_BATTERY;
290 Info->Technology = BifData.BatteryTechnology;
291 RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4);
292 // FIXME: take from _BIX method: Info->CycleCount
293 DeviceExtension->BifData = BifData;
294
295 if (BifData.PowerUnit == 1)
296 {
297 DPRINT1("FIXME: need to convert mAh into mWh\n");
298 Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
299 Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
300 Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
301 Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
302 }
303 else
304 {
305 Info->DesignedCapacity = BifData.DesignCapacity;
306 Info->FullChargedCapacity = BifData.LastFullCapacity;
307 Info->DefaultAlert1 = BifData.DesignCapacityLow;
308 Info->DefaultAlert2 = BifData.DesignCapacityWarning;
309 }
310 }
311
312 return Status;
313}
#define DPRINT1
Definition: precomp.h:8
#define BATTERY_SYSTEM_BATTERY
Definition: batclass.h:62
CHAR BatteryType[256]
Definition: cmbatt.h:94
ULONG DesignCapacityLow
Definition: cmbatt.h:89
ULONG LastFullCapacity
Definition: cmbatt.h:85
ULONG DesignCapacity
Definition: cmbatt.h:84
ULONG BatteryTechnology
Definition: cmbatt.h:86
ULONG DesignCapacityWarning
Definition: cmbatt.h:88
ULONG PowerUnit
Definition: cmbatt.h:83
BATTERY_INFORMATION BatteryInformation
Definition: cmbatt.h:134
ACPI_BIF_DATA BifData
Definition: cmbatt.h:128
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_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 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}
#define FALSE
Definition: types.h:117
BOOLEAN DelayNotification
Definition: cmbatt.h:119
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 1275 of file cmbatt.c.

1277{
1281 UNICODE_STRING CallbackName;
1282
1283 /* Allocate registry path */
1288 'MtaB');
1290 {
1291 /* Fail if we're out of memory this early */
1293 DbgPrint("CmBatt: Couldn't allocate pool for registry path.");
1295 }
1296
1297 /* Buffer allocated, copy the string */
1300 DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%wZ\"\n",
1302 RegistryPath);
1303
1304 /* Setup the major dispatchers */
1305 DriverObject->MajorFunction[IRP_MJ_CREATE] = CmBattOpenClose;
1306 DriverObject->MajorFunction[IRP_MJ_CLOSE] = CmBattOpenClose;
1309 DriverObject->MajorFunction[IRP_MJ_PNP] = CmBattPnpDispatch;
1311
1312 /* And the unload routine */
1313 DriverObject->DriverUnload = CmBattUnload;
1314
1315 /* And the add device routine */
1316 DriverExtension = DriverObject->DriverExtension;
1317 DriverExtension->AddDevice = CmBattAddDevice;
1318
1319 /* Create a power callback */
1320 RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
1322 &CallbackName,
1324 NULL,
1325 NULL);
1327 if (!NT_SUCCESS(Status))
1328 {
1329 /* No callback, fail */
1332 DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status);
1333 }
1334 else
1335 {
1336 /* Register the power callback now */
1339 DriverObject);
1341 {
1342 /* Last thing: setup our DPC and timer for battery wake */
1345 }
1346 else
1347 {
1350 DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n");
1351 }
1352
1353 /* All good */
1355 }
1356
1357 /* Return failure or success */
1358 return Status;
1359}
#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:317
NTSTATUS NTAPI CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbatt.c:380
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 PagedPool
Definition: env_spec_w32.h:308
#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
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_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().