Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

240 lines
6.4 KiB

#define BATTERYCLASS 1
#ifndef FAR
#define FAR
#endif
#include <wdm.h>
#include <wmistr.h>
#include <wmilib.h>
#include <batclass.h>
//
// Debug
//
#define DEBUG DBG
#if DEBUG
extern ULONG BattDebug;
extern ULONG NextDeviceNum;
#define BattPrint(l,m) if(l & BattDebug) DbgPrint m
#else
#define BattPrint(l,m)
#endif
#define BATT_LOW 0x00000001
#define BATT_NOTE 0x00000002
#define BATT_WARN 0x00000004
#define BATT_ERROR 0x00000008
#define BATT_TRACE 0x00000010
#define BATT_MP_ERROR 0x00000100
#define BATT_MP_DATA 0x00000200
#define BATT_IOCTL 0x00001000
#define BATT_IOCTL_DATA 0x00002000
#define BATT_IOCTL_QUEUE 0x00004000
#define BATT_WMI 0x00008000
#define BATT_LOCK 0x00010000
#define BATT_DEBUG 0x80000000
//
// Battery class info
//
#define NTMS 10000L // 1 millisecond is ten thousand 100ns
#define NTSEC (NTMS * 1000L)
#define NTMIN ((ULONGLONG) 60 * NTSEC)
#define SEC 1000
#define MIN (60 * SEC)
#define MIN_STATUS_POLL_RATE (3L * NTMIN)
// This is the slowest rate at which we should ever poll
// the battery when doing polling.
#define MAX_STATUS_POLL_RATE (20 * NTSEC)
// This is in general the fastest we should ever poll the battery.
#define INVALID_DATA_POLL_RATE (1 * NTSEC)
// If the battery returned invalid information, we want to poll
// it more frequesntly, since invalid information generally
// indicates that the battery was in a transition state. The user
// will not want to wait 20 seconds for the UI to update, but we don't
// want to poll too fast and hurt the performance of a machine with a
// poorly designed battery too much.
#define INVALID_DATA_MAX_RETRY 10
// Only retry 20 time before giving up.
// This should be reset on any notifiation from the battery.
#define STATUS_VALID_TIME (2 * NTSEC)
// If a request is received within STATUS_VALID_TIME of the last request
// time information was read, and there hasn't been a notification from
// the battery, the driver will assume that the cached values are good enough.
//
// WMI info
//
#define MOFRESOURCENAME L"BATTCWMI"
#define MOFREGISTRYPATH L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\BattC"
//#define MOFREGISTRYPATH L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{72631E54-78A4-11D0-BCF7-00AA00B7B32A}"
typedef enum {
BattWmiStatusId,
BattWmiRuntimeId,
BattWmiTemperatureId,
BattWmiFullChargedCapacityId,
BattWmiCycleCountId,
BattWmiStaticDataId,
BattWmiStatusChangeId,
BattWmiTagChangeId,
BattWmiTotalGuids
} BATT_WMI_GUID_INDEX;
//
// Non-paged battery class information
//
typedef struct {
//
// Pointer to paged information
//
struct _BATT_INFO *BattInfo; // Pointer to paged portion
//
// General
//
KTIMER WorkerTimer; // Timer to get worker thread
KDPC WorkerDpc; // DPC to get worker thread
KTIMER TagTimer; // Timer for query tag requests
KDPC TagDpc;
WORK_QUEUE_ITEM WorkerThread; // WORK_QUEUE to get worker thread
ULONG WorkerActive;
ULONG CheckStatus; // Worker to check status
ULONG CheckTag; // Worker to check for battery tag
ULONG StatusNotified; // Notification has occured (must re-read)
ULONG TagNotified;
FAST_MUTEX Mutex; // Synchorize with worker thread
BOOLEAN WantToRemove; // Syncronize device removal
LONG InUseCount;
KEVENT ReadyToRemove;
#if DEBUG
ULONG DeviceNum; // Device number for debug prints
#endif
} BATT_NP_INFO, *PBATT_NP_INFO;
//
// Paged battery class information
//
typedef struct _BATT_INFO {
WMILIB_CONTEXT WmiLibContext;
ULONG WmiGuidIndex; // Used to ignore miniclass WMI
// GUIDs
//
// IO
//
ULONG Tag; // Current battery tag
LIST_ENTRY IoQueue; // IRPs waiting to be processed
LIST_ENTRY StatusQueue; // Waiting status requests
LIST_ENTRY TagQueue; // Waiting battery tag requests
LIST_ENTRY WmiQueue;
ULONGLONG TagTime; // Time when tag was read
ULONGLONG StatusTime; // Time when status was read
BATTERY_STATUS Status; // The status
ULONG InvalidRetryCount; // How many times ni a row has the battery returned invalid data?
#if DEBUG
ULONG FullChargedCap;
PBATT_NP_INFO BattNPInfo;
#endif
ULONG NotifyTimeout; // LCD timeout of wat
BATTERY_MINIPORT_INFO Mp; // Miniport Info
UNICODE_STRING SymbolicLinkName; // Name returned by IoRegisterDeviceInterface
} BATT_INFO, *PBATT_INFO;
//
// WmiQueue entry
//
typedef struct _BATT_WMI_REQUEST {
LIST_ENTRY ListEntry;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
BATT_WMI_GUID_INDEX GuidIndex;
IN OUT PULONG InstanceLengthArray;
IN ULONG OutBufferSize;
OUT PUCHAR Buffer;
} BATT_WMI_REQUEST, *PBATT_WMI_REQUEST;
//
// Prototypes
//
VOID
BattCWorkerDpc (
IN struct _KDPC *Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
VOID
BattCWorkerThread (
IN PVOID Context
);
VOID
BattCQueueWorker (
IN PBATT_NP_INFO BattNPInfo,
IN BOOLEAN CheckStatus
);
NTSTATUS
BatteryIoctl(
IN ULONG Ioctl,
IN PDEVICE_OBJECT DeviceObject,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN BOOLEAN PrivateIoctl
);
VOID
BattCTagDpc (
IN struct _KDPC *Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
VOID
BattCCancelTag (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);