mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:05:43 +00:00
[ACPI] Move CMBATT and COMPBATT out of the acpi directory (#7599)
Move these out of ACPI in preparation for ACPI_NEW so they keep their juicy commit history. Also both ACPIs can coexist for awhile as I don't see the old driver getting removed anytime soon.
This commit is contained in:
parent
b35becef2e
commit
a8da29e888
19 changed files with 3 additions and 3 deletions
18
drivers/battery/compbatt/CMakeLists.txt
Normal file
18
drivers/battery/compbatt/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
compbatt.c
|
||||
compmisc.c
|
||||
comppnp.c)
|
||||
|
||||
list(APPEND PCH_SKIP_SOURCE
|
||||
guid.c)
|
||||
|
||||
add_library(compbatt MODULE
|
||||
${SOURCE}
|
||||
${PCH_SKIP_SOURCE}
|
||||
compbatt.rc)
|
||||
|
||||
set_module_type(compbatt kernelmodedriver)
|
||||
add_importlibs(compbatt ntoskrnl hal battc)
|
||||
add_pch(compbatt compbatt.h "${PCH_SKIP_SOURCE}")
|
||||
add_cd_file(TARGET compbatt DESTINATION reactos/system32/drivers FOR all)
|
1788
drivers/battery/compbatt/compbatt.c
Normal file
1788
drivers/battery/compbatt/compbatt.c
Normal file
File diff suppressed because it is too large
Load diff
329
drivers/battery/compbatt/compbatt.h
Normal file
329
drivers/battery/compbatt/compbatt.h
Normal file
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Composite Battery Driver
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Composite battery main header file
|
||||
* COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group <ros.arm@reactos.org>
|
||||
* Copyright 2024 George Bișoc <george.bisoc@reactos.org>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#ifndef _COMPBATT_PCH_
|
||||
#define _COMPBATT_PCH_
|
||||
|
||||
#include <wdm.h>
|
||||
#include <batclass.h>
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
//
|
||||
// I/O remove lock allocate tag
|
||||
//
|
||||
#define COMPBATT_TAG 'aBoC'
|
||||
|
||||
//
|
||||
// Composite battery flags
|
||||
//
|
||||
#define COMPBATT_BATTERY_INFORMATION_PRESENT 0x04
|
||||
#define COMPBATT_STATUS_NOTIFY_SET 0x10
|
||||
#define COMPBATT_TAG_ASSIGNED 0x80
|
||||
|
||||
//
|
||||
// IRP complete worker mode states
|
||||
//
|
||||
#define COMPBATT_QUERY_TAG 1
|
||||
#define COMPBATT_READ_STATUS 2
|
||||
|
||||
//
|
||||
// Low/High capacity wait constants
|
||||
//
|
||||
#define COMPBATT_WAIT_MIN_LOW_CAPACITY 0
|
||||
#define COMPBATT_WAIT_MAX_HIGH_CAPACITY 0x7FFFFFFF
|
||||
|
||||
//
|
||||
// One hour in seconds, used to calculate the total rate of each battery for time estimation
|
||||
//
|
||||
#define COMPBATT_ATRATE_HOUR_IN_SECS 3600
|
||||
|
||||
//
|
||||
// Time constant of which the battery status data is considered fresh (50000000 * 100ns == 5s)
|
||||
//
|
||||
#define COMPBATT_FRESH_STATUS_TIME 50000000
|
||||
|
||||
//
|
||||
// Macro that calculates the delta of a battery's capacity
|
||||
//
|
||||
#define COMPUTE_BATT_CAP_DELTA(LowDiff, Batt, TotalRate) \
|
||||
((ULONG)(((LONGLONG)LowDiff * (Batt)->BatteryStatus.Rate) / TotalRate))
|
||||
|
||||
//
|
||||
// Macro that calculates the "At Rate" time drain of the battery
|
||||
//
|
||||
#define COMPUTE_ATRATE_DRAIN(Batt, Time) \
|
||||
((LONG)((Batt)->BatteryStatus.Capacity) * COMPBATT_ATRATE_HOUR_IN_SECS / Time)
|
||||
|
||||
//
|
||||
// Composite battery debug levels
|
||||
//
|
||||
#define COMPBATT_DEBUG_INFO 0x1
|
||||
#define COMPBATT_DEBUG_TRACE 0x2
|
||||
#define COMPBATT_DEBUG_WARN 0x4
|
||||
#define COMPBATT_DEBUG_ERR 0x10
|
||||
#define COMPBATT_DEBUG_ALL_LEVELS (COMPBATT_DEBUG_INFO | COMPBATT_DEBUG_TRACE | COMPBATT_DEBUG_WARN | COMPBATT_DEBUG_ERR)
|
||||
|
||||
/* STRUCTURES *****************************************************************/
|
||||
|
||||
//
|
||||
// Individual ACPI battery data
|
||||
//
|
||||
typedef struct _COMPBATT_BATTERY_DATA
|
||||
{
|
||||
/* The linked battery with the Composite Battery */
|
||||
LIST_ENTRY BatteryLink;
|
||||
|
||||
/* I/O remove lock which protects the battery from being removed */
|
||||
IO_REMOVE_LOCK RemoveLock;
|
||||
|
||||
/*
|
||||
* The associated device object (usually CMBATT) and the I/O battery packet
|
||||
* which is used to transport and gather battery data.
|
||||
*/
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PIRP Irp;
|
||||
|
||||
/*
|
||||
* The Executive work item, which serves as a worker item for the
|
||||
* IRP battery monitor worker.
|
||||
*/
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
|
||||
/*
|
||||
* Execution state mode of the individual battery. Only two modes are valid:
|
||||
*
|
||||
* COMPBATT_QUERY_TAG - The battery is currently waiting for a tag to get assigned;
|
||||
* COMPBATT_READ_STATUS - The battery is querying battery status.
|
||||
*/
|
||||
UCHAR Mode;
|
||||
|
||||
/*
|
||||
* The battery wait configuration settings, set up by the SetStatusNotify method.
|
||||
* These values are used to instruct CMBATT when the battery status should be retrieved.
|
||||
*/
|
||||
BATTERY_WAIT_STATUS WaitStatus;
|
||||
|
||||
/*
|
||||
* A union that serves as the buffer which holds battery monitor IRP data, specifically
|
||||
* managed by CompBattMonitorIrpCompleteWorker, to avoid allocating separate memory pools.
|
||||
*/
|
||||
union
|
||||
{
|
||||
BATTERY_WAIT_STATUS WorkerWaitStatus;
|
||||
BATTERY_STATUS WorkerStatus;
|
||||
ULONG WorkerTag;
|
||||
} WorkerBuffer;
|
||||
|
||||
/* The ID of the battery that associates the identification of this battery */
|
||||
ULONG Tag;
|
||||
|
||||
/*
|
||||
* The battery flags that govern the behavior of the battery. The valid flags are:
|
||||
*
|
||||
* COMPBATT_BATTERY_INFORMATION_PRESENT - The static battery information ha been
|
||||
* queried. Re-querying such information is not needed.
|
||||
*
|
||||
* COMPBATT_STATUS_NOTIFY_SET - The current notification wait settings are valid.
|
||||
*
|
||||
* COMPBATT_TAG_ASSIGNED - The battery has a tag assigned and it can be read.
|
||||
*/
|
||||
ULONG Flags;
|
||||
|
||||
/* The static battery information and battery status */
|
||||
BATTERY_INFORMATION BatteryInformation;
|
||||
BATTERY_STATUS BatteryStatus;
|
||||
|
||||
/* The interrupt time of which the battery status was last read */
|
||||
ULONGLONG InterruptTime;
|
||||
|
||||
/* A uniquely given name of the battery that associates it */
|
||||
UNICODE_STRING BatteryName;
|
||||
} COMPBATT_BATTERY_DATA, *PCOMPBATT_BATTERY_DATA;
|
||||
|
||||
//
|
||||
// Composite battery device extension data
|
||||
//
|
||||
typedef struct _COMPBATT_DEVICE_EXTENSION
|
||||
{
|
||||
/*
|
||||
* The class data initialized and used by Battery Class. It contains information
|
||||
* such as miniport data used for registration and communication between the
|
||||
* Composite Battery and Battery Class, wait and context events, etc.
|
||||
*/
|
||||
PVOID ClassData;
|
||||
|
||||
/*
|
||||
* The successor computed tag. This field is used when there are more upcoming
|
||||
* batteries to be connected with the Composite Battery, of which the tag is
|
||||
* incremented by 1 by each new battery that is connected.
|
||||
*/
|
||||
ULONG NextTag;
|
||||
|
||||
/* A list of linked batteries connected with the Composite Battery */
|
||||
LIST_ENTRY BatteryList;
|
||||
|
||||
/* A mutex lock which ensures proper synchronization of Composite Battery operations */
|
||||
FAST_MUTEX Lock;
|
||||
|
||||
/* The ID of the Composite Battery */
|
||||
ULONG Tag;
|
||||
|
||||
/*
|
||||
* The battery flags that govern the behavior of the battery. The valid flags are:
|
||||
*
|
||||
* COMPBATT_BATTERY_INFORMATION_PRESENT - The static battery information has been
|
||||
* queried. Re-querying such information is not needed.
|
||||
*
|
||||
* COMPBATT_STATUS_NOTIFY_SET - The current notification wait settings are valid.
|
||||
*
|
||||
* COMPBATT_TAG_ASSIGNED - The battery has a tag assigned and it can be read.
|
||||
*/
|
||||
ULONG Flags;
|
||||
|
||||
/*
|
||||
* The Composite Battery static information, status and wait status settings.
|
||||
* Note that both the battery information and status are combined, based upon
|
||||
* the individual information and status of each linked battery.
|
||||
*/
|
||||
BATTERY_INFORMATION BatteryInformation;
|
||||
BATTERY_STATUS BatteryStatus;
|
||||
BATTERY_WAIT_STATUS WaitNotifyStatus;
|
||||
|
||||
/* The interrupt time of which the battery status was last read */
|
||||
ULONGLONG InterruptTime;
|
||||
|
||||
/*
|
||||
* The physical device object that associates the Composite Battery and
|
||||
* the attached device, typically the ACPI driver.
|
||||
*/
|
||||
PDEVICE_OBJECT AttachedDevice;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
|
||||
/* The notification entry that identifies the registered I/O PnP notification */
|
||||
PVOID NotificationEntry;
|
||||
} COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattAddDevice(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PDEVICE_OBJECT PdoDeviceObject
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattPowerDispatch(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattPnpDispatch(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattQueryInformation(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ ULONG Tag,
|
||||
_In_ BATTERY_QUERY_INFORMATION_LEVEL InfoLevel,
|
||||
_In_opt_ LONG AtRate,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG BufferLength,
|
||||
_Out_ PULONG ReturnedLength
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattQueryStatus(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
|
||||
_In_ ULONG Tag,
|
||||
_Out_ PBATTERY_STATUS BatteryStatus
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattGetEstimatedTime(
|
||||
_Out_ PULONG Time,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattSetStatusNotify(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
|
||||
_In_ ULONG BatteryTag,
|
||||
_In_ PBATTERY_NOTIFY BatteryNotify
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattDisableStatusNotify(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattQueryTag(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
|
||||
_Out_ PULONG Tag
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattMonitorIrpComplete(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp,
|
||||
_In_ PVOID Context
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CompBattMonitorIrpCompleteWorker(
|
||||
_In_ PCOMPBATT_BATTERY_DATA BatteryData
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattGetDeviceObjectPointer(
|
||||
_In_ PUNICODE_STRING DeviceName,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_Out_ PFILE_OBJECT *FileObject,
|
||||
_Out_ PDEVICE_OBJECT *DeviceObject
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
BatteryIoctl(
|
||||
_In_ ULONG IoControlCode,
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PVOID InputBuffer,
|
||||
_In_ ULONG InputBufferLength,
|
||||
_Out_ PVOID OutputBuffer,
|
||||
_Inout_ ULONG OutputBufferLength,
|
||||
_In_ BOOLEAN InternalDeviceIoControl
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattRemoveBattery(
|
||||
_In_ PUNICODE_STRING BatteryName,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension
|
||||
);
|
||||
|
||||
extern ULONG CompBattDebug;
|
||||
|
||||
#endif /* _COMPBATT_PCH_ */
|
5
drivers/battery/compbatt/compbatt.rc
Normal file
5
drivers/battery/compbatt/compbatt.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Composite Battery Driver"
|
||||
#define REACTOS_STR_INTERNAL_NAME "compbatt"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "compbatt.sys"
|
||||
#include <reactos/version.rc>
|
128
drivers/battery/compbatt/compmisc.c
Normal file
128
drivers/battery/compbatt/compmisc.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Composite Battery Driver
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Miscellaneous Support Routines
|
||||
* COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group <ros.arm@reactos.org>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "compbatt.h"
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
BatteryIoctl(
|
||||
_In_ ULONG IoControlCode,
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PVOID InputBuffer,
|
||||
_In_ ULONG InputBufferLength,
|
||||
_Out_ PVOID OutputBuffer,
|
||||
_Inout_ ULONG OutputBufferLength,
|
||||
_In_ BOOLEAN InternalDeviceIoControl)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
PAGED_CODE();
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING BatteryIoctl\n");
|
||||
|
||||
/* Initialize the event and IRP */
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, 0);
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
||||
DeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferLength,
|
||||
OutputBuffer,
|
||||
OutputBufferLength,
|
||||
InternalDeviceIoControl,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (Irp)
|
||||
{
|
||||
/* Call the class driver miniport */
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
/* Wait for result */
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
/* Print failure */
|
||||
if (!(NT_SUCCESS(Status)) && (CompBattDebug & COMPBATT_DEBUG_ERR))
|
||||
DbgPrint("BatteryIoctl: Irp failed - %x\n", Status);
|
||||
|
||||
/* Done */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING BatteryIoctl\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Out of memory */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("BatteryIoctl: couldn't create Irp\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattGetDeviceObjectPointer(
|
||||
_In_ PUNICODE_STRING DeviceName,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_Out_ PFILE_OBJECT *FileObject,
|
||||
_Out_ PDEVICE_OBJECT *DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PFILE_OBJECT LocalFileObject;
|
||||
HANDLE DeviceHandle;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Open a file object handle to the device */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DeviceName,
|
||||
OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwCreateFile(&DeviceHandle,
|
||||
DesiredAccess,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Reference the file object */
|
||||
Status = ObReferenceObjectByHandle(DeviceHandle,
|
||||
0,
|
||||
*IoFileObjectType,
|
||||
KernelMode,
|
||||
(PVOID)&LocalFileObject,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Return the FO and the associated DO */
|
||||
*FileObject = LocalFileObject;
|
||||
*DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
|
||||
}
|
||||
|
||||
/* Close the handle */
|
||||
ZwClose(DeviceHandle);
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
505
drivers/battery/compbatt/comppnp.c
Normal file
505
drivers/battery/compbatt/comppnp.c
Normal file
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Composite Battery Driver
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Plug-and-Play IOCTL/IRP Handling
|
||||
* COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group <ros.arm@reactos.org>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "compbatt.h"
|
||||
|
||||
#include <wdmguid.h>
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattPowerDispatch(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: PowerDispatch received power IRP.\n");
|
||||
|
||||
/* Start the next IRP */
|
||||
PoStartNextPowerIrp(Irp);
|
||||
|
||||
/* Call the next driver in the stack */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
|
||||
}
|
||||
|
||||
PCOMPBATT_BATTERY_DATA
|
||||
NTAPI
|
||||
RemoveBatteryFromList(
|
||||
_In_ PCUNICODE_STRING BatteryName,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PLIST_ENTRY ListHead, NextEntry;
|
||||
PCOMPBATT_BATTERY_DATA BatteryData;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE)
|
||||
DbgPrint("CompBatt: ENTERING RemoveBatteryFromList\n");
|
||||
|
||||
/* Loop the battery list */
|
||||
ExAcquireFastMutex(&DeviceExtension->Lock);
|
||||
ListHead = &DeviceExtension->BatteryList;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the battery information and compare the name */
|
||||
BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
|
||||
if (!RtlCompareUnicodeString(BatteryName, &BatteryData->BatteryName, TRUE))
|
||||
{
|
||||
/* Flush pending deletes and any lock waiters */
|
||||
IoAcquireRemoveLock(&BatteryData->RemoveLock, 0);
|
||||
ExReleaseFastMutex(&DeviceExtension->Lock);
|
||||
IoReleaseRemoveLockAndWait(&BatteryData->RemoveLock, 0);
|
||||
|
||||
/* Remove the entry from the list */
|
||||
ExAcquireFastMutex(&DeviceExtension->Lock);
|
||||
RemoveEntryList(&BatteryData->BatteryLink);
|
||||
ExReleaseFastMutex(&DeviceExtension->Lock);
|
||||
return BatteryData;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
ExReleaseFastMutex(&DeviceExtension->Lock);
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
IsBatteryAlreadyOnList(
|
||||
_In_ PCUNICODE_STRING BatteryName,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PLIST_ENTRY ListHead, NextEntry;
|
||||
PCOMPBATT_BATTERY_DATA BatteryData;
|
||||
BOOLEAN Found = FALSE;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE)
|
||||
DbgPrint("CompBatt: ENTERING IsBatteryAlreadyOnList\n");
|
||||
|
||||
/* Loop the battery list */
|
||||
ExAcquireFastMutex(&DeviceExtension->Lock);
|
||||
ListHead = &DeviceExtension->BatteryList;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the battery information and compare the name */
|
||||
BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
|
||||
if (!RtlCompareUnicodeString(BatteryName, &BatteryData->BatteryName, TRUE))
|
||||
{
|
||||
/* Got it */
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* Release the lock and return search status */
|
||||
ExReleaseFastMutex(&DeviceExtension->Lock);
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING IsBatteryAlreadyOnList\n");
|
||||
return Found;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattAddNewBattery(
|
||||
_In_ PUNICODE_STRING BatteryName,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PCOMPBATT_BATTERY_DATA BatteryData;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PFILE_OBJECT FileObject;
|
||||
PAGED_CODE();
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN)
|
||||
DbgPrint("CompBatt: ENTERING AddNewBattery \"%w\" \n", BatteryName->Buffer);
|
||||
|
||||
/* Is this a new battery? */
|
||||
if (!IsBatteryAlreadyOnList(BatteryName, DeviceExtension))
|
||||
{
|
||||
/* Allocate battery data */
|
||||
BatteryData = ExAllocatePoolWithTag(NonPagedPool,
|
||||
sizeof(COMPBATT_BATTERY_DATA) +
|
||||
BatteryName->Length,
|
||||
'CtaB');
|
||||
if (BatteryData)
|
||||
{
|
||||
/* Initialize the data and write the battery name */
|
||||
RtlZeroMemory(BatteryData, sizeof(COMPBATT_BATTERY_DATA));
|
||||
BatteryData->Tag = BATTERY_TAG_INVALID;
|
||||
BatteryData->BatteryName.MaximumLength = BatteryName->Length;
|
||||
BatteryData->BatteryName.Buffer = (PWCHAR)(BatteryData + 1);
|
||||
RtlCopyUnicodeString(&BatteryData->BatteryName, BatteryName);
|
||||
|
||||
/* Get the device object */
|
||||
Status = CompBattGetDeviceObjectPointer(BatteryName,
|
||||
FILE_ALL_ACCESS,
|
||||
&FileObject,
|
||||
&BatteryData->DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Reference the DO and drop the FO */
|
||||
ObReferenceObject(BatteryData->DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
/* Allocate the battery IRP */
|
||||
Irp = IoAllocateIrp(BatteryData->DeviceObject->StackSize + 1, 0);
|
||||
if (Irp)
|
||||
{
|
||||
/* Save it */
|
||||
BatteryData->Irp = Irp;
|
||||
|
||||
/* Setup the stack location */
|
||||
IoStackLocation = IoGetNextIrpStackLocation(Irp);
|
||||
IoStackLocation->Parameters.Others.Argument1 = DeviceExtension;
|
||||
IoStackLocation->Parameters.Others.Argument2 = BatteryData;
|
||||
|
||||
/* Set IRP data */
|
||||
IoSetNextIrpStackLocation(Irp);
|
||||
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||
|
||||
/* Insert this battery in the list */
|
||||
ExAcquireFastMutex(&DeviceExtension->Lock);
|
||||
InsertTailList(&DeviceExtension->BatteryList,
|
||||
&BatteryData->BatteryLink);
|
||||
ExReleaseFastMutex(&DeviceExtension->Lock);
|
||||
|
||||
/* Initialize the work item and delete lock */
|
||||
IoInitializeRemoveLock(&BatteryData->RemoveLock, COMPBATT_TAG, 0, 0);
|
||||
ExInitializeWorkItem(&BatteryData->WorkItem,
|
||||
(PVOID)CompBattMonitorIrpCompleteWorker,
|
||||
BatteryData);
|
||||
|
||||
/* Setup the IRP work entry */
|
||||
CompBattMonitorIrpComplete(BatteryData->DeviceObject, Irp, NULL);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fail, no memory */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
DbgPrint("CompBatt: Couldn't allocate new battery Irp\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
ObDereferenceObject(BatteryData->DeviceObject);
|
||||
}
|
||||
}
|
||||
else if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("CompBattAddNewBattery: Failed to get device Object. status = %lx\n",
|
||||
Status);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Free the battery data */
|
||||
ExFreePool(BatteryData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fail, no memory */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
DbgPrint("CompBatt: Couldn't allocate new battery node\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
/* We're done */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING AddNewBattery\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattRemoveBattery(
|
||||
_In_ PUNICODE_STRING BatteryName,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PCOMPBATT_BATTERY_DATA BatteryData;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: RemoveBattery\n");
|
||||
|
||||
/* Remove the entry */
|
||||
BatteryData = RemoveBatteryFromList(BatteryName, DeviceExtension);
|
||||
if (BatteryData)
|
||||
{
|
||||
/* Dereference and free it */
|
||||
ObDereferenceObject(BatteryData->DeviceObject);
|
||||
ExFreePool(BatteryData);
|
||||
|
||||
/* Notify class driver */
|
||||
DeviceExtension->Flags = 0;
|
||||
BatteryClassStatusNotify(DeviceExtension->ClassData);
|
||||
}
|
||||
|
||||
/* It's done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattGetBatteries(
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PWCHAR p;
|
||||
NTSTATUS Status;
|
||||
PWCHAR LinkList;
|
||||
UNICODE_STRING LinkString;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING GetBatteries\n");
|
||||
|
||||
/* Get all battery links */
|
||||
Status = IoGetDeviceInterfaces(&GUID_DEVICE_BATTERY, NULL, 0, &LinkList);
|
||||
p = LinkList;
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Loop all strings inside */
|
||||
while (TRUE)
|
||||
{
|
||||
/* Create the string */
|
||||
RtlInitUnicodeString(&LinkString, p);
|
||||
if (!LinkString.Length) break;
|
||||
|
||||
/* Add this battery and move on */
|
||||
Status = CompBattAddNewBattery(&LinkString, DeviceExtension);
|
||||
p += (LinkString.Length / sizeof(WCHAR)) + sizeof(UNICODE_NULL);
|
||||
}
|
||||
|
||||
/* Parsing complete, clean up buffer */
|
||||
ExFreePool(LinkList);
|
||||
}
|
||||
else if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("CompBatt: Couldn't get list of batteries\n");
|
||||
}
|
||||
|
||||
/* Done */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING GetBatteries\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattPnpEventHandler(
|
||||
_In_ PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification,
|
||||
_In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING PnpEventHandler\n");
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received device interface change notification\n");
|
||||
|
||||
/* Check what happened */
|
||||
if (IsEqualGUIDAligned(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL))
|
||||
{
|
||||
/* Add the new battery */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN)
|
||||
DbgPrint("CompBatt: Received notification of battery arrival\n");
|
||||
CompBattAddNewBattery(Notification->SymbolicLinkName, DeviceExtension);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL))
|
||||
{
|
||||
/* Don't do anything */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN)
|
||||
DbgPrint("CompBatt: Received notification of battery removal\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received unhandled PnP event\n");
|
||||
}
|
||||
|
||||
/* Done, return success */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING PnpEventHandler\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattAddDevice(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PDEVICE_OBJECT PdoDeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DeviceName;
|
||||
PCOMPBATT_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING SymbolicLinkName;
|
||||
BATTERY_MINIPORT_INFO MiniportInfo;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject);
|
||||
|
||||
/* Create the device */
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\CompositeBattery");
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(COMPBATT_DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_BATTERY,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Setup symbolic link for Win32 access */
|
||||
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\CompositeBattery");
|
||||
IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
|
||||
|
||||
/* Initialize the device extension */
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(COMPBATT_DEVICE_EXTENSION));
|
||||
|
||||
/* Attach to device stack and set DO pointers */
|
||||
DeviceExtension->AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||
PdoDeviceObject);
|
||||
DeviceExtension->DeviceObject = DeviceObject;
|
||||
if (!DeviceExtension->AttachedDevice)
|
||||
{
|
||||
/* Fail */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
DbgPrint("CompBattAddDevice: Could not attach to LowerDevice.\n");
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Set device object flags */
|
||||
DeviceObject->Flags |= (DO_POWER_PAGABLE | DO_BUFFERED_IO);
|
||||
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
/* Setup the device extension */
|
||||
ExInitializeFastMutex(&DeviceExtension->Lock);
|
||||
InitializeListHead(&DeviceExtension->BatteryList);
|
||||
DeviceExtension->Flags = 0;
|
||||
DeviceExtension->NextTag = 1;
|
||||
|
||||
/* Setup the miniport data */
|
||||
RtlZeroMemory(&MiniportInfo, sizeof(MiniportInfo));
|
||||
MiniportInfo.MajorVersion = BATTERY_CLASS_MAJOR_VERSION;
|
||||
MiniportInfo.MinorVersion = BATTERY_CLASS_MINOR_VERSION;
|
||||
MiniportInfo.Context = DeviceExtension;
|
||||
MiniportInfo.DeviceName = &DeviceName;
|
||||
MiniportInfo.QueryTag = (BCLASS_QUERY_TAG)CompBattQueryTag;
|
||||
MiniportInfo.QueryInformation = (BCLASS_QUERY_INFORMATION)CompBattQueryInformation;
|
||||
MiniportInfo.SetInformation = NULL;
|
||||
MiniportInfo.QueryStatus = (BCLASS_QUERY_STATUS)CompBattQueryStatus;
|
||||
MiniportInfo.SetStatusNotify = (BCLASS_SET_STATUS_NOTIFY)CompBattSetStatusNotify;
|
||||
MiniportInfo.DisableStatusNotify = (BCLASS_DISABLE_STATUS_NOTIFY)CompBattDisableStatusNotify;
|
||||
MiniportInfo.Pdo = NULL;
|
||||
|
||||
/* Register with the class driver */
|
||||
Status = BatteryClassInitializeDevice(&MiniportInfo,
|
||||
&DeviceExtension->ClassData);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Undo everything */
|
||||
IoDetachDevice(DeviceExtension->AttachedDevice);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CompBattPnpDispatch(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS Status;
|
||||
PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING PnpDispatch\n");
|
||||
|
||||
/* Set default error */
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* Check what kind of PnP function this is */
|
||||
switch (IoStackLocation->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
|
||||
/* Device is starting, register for new batteries and pick up current ones */
|
||||
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
||||
0,
|
||||
(PVOID)&GUID_DEVICE_BATTERY,
|
||||
DeviceObject->DriverObject,
|
||||
(PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)CompBattPnpEventHandler,
|
||||
DeviceExtension,
|
||||
&DeviceExtension->NotificationEntry);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Now go get the batteries */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_WARN)
|
||||
DbgPrint("CompBatt: Successfully registered for PnP notification\n");
|
||||
Status = CompBattGetBatteries(DeviceExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We failed */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_ERR)
|
||||
DbgPrint("CompBatt: Couldn't register for PnP notification - %x\n",
|
||||
Status);
|
||||
}
|
||||
break;
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
|
||||
/* Explicitly say ok */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
|
||||
/* Explicitly say ok */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
|
||||
/* Explicitly say ok */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
|
||||
/* Add this in */
|
||||
Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Not supported */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set IRP status if we have one */
|
||||
if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
|
||||
|
||||
/* Did someone pick it up? */
|
||||
if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))
|
||||
{
|
||||
/* Still unsupported, try ACPI */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Complete the request */
|
||||
Status = Irp->IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
/* Release the remove lock and return status */
|
||||
if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING PnpDispatch\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
8
drivers/battery/compbatt/guid.c
Normal file
8
drivers/battery/compbatt/guid.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
|
||||
|
||||
#include <wdm.h>
|
||||
#include <initguid.h>
|
||||
#include <wdmguid.h>
|
||||
#include <batclass.h>
|
||||
|
||||
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
|
Loading…
Add table
Add a link
Reference in a new issue