Leaked source code of windows server 2003
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.
 
 
 
 
 
 

401 lines
9.6 KiB

#include <wdm.h>
#include <batclass.h>
#ifndef FAR
#define FAR
#endif
//
// Debug
//
#define DEBUG DBG
#if DEBUG
extern ULONG CompBattDebug;
#define BattPrint(l,m) if(l & CompBattDebug) 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_ERRORS (BATT_ERROR | BATT_WARN)
#define BATT_MP 0x00000010
#define BATT_DEBUG 0x00000020
#define BATT_TRACE 0x00000100
#define BATT_DATA 0x00000200
//
// 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)
//
// Poll rates for when a notification alarm cannot be set
//
#define MIN_STATUS_POLL_RATE (3L * NTMIN)
#define MAX_STATUS_POLL_RATE (20 * NTSEC)
#define STATUS_VALID_TIME (2 * NTSEC)
#define MAX_HIGH_CAPACITY 0x7fffffff
#define MIN_LOW_CAPACITY 0x0
//
// Charge/Discharge policy values (in percent)
//
#define BATTERY_MIN_SAFE_CAPACITY 2 // Min we will attempt to run on
#define BATTERY_MAX_CHARGE_CAPACITY 90 // Max we will attempt to charge
//
// Cache expiration timeouts -- when the cached battery status/info expires.
//
#define CACHE_STATUS_TIMEOUT (4 * NTSEC)
#define CACHE_INFO_TIMEOUT (4 * NTSEC)
//
// Cached battery info
//
typedef struct {
ULONG Tag;
ULONG Valid;
BATTERY_INFORMATION Info;
ULONGLONG InfoTimeStamp;
UCHAR ManufacturerNameLength;
UCHAR ManufacturerName[MAX_BATTERY_STRING_SIZE];
UCHAR DeviceNameLength;
UCHAR DeviceName[MAX_BATTERY_STRING_SIZE];
BATTERY_MANUFACTURE_DATE ManufacturerDate;
ULONG SerialNumber;
BATTERY_STATUS Status;
ULONGLONG StatusTimeStamp;
} STATIC_BAT_INFO, *PSTATIC_BAT_INFO;
#define VALID_TAG_DATA 0x01 // manufacturer, device, serial #
#define VALID_MODE 0x02
#define VALID_INFO 0x04
#define VALID_CYCLE_COUNT 0x08
#define VALID_SANITY_CHECK 0x10
#define VALID_TAG 0x80
#define VALID_NOTIFY 0x100
#define VALID_ALL 0x1F // (does not include tag)
//
// Locking mechanism for battery nodes so we don't delete out from under
// ourselves. I would just use an IO_REMOVE_LOCK, but that's NT not WDM...
//
typedef struct _COMPBATT_DELETE_LOCK {
BOOLEAN Deleted;
BOOLEAN Reserved [3];
LONG RefCount;
KEVENT DeleteEvent;
} COMPBATT_DELETE_LOCK, *PCOMPBATT_DELETE_LOCK;
VOID
CompbattInitializeDeleteLock (
IN PCOMPBATT_DELETE_LOCK Lock
);
NTSTATUS
CompbattAcquireDeleteLock (
IN PCOMPBATT_DELETE_LOCK Lock
);
VOID
CompbattReleaseDeleteLock (
IN PCOMPBATT_DELETE_LOCK Lock
);
VOID
CompbattReleaseDeleteLockAndWait (
IN PCOMPBATT_DELETE_LOCK Lock
);
//
// Battery node in the composite's list of batteries
//
typedef struct {
LIST_ENTRY Batteries; // All batteries in composite
COMPBATT_DELETE_LOCK DeleteLock;
PDEVICE_OBJECT DeviceObject; // device object for the battery
PIRP StatusIrp; // current status irp at device
WORK_QUEUE_ITEM WorkItem; // Used for restarting status Irp
// if it is completed at DPC level
BOOLEAN NewBatt; // Is this a new battery on the list
UCHAR State;
BATTERY_WAIT_STATUS Wait;
union {
BATTERY_STATUS Status;
BATTERY_WAIT_STATUS Wait;
ULONG Tag;
} IrpBuffer;
//
// Keep some static information around so we don't have to go out to the
// batteries all the time.
//
STATIC_BAT_INFO Info;
//
// Symbolic link name for the battery. Since we calculate the length of this
// structure based on the structure size plus the length of this string, the
// string must be the last thing declared in the structure.
//
UNICODE_STRING BattName;
} COMPOSITE_ENTRY, *PCOMPOSITE_ENTRY;
#define CB_ST_GET_TAG 0
#define CB_ST_GET_STATUS 1
//
// Composite battery device extension
//
typedef struct {
PVOID Class; // Class information
// ULONG Tag; // Current tag of composite battery
ULONG NextTag; // Next tag
LIST_ENTRY Batteries; // All batteries
FAST_MUTEX ListMutex; // List synchronization
//
// Keep some static information around so we don't have to go out to the
// batteries all the time.
//
STATIC_BAT_INFO Info;
BATTERY_WAIT_STATUS Wait;
PDEVICE_OBJECT LowerDevice; // PDO
PDEVICE_OBJECT DeviceObject; // Compbatt Device
PVOID NotificationEntry; // PnP registration handle
} COMPOSITE_BATTERY, *PCOMPOSITE_BATTERY;
//
// Prototypes
//
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
CompBattIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CompBattSystemControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CompBattQueryTag (
IN PVOID Context,
OUT PULONG BatteryTag
);
NTSTATUS
CompBattQueryInformation (
IN PVOID Context,
IN ULONG BatteryTag,
IN BATTERY_QUERY_INFORMATION_LEVEL Level,
IN LONG AtRate,
OUT PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnedLength
);
NTSTATUS
CompBattQueryStatus (
IN PVOID Context,
IN ULONG BatteryTag,
OUT PBATTERY_STATUS BatteryStatus
);
NTSTATUS
CompBattSetStatusNotify (
IN PVOID Context,
IN ULONG BatteryTag,
IN PBATTERY_NOTIFY BatteryNotify
);
NTSTATUS
CompBattDisableStatusNotify (
IN PVOID Context
);
NTSTATUS
CompBattDriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
CompBattGetBatteryInformation (
IN PBATTERY_INFORMATION TotalBattInfo,
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattGetBatteryGranularity (
IN PBATTERY_REPORTING_SCALE GranularityBuffer,
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattPrivateIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CompBattGetEstimatedTime (
IN PULONG TimeBuffer,
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattAddDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PDO
);
NTSTATUS
CompBattPowerDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CompBattPnpDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
CompBattUnload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
CompBattOpenClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
BatteryIoctl(
IN ULONG Ioctl,
IN PDEVICE_OBJECT DeviceObject,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN BOOLEAN PrivateIoctl
);
NTSTATUS
CompBattPnpEventHandler(
IN PVOID NotificationStructure,
IN PVOID Context
);
NTSTATUS
CompBattAddNewBattery(
IN PUNICODE_STRING SymbolicLinkName,
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattRemoveBattery(
IN PUNICODE_STRING SymbolicLinkName,
IN PCOMPOSITE_BATTERY CompBatt
);
BOOLEAN
IsBatteryAlreadyOnList(
IN PUNICODE_STRING SymbolicLinkName,
IN PCOMPOSITE_BATTERY CompBatt
);
PCOMPOSITE_ENTRY
RemoveBatteryFromList(
IN PUNICODE_STRING SymbolicLinkName,
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattGetBatteries(
IN PCOMPOSITE_BATTERY CompBatt
);
BOOLEAN
CompBattVerifyStaticInfo (
IN PCOMPOSITE_BATTERY CompBatt
);
VOID CompBattMonitorIrpCompleteWorker (
IN PVOID Context
);
NTSTATUS
CompBattMonitorIrpComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
VOID
CompBattRecalculateTag (
IN PCOMPOSITE_BATTERY CompBatt
);
VOID
CompBattChargeDischarge (
IN PCOMPOSITE_BATTERY CompBatt
);
NTSTATUS
CompBattGetDeviceObjectPointer(
IN PUNICODE_STRING ObjectName,
IN ACCESS_MASK DesiredAccess,
OUT PFILE_OBJECT *FileObject,
OUT PDEVICE_OBJECT *DeviceObject
);