ReactOS  0.4.13-dev-464-g6b95727
cmbatt.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS ACPI-Compliant Control Method Battery
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: boot/drivers/bus/acpi/cmbatt/cmbatt.c
5  * PURPOSE: Main Initialization Code and IRP Handling
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "cmbatt.h"
12 
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
25 
26 /* FUNCTIONS ******************************************************************/
27 
28 VOID
29 NTAPI
31  IN ULONG Action,
32  IN ULONG Value)
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");
69  }
70  }
71 }
72 
73 VOID
74 NTAPI
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 }
139 
140 VOID
141 NTAPI
143  IN ULONG NotifyValue)
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 */
178  case ACPI_DEVICE_CHECK:
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;
234  DeviceObject;
235  DeviceObject = DeviceObject->NextDevice)
236  {
237  /* Is this a battery? */
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 }
251 
252 VOID
253 NTAPI
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 */
271  {
272  DbgPrint("Unload called before all devices removed.\n");
273  }
274 }
275 
276 NTSTATUS
277 NTAPI
280 {
282  return STATUS_NOT_IMPLEMENTED;
283 }
284 
285 NTSTATUS
286 NTAPI
288  IN PIRP Irp)
289 {
291  PIO_STACK_LOCATION IoStackLocation;
292  UCHAR Major;
293  ULONG Count;
294  PCMBATT_DEVICE_EXTENSION DeviceExtension;
295  PAGED_CODE();
296  if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattOpenClose\n");
297 
298  /* Grab the device extension and lock it */
299  DeviceExtension = DeviceObject->DeviceExtension;
300  ExAcquireFastMutex(&DeviceExtension->FastMutex);
301 
302  /* Check if someone is trying to open a device that doesn't exist yet */
303  Count = DeviceExtension->HandleCount;
304  if (Count == 0xFFFFFFFF)
305  {
306  /* Fail the request */
309  {
310  DbgPrint("CmBattOpenClose: Failed (UID = %x)(device being removed).\n",
311  DeviceExtension->Tag);
312  }
313  goto Complete;
314  }
315 
316  /* Check if this is an open or close */
317  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
318  Major = IoStackLocation->MajorFunction;
319  if (Major == IRP_MJ_CREATE)
320  {
321  /* Increment the open count */
322  DeviceExtension->HandleCount = Count + 1;
324  {
325  DbgPrint("CmBattOpenClose: Open (DeviceNumber = %x)(count = %x).\n",
326  DeviceExtension->DeviceId, Count + 1);
327  }
328  }
329  else if (Major == IRP_MJ_CLOSE)
330  {
331  /* Decrement the open count */
332  DeviceExtension->HandleCount = Count - 1;
334  {
335  DbgPrint("CmBattOpenClose: Close (DeviceNumber = %x)(count = %x).\n",
336  DeviceExtension->DeviceId, Count + 1);
337  }
338  }
339 
340 Complete:
341  /* Release lock and complete request */
342  ExReleaseFastMutex(&DeviceExtension->FastMutex);
343  Irp->IoStatus.Status = Status;
345  return Status;
346 }
347 
348 NTSTATUS
349 NTAPI
351  IN PIRP Irp)
352 {
355  PIO_STACK_LOCATION IoStackLocation;
357  PAGED_CODE();
358  if (CmBattDebug & 2) DbgPrint("CmBattIoctl\n");
359 
360  /* Acquire the remove lock */
361  Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, 0);
362  if (!NT_SUCCESS(Status))
363  {
364  /* It's too late, fail */
365  Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
367  return STATUS_DEVICE_REMOVED;
368  }
369 
370  /* There's nothing to do for an AC adapter */
371  if (DeviceExtension->FdoType == CmBattAcAdapter)
372  {
373  /* Pass it down, and release the remove lock */
375  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
376  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
377  return Status;
378  }
379 
380  /* Send to class driver */
381  Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp);
383  {
384  /* Read IOCTL information from IRP stack */
385  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
386  IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
387  OutputBufferLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
388  InputBufferLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
389  if (CmBattDebug & 4)
390  DbgPrint("CmBattIoctl: Received Direct Access IOCTL %x\n", IoControlCode);
391 
392  /* Handle internal IOCTLs */
393  switch (IoControlCode)
394  {
396 
397  /* Data is 4 bytes long */
398  if (OutputBufferLength == sizeof(ULONG))
399  {
400  /* Query it */
401  Status = CmBattGetUniqueId(DeviceExtension->PdoDeviceObject,
402  Irp->AssociatedIrp.SystemBuffer);
403  if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
404  }
405  else
406  {
407  /* Buffer size invalid */
409  }
410  break;
411 
413 
414  /* Data is 4 bytes long */
415  if (OutputBufferLength == sizeof(ULONG))
416  {
417  /* Query it */
418  Status = CmBattGetStaData(DeviceExtension->PdoDeviceObject,
419  Irp->AssociatedIrp.SystemBuffer);
420  if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
421  }
422  else
423  {
424  /* Buffer size invalid */
426  }
427  break;
428 
430 
431  /* Data is 4 bytes long */
432  if (OutputBufferLength == sizeof(ULONG))
433  {
434  /* Do we have an AC adapter? */
435  if (AcAdapterPdo)
436  {
437  /* Query it */
439  Irp->AssociatedIrp.SystemBuffer);
440  if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ULONG);
441  }
442  else
443  {
444  /* No adapter, just a battery, so fail */
446  }
447  }
448  else
449  {
450  /* Buffer size invalid */
452  }
453  break;
454 
456 
457  /* Data is 4 bytes long */
458  if (InputBufferLength == sizeof(ULONG))
459  {
460  /* Query it */
461  Status = CmBattSetTripPpoint(DeviceExtension,
462  *(PULONG)Irp->AssociatedIrp.SystemBuffer);
463  Irp->IoStatus.Information = 0;
464  }
465  else
466  {
467  /* Buffer size invalid */
469  }
470  break;
471 
473 
474  /* Data is 1060 bytes long */
475  if (OutputBufferLength == sizeof(ACPI_BIF_DATA))
476  {
477  /* Query it */
478  Status = CmBattGetBifData(DeviceExtension,
479  Irp->AssociatedIrp.SystemBuffer);
480  if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA);
481  }
482  else
483  {
484  /* Buffer size invalid */
486  }
487  break;
488 
490 
491  /* Data is 16 bytes long */
492  if (OutputBufferLength == sizeof(ACPI_BST_DATA))
493  {
494  /* Query it */
495  Status = CmBattGetBstData(DeviceExtension,
496  Irp->AssociatedIrp.SystemBuffer);
497  if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BST_DATA);
498  }
499  else
500  {
501  /* Buffer size invalid */
503  }
504  break;
505 
506  default:
507 
508  /* Unknown, let us pass it on to ACPI */
509  if (CmBattDebug & 0xC)
510  DbgPrint("CmBattIoctl: Unknown IOCTL %x\n", IoControlCode);
511  break;
512  }
513 
514  /* Did someone pick it up? */
516  {
517  /* Complete the request */
518  Irp->IoStatus.Status = Status;
520  }
521  else
522  {
523  /* Still unsupported, try ACPI */
525  Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
526  }
527  }
528 
529  /* Release the remove lock and return status */
530  IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
531  return Status;
532 }
533 
534 NTSTATUS
535 NTAPI
537  OUT PULONG Tag)
538 {
539  PDEVICE_OBJECT PdoDevice;
540  ULONG StaData;
541  ULONG NewTag;
543  PAGED_CODE();
545  DbgPrint("CmBattQueryTag - Tag (%d), Battery %x, Device %d\n",
546  *Tag, DeviceExtension, DeviceExtension->DeviceId);
547 
548  /* Get PDO and clear notification flag */
549  PdoDevice = DeviceExtension->PdoDeviceObject;
550  DeviceExtension->NotifySent = 0;
551 
552  /* Get _STA from PDO (we need the machine status, not the battery status) */
553  Status = CmBattGetStaData(PdoDevice, &StaData);
554  if (NT_SUCCESS(Status))
555  {
556  /* Is a battery present? */
557  if (StaData & ACPI_STA_BATTERY_PRESENT)
558  {
559  /* Do we not have a tag yet? */
560  if (!DeviceExtension->Tag)
561  {
562  /* Set the new tag value, reset tags if we reached the maximum */
563  NewTag = DeviceExtension->TagData;
564  if (DeviceExtension->TagData++ == 0xFFFFFFFF) NewTag = 1;
565  DeviceExtension->Tag = NewTag;
567  DbgPrint("CmBattQueryTag - New Tag: (%d)\n", DeviceExtension->Tag);
568 
569  /* Reset trip point data */
570  DeviceExtension->TripPointOld = 0;
571  DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
572 
573  /* Clear AR lock and set new interrupt time */
574  InterlockedExchange(&DeviceExtension->ArLockValue, 0);
575  DeviceExtension->InterruptTime = KeQueryInterruptTime();
576  }
577  }
578  else
579  {
580  /* No battery, so no tag */
581  DeviceExtension->Tag = 0;
583  }
584  }
585 
586  /* Return the tag and status result */
587  *Tag = DeviceExtension->Tag;
589  DbgPrint("CmBattQueryTag: Returning Tag: 0x%x, status 0x%x\n", *Tag, Status);
590  return Status;
591 }
592 
593 NTSTATUS
594 NTAPI
596 {
598  PAGED_CODE();
599  if (CmBattDebug & 0xA) DbgPrint("CmBattDisableStatusNotify\n");
600 
601  /* Do we have a trip point */
602  if (DeviceExtension->TripPointSet)
603  {
604  /* Is there a current value set? */
605  if (DeviceExtension->TripPointValue)
606  {
607  /* Reset it back to 0 */
608  DeviceExtension->TripPointValue = 0;
609  Status = CmBattSetTripPpoint(DeviceExtension, 0);
610  if (!NT_SUCCESS(Status))
611  {
612  /* If it failed, set unknown/invalid value */
613  DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
614  if (CmBattDebug & 8)
615  DbgPrint("CmBattDisableStatusNotify: SetTripPoint failed - %x\n", Status);
616  }
617  }
618  else
619  {
620  /* No trip point set, so this is a successful no-op */
622  }
623  }
624  else
625  {
626  /* Nothing we can do */
628  }
629 
630  /* Return status */
631  return Status;
632 }
633 
634 NTSTATUS
635 NTAPI
639 {
641  ACPI_BST_DATA BstData;
642  ULONG Capacity, NewTripPoint, TripPoint, DesignVoltage;
643  BOOLEAN Charging;
644  PAGED_CODE();
646  DbgPrint("CmBattSetStatusNotify: Tag (%d) Target(0x%x)\n",
648 
649  /* Update any ACPI evaluations */
650  Status = CmBattVerifyStaticInfo(DeviceExtension, BatteryTag);
651  if (!NT_SUCCESS(Status)) return Status;
652 
653  /* Trip point not supported, fail */
654  if (!DeviceExtension->TripPointSet) return STATUS_OBJECT_NAME_NOT_FOUND;
655 
656  /* Are both capacities known? */
659  {
660  /* We can't set trip points without these */
662  DbgPrint("CmBattSetStatusNotify: Failing request because of BATTERY_UNKNOWN_CAPACITY.\n");
663  return STATUS_NOT_SUPPORTED;
664  }
665 
666  /* Is the battery charging? */
667  Charging = DeviceExtension->BstData.State & ACPI_BATT_STAT_CHARGING;
668  if (Charging)
669  {
670  /* Then the trip point is when we hit the cap */
671  Capacity = BatteryNotify->HighCapacity;
672  NewTripPoint = BatteryNotify->HighCapacity;
673  }
674  else
675  {
676  /* Otherwise it's when we discharge to the bottom */
677  Capacity = BatteryNotify->LowCapacity;
678  NewTripPoint = BatteryNotify->LowCapacity;
679  }
680 
681  /* Do we have data in Amps or Watts? */
682  if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
683  {
684  /* We need the voltage to do the conversion */
685  DesignVoltage = DeviceExtension->BifData.DesignVoltage;
686  if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage))
687  {
688  /* Convert from mAh into Ah */
689  TripPoint = 1000 * NewTripPoint;
690  if (Charging)
691  {
692  /* Scale the high trip point */
693  NewTripPoint = (TripPoint + 500) / DesignVoltage + ((TripPoint + 500) % DesignVoltage != 0);
694  }
695  else
696  {
697  /* Scale the low trip point */
698  NewTripPoint = (TripPoint - 500) / DesignVoltage - ((TripPoint - 500) % DesignVoltage == 0);
699  }
700  }
701  else
702  {
703  /* Without knowing the voltage, Amps are not enough data on consumption */
706  DbgPrint("CmBattSetStatusNotify: Can't calculate BTP, DesignVoltage = 0x%08x\n",
707  DesignVoltage);
708  }
709  }
710  else if (Charging)
711  {
712  /* Make it trip just one past the charge cap */
713  ++NewTripPoint;
714  }
715  else if (NewTripPoint > 0)
716  {
717  /* Make it trip just one below the drain cap */
718  --NewTripPoint;
719  }
720 
721  /* Do we actually have a new trip point? */
722  if (NewTripPoint == DeviceExtension->TripPointValue)
723  {
724  /* No, so there is no work to be done */
726  DbgPrint("CmBattSetStatusNotify: Keeping original setting: %X\n", DeviceExtension->TripPointValue);
727  return STATUS_SUCCESS;
728  }
729 
730  /* Set the trip point with ACPI and check for success */
731  DeviceExtension->TripPointValue = NewTripPoint;
732  Status = CmBattSetTripPpoint(DeviceExtension, NewTripPoint);
733  if (!(NewTripPoint) && (Capacity)) Status = STATUS_NOT_SUPPORTED;
734  if (!NT_SUCCESS(Status))
735  {
736  /* We failed to set the trip point, or there wasn't one settable */
737  DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
739  DbgPrint("CmBattSetStatusNotify: SetTripPoint failed - %x\n", Status);
740  return Status;
741  }
742 
743  /* Read the new BST data to see the latest state */
744  Status = CmBattGetBstData(DeviceExtension, &BstData);
745  if (!NT_SUCCESS(Status))
746  {
747  /* We'll return failure to the caller */
749  DbgPrint("CmBattSetStatusNotify: GetBstData - %x\n", Status);
750  }
751  else if ((Charging) && (BstData.RemainingCapacity >= NewTripPoint))
752  {
753  /* We are charging and our capacity is past the trip point, so trip now */
755  DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
756  NewTripPoint, BstData.RemainingCapacity);
758  }
759  else if ((BstData.RemainingCapacity) && (Capacity))
760  {
761  /* We are discharging, and our capacity is below the trip point, trip now */
763  DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
764  NewTripPoint, BstData.RemainingCapacity);
765  CmBattNotifyHandler(DeviceExtension, ACPI_BATT_NOTIFY_STATUS);
766  }
767 
768  /* All should've went well if we got here, unless BST failed... return! */
770  DbgPrint("CmBattSetStatusNotify: Want %X CurrentCap %X\n",
771  Capacity, DeviceExtension->RemainingCapacity);
773  DbgPrint("CmBattSetStatusNotify: Set to: [%#08lx][%#08lx][%#08lx] Status %x\n",
777  return Status;
778 }
779 
780 NTSTATUS
781 NTAPI
783  IN ULONG Tag)
784 {
785  ULONG PsrData = 0;
787  ULONG BstState;
788  ULONG DesignVoltage, PresentRate, RemainingCapacity;
789  PAGED_CODE();
791  DbgPrint("CmBattGetBatteryStatus - CmBatt (%08x) Tag (%d)\n", DeviceExtension, Tag);
792 
793  /* Validate ACPI data */
794  Status = CmBattVerifyStaticInfo(DeviceExtension, Tag);
795  if (!NT_SUCCESS(Status)) return Status;
796 
797  /* Check for delayed status notifications */
798  if (DeviceExtension->DelayNotification)
799  {
800  /* Process them now and don't do any other work */
802  return Status;
803  }
804 
805  /* Get _BST from ACPI */
806  Status = CmBattGetBstData(DeviceExtension, &DeviceExtension->BstData);
807  if (!NT_SUCCESS(Status))
808  {
809  /* Fail */
810  InterlockedExchange(&DeviceExtension->ArLockValue, 0);
811  return Status;
812  }
813 
814  /* Clear current BST information */
815  DeviceExtension->State = 0;
816  DeviceExtension->RemainingCapacity = 0;
817  DeviceExtension->PresentVoltage = 0;
818  DeviceExtension->Rate = 0;
819 
820  /* Get battery state */
821  BstState = DeviceExtension->BstData.State;
822 
823  /* Is the battery both charging and discharging? */
824  if ((BstState & ACPI_BATT_STAT_DISCHARG) && (BstState & ACPI_BATT_STAT_CHARGING) &&
826  DbgPrint("************************ ACPI BIOS BUG ********************\n* "
827  "CmBattGetBatteryStatus: Invalid state: _BST method returned 0x%08x for Battery State.\n"
828  "* One battery cannot be charging and discharging at the same time.\n",
829  BstState);
830 
831  /* Is the battery discharging? */
832  if (BstState & ACPI_BATT_STAT_DISCHARG)
833  {
834  /* Set power state and check if it just started discharging now */
835  DeviceExtension->State |= BATTERY_DISCHARGING;
836  if (!(DeviceExtension->State & ACPI_BATT_STAT_DISCHARG))
837  {
838  /* Remember the time when the state changed */
839  DeviceExtension->InterruptTime = KeQueryInterruptTime();
840  }
841  }
842  else if (BstState & ACPI_BATT_STAT_CHARGING)
843  {
844  /* Battery is charging, update power state */
845  DeviceExtension->State |= (BATTERY_CHARGING | BATTERY_POWER_ON_LINE);
846  }
847 
848  /* Is the battery in a critical state? */
849  if (BstState & ACPI_BATT_STAT_CRITICAL) DeviceExtension->State |= BATTERY_CRITICAL;
850 
851  /* Read the voltage data */
852  DeviceExtension->PresentVoltage = DeviceExtension->BstData.PresentVoltage;
853 
854  /* Check if we have an A/C adapter */
855  if (AcAdapterPdo)
856  {
857  /* Query information on it */
858  CmBattGetPsrData(AcAdapterPdo, &PsrData);
859  }
860  else
861  {
862  /* Otherwise, check if the battery is charging */
863  if (BstState & ACPI_BATT_STAT_CHARGING)
864  {
865  /* Then we'll assume there's a charger */
866  PsrData = 1;
867  }
868  else
869  {
870  /* Assume no charger */
871  PsrData = 0;
872  }
873  }
874 
875  /* Is there a charger? */
876  if (PsrData)
877  {
878  /* Set the power state flag to reflect this */
879  DeviceExtension->State |= BATTERY_POWER_ON_LINE;
881  DbgPrint("CmBattGetBatteryStatus: AC adapter is connected\n");
882  }
884  {
885  DbgPrint("CmBattGetBatteryStatus: AC adapter is NOT connected\n");
886  }
887 
888  /* Get some data we'll need */
889  DesignVoltage = DeviceExtension->BifData.DesignVoltage;
890  PresentRate = DeviceExtension->BstData.PresentRate;
891  RemainingCapacity = DeviceExtension->BstData.RemainingCapacity;
892 
893  /* Check if we have battery data in Watts instead of Amps */
894  if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_WATTS)
895  {
896  /* Get the data from the BST */
897  DeviceExtension->RemainingCapacity = RemainingCapacity;
898  DeviceExtension->Rate = PresentRate;
899 
900  /* Check if the rate is invalid */
901  if (PresentRate > CM_MAX_VALUE)
902  {
903  /* Set an unknown rate and don't touch the old value */
904  DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
905  if ((PresentRate != CM_UNKNOWN_VALUE) && (CmBattDebug & CMBATT_ACPI_WARNING))
906  {
907  DbgPrint("CmBattGetBatteryStatus - Rate is greater than CM_MAX_VALUE\n");
908  DbgPrint("---------------------- PresentRate = 0x%08x\n", PresentRate);
909  }
910  }
911  }
912  else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage))
913  {
914  /* We have voltage data, what about capacity? */
915  if (RemainingCapacity == CM_UNKNOWN_VALUE)
916  {
917  /* Unable to calculate it */
918  DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
920  {
921  DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity \n");
922  DbgPrint("---------------------- RemainingCapacity = CM_UNKNOWN_VALUE\n");
923  }
924  }
925  else
926  {
927  /* Compute the capacity with the information we have */
928  DeviceExtension->RemainingCapacity = (DesignVoltage * RemainingCapacity + 500) / 1000;
929  }
930 
931  /* Check if we have a rate */
932  if (PresentRate != CM_UNKNOWN_VALUE)
933  {
934  /* Make sure the rate isn't too large */
935  if (PresentRate > (-500 / DesignVoltage))
936  {
937  /* It is, so set unknown state */
938  DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
940  {
941  DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
942  DbgPrint("---------------------- Overflow: PresentRate = 0x%08x\n", PresentRate);
943  }
944  }
945 
946  /* Compute the rate */
947  DeviceExtension->Rate = (PresentRate * DesignVoltage + 500) / 1000;
948  }
949  else
950  {
951  /* We don't have a rate, so set unknown value */
952  DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
954  {
955  DbgPrint("CmBattGetBatteryStatus - Can't calculate Rate \n");
956  DbgPrint("---------------------- Present Rate = CM_UNKNOWN_VALUE\n");
957  }
958  }
959  }
960  else
961  {
962  /* We have no rate, and no capacity, set unknown values */
963  DeviceExtension->Rate = BATTERY_UNKNOWN_RATE;
964  DeviceExtension->RemainingCapacity = BATTERY_UNKNOWN_CAPACITY;
966  {
967  DbgPrint("CmBattGetBatteryStatus - Can't calculate RemainingCapacity and Rate \n");
968  DbgPrint("---------------------- DesignVoltage = 0x%08x\n", DesignVoltage);
969  }
970  }
971 
972  /* Check if we have an unknown rate */
973  if (DeviceExtension->Rate == BATTERY_UNKNOWN_RATE)
974  {
975  /* The battery is discharging but we don't know by how much... this is bad! */
976  if ((BstState & ACPI_BATT_STAT_DISCHARG) &&
978  DbgPrint("CmBattGetBatteryStatus: battery rate is unknown when battery is not charging!\n");
979  }
980  else if (DeviceExtension->State & BATTERY_DISCHARGING)
981  {
982  /* The battery is discharging, so treat the rate as a negative rate */
983  DeviceExtension->Rate = -DeviceExtension->Rate;
984  }
985  else if (!(DeviceExtension->State & BATTERY_CHARGING) && (DeviceExtension->Rate))
986  {
987  /* We are not charging, not discharging, but have a rate? Ignore it! */
989  DbgPrint("CmBattGetBatteryStatus: battery is not charging or discharging, but rate = %x\n",
990  DeviceExtension->Rate);
991  DeviceExtension->Rate = 0;
992  }
993 
994  /* Done */
995  return STATUS_SUCCESS;
996 }
997 
998 NTSTATUS
999 NTAPI
1001  IN ULONG Tag,
1004  IN PVOID Buffer,
1007 {
1008  NTSTATUS Status;
1009  PVOID QueryData = NULL;
1010  ULONG QueryLength = 0;
1011  ULONG RemainingTime = 0;
1012  ANSI_STRING TempString;
1013  UNICODE_STRING TempString2;
1014  WCHAR InfoBuffer[256];
1015  WCHAR TempBuffer[256];
1016  UNICODE_STRING InfoString;
1017  ULONG RemainingCapacity;
1018  BATTERY_REPORTING_SCALE BatteryReportingScale[2];
1019  LONG Rate;
1020  PAGED_CODE();
1022  DbgPrint("CmBattQueryInformation - Tag (%d) Device %d, Informationlevel %d\n",
1023  Tag,
1024  FdoExtension->DeviceId,
1025  InfoLevel);
1026 
1027  /* Check ACPI Data */
1029  if (!NT_SUCCESS(Status)) return Status;
1030 
1031  /* Check what caller wants */
1032  switch (InfoLevel)
1033  {
1034  case BatteryInformation:
1035  /* Just return our static information */
1036  QueryData = &FdoExtension->BatteryInformation;
1037  QueryLength = sizeof(BATTERY_INFORMATION);
1038  break;
1039 
1041 
1042  /* Return our static information, we have two scales */
1043  BatteryReportingScale[0].Granularity = FdoExtension->BatteryCapacityGranularity1;
1044  BatteryReportingScale[0].Capacity = FdoExtension->BatteryInformation.DefaultAlert1;
1045  BatteryReportingScale[1].Granularity = FdoExtension->BatteryCapacityGranularity2;
1046  BatteryReportingScale[1].Capacity = FdoExtension->BatteryInformation.DesignedCapacity;
1047  QueryData = BatteryReportingScale;
1048  QueryLength = sizeof(BATTERY_REPORTING_SCALE) * 2;
1049  break;
1050 
1051  case BatteryEstimatedTime:
1052 
1053  /* Check if it's been more than 2 1/2 minutes since the last change */
1054  if ((KeQueryInterruptTime() - 150000000) > (FdoExtension->InterruptTime))
1055  {
1056  /* Get new battery status */
1058 
1059  /* If the caller didn't specify a rate, use our static one */
1060  Rate = AtRate;
1061  if (!Rate) Rate = FdoExtension->Rate;
1062 
1063  /* If we don't have a valid negative rate, use unknown value */
1064  if (Rate >= 0) Rate = BATTERY_UNKNOWN_RATE;
1065 
1066  /* Grab the remaining capacity */
1067  RemainingCapacity = FdoExtension->RemainingCapacity;
1068 
1069  /* See if we don't know one or the other */
1070  if ((Rate == BATTERY_UNKNOWN_RATE) ||
1071  (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY))
1072  {
1073  /* If the battery is discharging, we can't give out a time */
1074  if ((FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG) &&
1076  DbgPrint("CmBattQueryInformation: Can't calculate EstimatedTime.\n");
1077 
1078  /* Check if we don't have a rate and capacity is going down */
1079  if ((FdoExtension->Rate == BATTERY_UNKNOWN_RATE) &&
1080  (FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG))
1081  {
1082  /* We have to fail, since we lack data */
1085  DbgPrint("---------------------- PresentRate = BATTERY_UNKNOWN_RATE\n");
1086  }
1087 
1088  /* If we don't have capacity, the rate is useless */
1089  if (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)
1090  {
1091  /* We have to fail the request */
1094  DbgPrint("---------------------- RemainingCapacity = BATTERY_UNKNOWN_CAPACITY\n");
1095  }
1096  }
1097  else
1098  {
1099  /* We have data, but is it valid? */
1100  if (RemainingCapacity > 0x123456)
1101  {
1102  /* The capacity seems bogus, so don't use it */
1104  DbgPrint("CmBattQueryInformation: Data Overflow in calculating Remaining Capacity.\n");
1105  }
1106  else
1107  {
1108  /* Compute the remaining time in seconds, based on rate */
1109  RemainingTime = (RemainingCapacity * 3600) / -Rate;
1110  }
1111  }
1112  }
1113 
1114  /* Return the remaining time */
1115  QueryData = &RemainingTime;
1116  QueryLength = sizeof(ULONG);
1117  break;
1118 
1119  case BatteryDeviceName:
1120 
1121  /* Build the model number string */
1122  RtlInitAnsiString(&TempString, FdoExtension->ModelNumber);
1123 
1124  /* Convert it to Unicode */
1125  InfoString.Buffer = InfoBuffer;
1126  InfoString.MaximumLength = sizeof(InfoBuffer);
1127  Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1128 
1129  /* Return the unicode buffer */
1130  QueryData = InfoString.Buffer;
1131  QueryLength = InfoString.Length;
1132  break;
1133 
1134  case BatteryTemperature:
1136 
1137  /* We don't support these */
1139  break;
1140 
1142 
1143  /* Build the OEM info string */
1144  RtlInitAnsiString(&TempString, FdoExtension->OemInfo);
1145 
1146  /* Convert it to Unicode */
1147  InfoString.Buffer = InfoBuffer;
1148  InfoString.MaximumLength = sizeof(InfoBuffer);
1149  Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1150 
1151  /* Return the unicode buffer */
1152  QueryData = InfoString.Buffer;
1153  QueryLength = InfoString.Length;
1154  break;
1155 
1156  case BatteryUniqueID:
1157 
1158  /* Build the serial number string */
1159  RtlInitAnsiString(&TempString, FdoExtension->SerialNumber);
1160 
1161  /* Convert it to Unicode */
1162  InfoString.Buffer = InfoBuffer;
1163  InfoString.MaximumLength = sizeof(InfoBuffer);
1164  RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
1165 
1166  /* Setup a temporary string for concatenation */
1167  TempString2.Buffer = TempBuffer;
1168  TempString2.MaximumLength = sizeof(TempBuffer);
1169 
1170  /* Check if there's an OEM string */
1171  if (FdoExtension->OemInfo[0])
1172  {
1173  /* Build the OEM info string */
1174  RtlInitAnsiString(&TempString, FdoExtension->OemInfo);
1175 
1176  /* Convert it to Unicode and append it */
1177  RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1178  RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1179  }
1180 
1181  /* Build the model number string */
1182  RtlInitAnsiString(&TempString, FdoExtension->ModelNumber);
1183 
1184  /* Convert it to Unicode and append it */
1185  RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
1186  RtlAppendUnicodeStringToString(&InfoString, &TempString2);
1187 
1188  /* Return the final appended string */
1189  QueryData = InfoString.Buffer;
1190  QueryLength = InfoString.Length;
1191  break;
1192 
1193  default:
1194 
1195  /* Everything else is unknown */
1197  break;
1198  }
1199 
1200  /* Return the required length and check if the caller supplied enough */
1201  *ReturnedLength = QueryLength;
1202  if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
1203 
1204  /* Copy the data if there's enough space and it exists */
1205  if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength);
1206 
1207  /* Return function result */
1208  return Status;
1209 }
1210 
1211 NTSTATUS
1212 NTAPI
1214  IN ULONG Tag,
1216 {
1217  NTSTATUS Status;
1218  PAGED_CODE();
1220  DbgPrint("CmBattQueryStatus - Tag (%d) Device %x\n", Tag, DeviceExtension->DeviceId);
1221 
1222  /* Query ACPI information */
1223  Status = CmBattGetBatteryStatus(DeviceExtension, Tag);
1224  if (NT_SUCCESS(Status))
1225  {
1226  BatteryStatus->PowerState = DeviceExtension->State;
1227  BatteryStatus->Capacity = DeviceExtension->RemainingCapacity;
1228  BatteryStatus->Voltage = DeviceExtension->PresentVoltage;
1229  BatteryStatus->Rate = DeviceExtension->Rate;
1230  }
1231 
1232  /* Return status */
1234  DbgPrint("CmBattQueryStatus: Returning [%#08lx][%#08lx][%#08lx][%#08lx]\n",
1238  BatteryStatus->Rate);
1239  return Status;
1240 }
1241 
1242 NTSTATUS
1243 NTAPI
1246 {
1247  NTSTATUS Status;
1250  UNICODE_STRING CallbackName;
1251 
1252  /* Allocate registry path */
1257  'MtaB');
1259  {
1260  /* Fail if we're out of memory this early */
1262  DbgPrint("CmBatt: Couldn't allocate pool for registry path.");
1264  }
1265 
1266  /* Buffer allocated, copy the string */
1269  DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%ws\"\n",
1270  DriverObject,
1271  RegistryPath->Buffer);
1272 
1273  /* Setup the major dispatchers */
1280 
1281  /* And the unload routine */
1283 
1284  /* And the add device routine */
1286  DriverExtension->AddDevice = CmBattAddDevice;
1287 
1288  /* Create a power callback */
1289  RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
1291  &CallbackName,
1293  NULL,
1294  NULL);
1296  if (!NT_SUCCESS(Status))
1297  {
1298  /* No callback, fail */
1301  DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status);
1302  }
1303  else
1304  {
1305  /* Register the power callback now */
1308  DriverObject);
1310  {
1311  /* Last thing: setup our DPC and timer for battery wake */
1314  }
1315  else
1316  {
1319  DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n");
1320  }
1321 
1322  /* All good */
1324  }
1325 
1326  /* Return failure or success */
1327  return Status;
1328 }
1329 
1330 /* EOF */
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
IO_REMOVE_LOCK RemoveLock
Definition: cmbatt.h:115
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG RemainingCapacity
Definition: cmbatt.h:74
#define IN
Definition: typedefs.h:38
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:795
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS NTAPI CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BST_DATA BstData)
Definition: cmexec.c:334
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
_In_ ULONG _Out_ PBATTERY_STATUS BatteryStatus
Definition: batclass.h:198
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_BATTERY_QUERY_UNIQUE_ID
Definition: cmbatt.h:17
BOOLEAN DelayNotification
Definition: cmbatt.h:119
VOID NTAPI CmBattPowerCallBack(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Action, IN ULONG Value)
Definition: cmbatt.c:30
NTSTATUS NTAPI CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag)
Definition: cmbatt.c:782
struct _BATTERY_INFORMATION BATTERY_INFORMATION
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define DbgPrint
Definition: loader.c:25
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
ULONG PowerState
Definition: batclass.h:154
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI CmBattOpenClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbatt.c:287
enum _BATTERY_QUERY_INFORMATION_LEVEL BATTERY_QUERY_INFORMATION_LEVEL
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
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
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG _In_ PBATTERY_NOTIFY BatteryNotify
Definition: batclass.h:215
#define IOCTL_BATTERY_QUERY_STA
Definition: cmbatt.h:20
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2716
NTSTATUS NTAPI CmBattSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS NTAPI ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
Definition: callback.c:361
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define BATTERY_CRITICAL
Definition: batclass.h:76
BCLASSAPI NTSTATUS NTAPI BatteryClassIoctl(PVOID ClassData, PIRP Irp)
Definition: battc.c:189
#define PO_CB_SYSTEM_STATE_LOCK
#define ACPI_BATT_STAT_DISCHARG
Definition: cmbatt.h:63
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define CM_MAX_VALUE
Definition: cmbatt.h:67
_Out_ PULONG BatteryTag
Definition: batclass.h:173
LARGE_INTEGER CmBattWakeDpcDelay
Definition: cmbatt.c:24
#define IOCTL_BATTERY_QUERY_BIF
Definition: cmbatt.h:29
ULONG CmBattDebug
Definition: cmbatt.c:17
#define CMBATT_PNP_INFO
Definition: cmbatt.h:40
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
UNICODE_STRING GlobalRegistryPath
Definition: cmbatt.c:20
#define PAGED_CODE()
Definition: video.h:57
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
VOID NTAPI ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
Definition: callback.c:636
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define ACPI_BATT_STAT_CRITICAL
Definition: cmbatt.h:65
NTSTATUS NTAPI CmBattPnpDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS NTAPI CmBattPowerDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PVOID CmBattPowerCallBackRegistration
Definition: cmbatt.c:19
PDEVICE_OBJECT AcAdapterPdo
Definition: cmbatt.c:23
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
struct _ACPI_BIF_DATA ACPI_BIF_DATA
#define CMBATT_AR_INSERT
Definition: cmbatt.h:99
FAST_MUTEX FastMutex
Definition: cmbatt.h:109
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2173
VOID NTAPI CmBattUnload(IN PDRIVER_OBJECT DriverObject)
Definition: cmbatt.c:254
#define IOCTL_BATTERY_QUERY_PSR
Definition: cmbatt.h:23
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define CM_UNKNOWN_VALUE
Definition: cmbatt.h:68
smooth NULL
Definition: ftsmooth.c:416
#define CMBATT_AR_REMOVE
Definition: cmbatt.h:100
BCLASSAPI NTSTATUS NTAPI BatteryClassStatusNotify(PVOID ClassData)
Definition: battc.c:79
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define BATTERY_UNKNOWN_CAPACITY
Definition: batclass.h:65
void DPRINT(...)
Definition: polytest.cpp:61
#define ACPI_STA_BATTERY_PRESENT
Definition: actypes.h:1319
Definition: bufpool.h:45
ULONG HighCapacity
Definition: batclass.h:205
#define BATTERY_CHARGING
Definition: batclass.h:75
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define CMBATT_ACPI_WARNING
Definition: cmbatt.h:38
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
ULONG PowerState
Definition: batclass.h:203
NTSTATUS NTAPI CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG BatteryTag, IN PBATTERY_NOTIFY BatteryNotify)
Definition: cmbatt.c:636
#define BATTERY_UNKNOWN_VOLTAGE
Definition: batclass.h:79
NTSTATUS NTAPI CmBattGetStaData(PDEVICE_OBJECT DeviceObject, PULONG StaData)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ACPI_BATT_NOTIFY_STATUS
Definition: cmbatt.h:60
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
NTSTATUS NTAPI CmBattGetPsrData(PDEVICE_OBJECT DeviceObject, PULONG PsrData)
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG Action
Definition: fsrtlfuncs.h:738
#define ACPI_BATT_NOTIFY_INFO
Definition: cmbatt.h:61
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG AtRate
Definition: batclass.h:183
#define BATTERY_UNKNOWN_RATE
Definition: batclass.h:82
#define BATTERY_POWER_ON_LINE
Definition: batclass.h:73
#define ACPI_BATT_POWER_UNIT_WATTS
Definition: cmbatt.h:78
NTSTATUS NTAPI CmBattSetTripPpoint(PCMBATT_DEVICE_EXTENSION DeviceExtension, ULONG AlarmValue)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CMBATT_AR_NOTIFY
Definition: cmbatt.h:98
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
NTSTATUS NTAPI CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbatt.c:350
NTSTATUS NTAPI CmBattAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject)
static const WCHAR L[]
Definition: oid.c:1250
Definition: ketypes.h:687
NTSTATUS NTAPI CmBattGetUniqueId(PDEVICE_OBJECT DeviceObject, PULONG UniqueId)
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2179
NTSTATUS NTAPI CmBattDisableStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension)
Definition: cmbatt.c:595
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
#define CMBATT_GENERIC_INFO
Definition: cmbatt.h:36
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
#define CMBATT_GENERIC_STATUS
Definition: cmbatt.h:35
#define ACPI_BUS_CHECK
Definition: cmbatt.h:51
#define IRP_MJ_SYSTEM_CONTROL
PDEVICE_OBJECT PdoDeviceObject
Definition: cmbatt.h:107
ULONG Capacity
Definition: batclass.h:155
#define InterlockedExchange
Definition: armddk.h:54
NTSTATUS NTAPI CmBattQueryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag, IN PBATTERY_STATUS BatteryStatus)
Definition: cmbatt.c:1213
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define ACPI_DEVICE_CHECK
Definition: cmbatt.h:52
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG LowCapacity
Definition: batclass.h:204
NTSTATUS NTAPI CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension, PACPI_BIF_DATA BifData)
Definition: cmexec.c:325
KDPC CmBattWakeDpcObject
Definition: cmbatt.c:22
KTIMER CmBattWakeDpcTimerObject
Definition: cmbatt.c:21
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define CMBATT_GENERIC_WARNING
Definition: cmbatt.h:37
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
#define IOCTL_BATTERY_SET_TRIP_POINT
Definition: cmbatt.h:26
#define CMBATT_ACPI_ASSERT
Definition: cmbatt.h:43
NTSTATUS NTAPI CmBattQueryTag(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, OUT PULONG Tag)
Definition: cmbatt.c:536
CMBATT_EXTENSION_TYPE FdoType
Definition: cmbatt.h:104
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: cmbatt.c:1244
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
struct _ACPI_BST_DATA ACPI_BST_DATA
PDEVICE_OBJECT AttachedDevice
Definition: cmbatt.h:108
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define BATTERY_DISCHARGING
Definition: batclass.h:74
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
PVOID NTAPI ExRegisterCallback(IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext)
Definition: callback.c:556
#define OUT
Definition: typedefs.h:39
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
PCALLBACK_OBJECT CmBattPowerCallBackObject
Definition: cmbatt.c:18
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define IOCTL_BATTERY_QUERY_BST
Definition: cmbatt.h:32
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: cmbatt.c:1000
#define IoAcquireRemoveLock(RemoveLock, Tag)
ULONGLONG NTAPI KeQueryInterruptTime(VOID)
Definition: clock.c:203
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI CmBattWakeDpc(IN PKDPC Dpc, IN PCMBATT_DEVICE_EXTENSION FdoExtension, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: cmbatt.c:75
#define ACPI_BATT_STAT_CHARGING
Definition: cmbatt.h:64
#define ACPI_BATT_POWER_UNIT_AMPS
Definition: cmbatt.h:79
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2168
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68