321 lines
8.1 KiB
C
321 lines
8.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ken Reneris
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
console
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
//
|
|||
|
// set variable to define global variables
|
|||
|
//
|
|||
|
|
|||
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
#include <nturtl.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <errno.h>
|
|||
|
#include <malloc.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <poclass.h>
|
|||
|
|
|||
|
//
|
|||
|
// global handles
|
|||
|
//
|
|||
|
|
|||
|
UCHAR Usage[] = "batt: \n";
|
|||
|
HANDLE DriverHandle;
|
|||
|
ULONG BatteryTag;
|
|||
|
#define RANGE 1
|
|||
|
|
|||
|
//
|
|||
|
// Prototypes
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
InitDriver ( CHAR *NamePtr );
|
|||
|
|
|||
|
|
|||
|
int
|
|||
|
Nib (
|
|||
|
UCHAR c
|
|||
|
)
|
|||
|
{
|
|||
|
if (c >= '0' && c <= '9') {
|
|||
|
return c - '0';
|
|||
|
}
|
|||
|
|
|||
|
if (c >= 'A' && c <= 'F') {
|
|||
|
return c - 'A' + 10;
|
|||
|
}
|
|||
|
|
|||
|
if (c >= 'a' && c <= 'f') {
|
|||
|
return c - 'a' + 10;
|
|||
|
}
|
|||
|
|
|||
|
printf ("Invalid hex value\n");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int
|
|||
|
htoi (
|
|||
|
PUCHAR s
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
UCHAR c;
|
|||
|
|
|||
|
i = Nib(s[0]);
|
|||
|
if (s[1]) {
|
|||
|
i = i << 4 | Nib(s[1]);
|
|||
|
}
|
|||
|
return i;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
GetBatteryTag (
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
IO_STATUS_BLOCK IOSB;
|
|||
|
|
|||
|
|
|||
|
Status = NtDeviceIoControlFile(
|
|||
|
DriverHandle,
|
|||
|
(HANDLE) NULL, // event
|
|||
|
(PIO_APC_ROUTINE) NULL,
|
|||
|
(PVOID) NULL,
|
|||
|
&IOSB,
|
|||
|
IOCTL_BATTERY_QUERY_TAG,
|
|||
|
NULL, // input buffer
|
|||
|
0,
|
|||
|
&BatteryTag, // output buffer
|
|||
|
sizeof (BatteryTag)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf ("Battery tag not available. Status = %x\n", Status);
|
|||
|
BatteryTag = 0xffffffff;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
GetBatteryInfo (
|
|||
|
IN BATTERY_QUERY_INFORMATION_LEVEL Level,
|
|||
|
IN PVOID Buffer,
|
|||
|
IN ULONG BufferLength
|
|||
|
)
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
IO_STATUS_BLOCK IOSB;
|
|||
|
BATTERY_QUERY_INFORMATION BInfo;
|
|||
|
|
|||
|
memset (Buffer, 0, BufferLength);
|
|||
|
BInfo.BatteryTag = BatteryTag;
|
|||
|
BInfo.InformationLevel = Level;
|
|||
|
|
|||
|
Status = NtDeviceIoControlFile(
|
|||
|
DriverHandle,
|
|||
|
(HANDLE) NULL, // event
|
|||
|
(PIO_APC_ROUTINE) NULL,
|
|||
|
(PVOID) NULL,
|
|||
|
&IOSB,
|
|||
|
IOCTL_BATTERY_QUERY_INFORMATION,
|
|||
|
&BInfo, // input buffer
|
|||
|
sizeof (BInfo),
|
|||
|
Buffer, // output buffer
|
|||
|
BufferLength
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf ("Query battery information failed. Level %x. Status = %x\n", Level, Status);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
GetBatteryStatus (
|
|||
|
IN PBATTERY_WAIT_STATUS WaitStatus,
|
|||
|
OUT PBATTERY_STATUS BatteryStatus
|
|||
|
)
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
IO_STATUS_BLOCK IOSB;
|
|||
|
|
|||
|
memset (BatteryStatus, 0xAB, sizeof(BatteryStatus));
|
|||
|
|
|||
|
Status = NtDeviceIoControlFile(
|
|||
|
DriverHandle,
|
|||
|
(HANDLE) NULL, // event
|
|||
|
(PIO_APC_ROUTINE) NULL,
|
|||
|
(PVOID) NULL,
|
|||
|
&IOSB,
|
|||
|
IOCTL_BATTERY_QUERY_STATUS,
|
|||
|
WaitStatus, // input buffer
|
|||
|
sizeof (BATTERY_WAIT_STATUS),
|
|||
|
BatteryStatus, // output buffer
|
|||
|
sizeof (BATTERY_STATUS)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf ("Query battery status failed. Status = %x\n", Status);
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
// dump battery status
|
|||
|
|
|||
|
printf ("Power State.........: %08x\n", BatteryStatus->PowerState);
|
|||
|
printf ("Capacity............: %08x %d\n", BatteryStatus->Capacity, BatteryStatus->Capacity);
|
|||
|
printf ("Voltage.............: %08x %d\n", BatteryStatus->Voltage, BatteryStatus->Voltage);
|
|||
|
printf ("Current.,,,,,,,,,...: %08x %d\n", BatteryStatus->Current, BatteryStatus->Current);
|
|||
|
printf ("\n");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int
|
|||
|
__cdecl
|
|||
|
main(USHORT argc, CHAR **argv)
|
|||
|
{
|
|||
|
ULONG BattTag;
|
|||
|
BATTERY_INFORMATION BInfo;
|
|||
|
ULONG BETime;
|
|||
|
WCHAR BDeviceName[50];
|
|||
|
UCHAR BManDate[50];
|
|||
|
WCHAR BManName[50];
|
|||
|
ULONG BETemp;
|
|||
|
WCHAR BEUID [50];
|
|||
|
ULONG BEGran[4];
|
|||
|
BATTERY_WAIT_STATUS WStat;
|
|||
|
BATTERY_STATUS BStat;
|
|||
|
CHAR *NamePtr;
|
|||
|
|
|||
|
if (argc > 1) {
|
|||
|
NamePtr=argv[1];
|
|||
|
} else {
|
|||
|
NamePtr = "CmBatt";
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Locate pentium perf driver
|
|||
|
//
|
|||
|
|
|||
|
if (!InitDriver (NamePtr)) {
|
|||
|
printf ("CmBatt not found\n");
|
|||
|
exit (1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
GetBatteryTag ();
|
|||
|
printf ("Battery Tag.........: %x\n", BatteryTag);
|
|||
|
|
|||
|
//
|
|||
|
// Get generic info
|
|||
|
//
|
|||
|
|
|||
|
GetBatteryInfo (BatteryInformation, &BInfo, sizeof(BInfo));
|
|||
|
GetBatteryInfo (BatteryEstimatedTime, &BETime, sizeof(BETime));
|
|||
|
GetBatteryInfo (BatteryDeviceName, BDeviceName, sizeof(BDeviceName));
|
|||
|
GetBatteryInfo (BatteryManufactureDate, BManDate, sizeof(BManDate));
|
|||
|
GetBatteryInfo (BatteryManufactureName, BManName, sizeof(BManName));
|
|||
|
GetBatteryInfo (BatteryTemperature, &BETemp, sizeof(BETemp));
|
|||
|
GetBatteryInfo (BatteryUniqueID, BEUID, sizeof(BEUID));
|
|||
|
GetBatteryInfo (BatteryGranularityInformation, BEGran, sizeof(BEGran));
|
|||
|
|
|||
|
// dump it...
|
|||
|
printf ("Capabilities........: %08x\n", BInfo.Capabilities);
|
|||
|
printf ("Technology..........: %02x\n", BInfo.Technology);
|
|||
|
printf ("Chemisttry..........: %4.4s\n", BInfo.Chemistry);
|
|||
|
printf ("Designed Capacity...: %08x\n", BInfo.DesignedCapacity);
|
|||
|
printf ("FullCharged Capacity: %08x\n", BInfo.FullChargedCapacity);
|
|||
|
printf ("Default Alert1......: %08x\n", BInfo.DefaultAlert1);
|
|||
|
printf ("Default Alert2......: %08x\n", BInfo.DefaultAlert2);
|
|||
|
printf ("Critical Bias.......: %08x\n", BInfo.CriticalBias);
|
|||
|
printf ("Cycle Count.........: %08x\n", BInfo.CycleCount);
|
|||
|
printf ("Granularity.........: %x %x %x %x\n", BEGran[0], BEGran[1], BEGran[2], BEGran[3]);
|
|||
|
printf ("Temapture...........: %08x\n", BETemp);
|
|||
|
wprintf (L"Unique ID...........: %s\n", BEUID);
|
|||
|
|
|||
|
printf ("Estimated Time......: %08x\n", BETime);
|
|||
|
wprintf (L"Device Name.........: %s\n", BDeviceName);
|
|||
|
printf ("Manufacture Date....: %d %d %d %d\n", BManDate[0], BManDate[1], BManDate[2], BManDate[3]);
|
|||
|
wprintf (L"Manufacture Name....: %s\n", BManName);
|
|||
|
|
|||
|
printf ("\n");
|
|||
|
|
|||
|
memset (&WStat, 0, sizeof(WStat));
|
|||
|
WStat.BatteryTag = BatteryTag;
|
|||
|
|
|||
|
GetBatteryStatus (&WStat, &BStat);
|
|||
|
|
|||
|
// Now that we've got the state, let's perform a long term status change request
|
|||
|
WStat.PowerState = BStat.PowerState;
|
|||
|
WStat.LowCapacity = BStat.Capacity - RANGE;
|
|||
|
WStat.HighCapacity = BStat.Capacity + RANGE;
|
|||
|
WStat.Timeout = 50000000; // 5 min
|
|||
|
GetBatteryStatus (&WStat, &BStat);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
InitDriver (
|
|||
|
CHAR *NamePtr
|
|||
|
)
|
|||
|
{
|
|||
|
UNICODE_STRING DriverName;
|
|||
|
ANSI_STRING AnsiName;
|
|||
|
NTSTATUS status;
|
|||
|
OBJECT_ATTRIBUTES ObjA;
|
|||
|
IO_STATUS_BLOCK IOSB;
|
|||
|
UCHAR strbuf[100];
|
|||
|
|
|||
|
sprintf (strbuf, "\\Device\\%s",NamePtr);
|
|||
|
|
|||
|
RtlInitAnsiString(&AnsiName, strbuf);
|
|||
|
|
|||
|
RtlAnsiStringToUnicodeString(&DriverName, &AnsiName, TRUE);
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&ObjA,
|
|||
|
&DriverName,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
0,
|
|||
|
0 );
|
|||
|
|
|||
|
status = NtOpenFile (
|
|||
|
&DriverHandle, // return handle
|
|||
|
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, // desired access
|
|||
|
&ObjA, // Object
|
|||
|
&IOSB, // io status block
|
|||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, // share access
|
|||
|
FILE_SYNCHRONOUS_IO_ALERT // open options
|
|||
|
);
|
|||
|
|
|||
|
if (!NT_SUCCESS(status)) {
|
|||
|
printf ("Device name %s Error %x\n", strbuf, status);
|
|||
|
return FALSE;
|
|||
|
} else {
|
|||
|
printf ("Opened Device name %s\n", strbuf);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|