Author: sir_richard
Date: Mon Mar 29 02:02:05 2010
New Revision: 46540
URL:
http://svn.reactos.org/svn/reactos?rev=46540&view=rev
Log:
[COMPBATT]: Main battery detection/PnP notification logic: CompBattAddNewBattery,
CompBattRemoveBattery, IsBatteryAlreadyOnList, RemoveBatteryFromList,
CompBattGetBatteries, CompBattPnpEventHandler.
Modified:
trunk/reactos/drivers/bus/acpi/compbatt/compbatt.c
trunk/reactos/drivers/bus/acpi/compbatt/compbatt.h
trunk/reactos/drivers/bus/acpi/compbatt/comppnp.c
Modified: trunk/reactos/drivers/bus/acpi/compbatt/compbatt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/compbatt/…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/compbatt/compbatt.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/compbatt/compbatt.c [iso-8859-1] Mon Mar 29 02:02:05
2010
@@ -27,7 +27,7 @@
/* Complete the IRP with success */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Return success */
if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n");
@@ -56,7 +56,7 @@
/* We don't support WMI */
Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
/* Return status */
@@ -75,7 +75,7 @@
NTSTATUS
NTAPI
-CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_ENTRY BatteryData)
+CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_DATA BatteryData)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
Modified: trunk/reactos/drivers/bus/acpi/compbatt/compbatt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/compbatt/…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/compbatt/compbatt.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/compbatt/compbatt.h [iso-8859-1] Mon Mar 29 02:02:05
2010
@@ -10,8 +10,9 @@
#include <initguid.h>
#include <batclass.h>
#include <debug.h>
+#include <wdmguid.h>
-typedef struct _COMPBATT_BATTERY_ENTRY
+typedef struct _COMPBATT_BATTERY_DATA
{
LIST_ENTRY BatteryLink;
IO_REMOVE_LOCK RemoveLock;
@@ -31,7 +32,7 @@
BATTERY_STATUS BatteryStatus;
ULONGLONG InterruptTime;
UNICODE_STRING BatteryName;
-} COMPBATT_BATTERY_ENTRY, *PCOMPBATT_BATTERY_ENTRY;
+} COMPBATT_BATTERY_DATA, *PCOMPBATT_BATTERY_DATA;
typedef struct _COMPBATT_DEVICE_EXTENSION
{
@@ -114,6 +115,29 @@
OUT PULONG Tag
);
+NTSTATUS
+NTAPI
+CompBattMonitorIrpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PKEVENT Event
+);
+
+NTSTATUS
+NTAPI
+CompBattMonitorIrpCompleteWorker(
+ IN PCOMPBATT_BATTERY_DATA BatteryData
+);
+
+NTSTATUS
+NTAPI
+CompBattGetDeviceObjectPointer(
+ IN PCUNICODE_STRING DeviceName,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PFILE_OBJECT *FileObject,
+ OUT PDEVICE_OBJECT *DeviceObject
+);
+
extern ULONG CompBattDebug;
/* EOF */
Modified: trunk/reactos/drivers/bus/acpi/compbatt/comppnp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/compbatt/…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/compbatt/comppnp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/compbatt/comppnp.c [iso-8859-1] Mon Mar 29 02:02:05
2010
@@ -28,13 +28,43 @@
return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
}
-PCOMPBATT_BATTERY_ENTRY
+PCOMPBATT_BATTERY_DATA
NTAPI
RemoveBatteryFromList(IN PCUNICODE_STRING BatteryName,
IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- return NULL;
+ PLIST_ENTRY ListHead, NextEntry;
+ PCOMPBATT_BATTERY_DATA BatteryData;
+ if (CompBattDebug & 1)
+ 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;
+ }
+ }
+
+ /* Done */
+ ExReleaseFastMutex(&DeviceExtension->Lock);
+ if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING
RemoveBatteryFromList\n");
+ return STATUS_SUCCESS;
}
BOOLEAN
@@ -42,8 +72,32 @@
IsBatteryAlreadyOnList(IN PCUNICODE_STRING BatteryName,
IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- return FALSE;
+ PLIST_ENTRY ListHead, NextEntry;
+ PCOMPBATT_BATTERY_DATA BatteryData;
+ BOOLEAN Found = FALSE;
+ if (CompBattDebug & 1)
+ 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;
+ }
+ }
+
+ /* Release the lock and return search status */
+ ExReleaseFastMutex(&DeviceExtension->Lock);
+ if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING
IsBatteryAlreadyOnList\n");
+ return Found;
}
NTSTATUS
@@ -51,8 +105,107 @@
CompBattAddNewBattery(IN PCUNICODE_STRING BatteryName,
IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PCOMPBATT_BATTERY_DATA BatteryData;
+ PIRP Irp;
+ PIO_STACK_LOCATION IoStackLocation;
+ PFILE_OBJECT FileObject;
+ PAGED_CODE();
+ if (CompBattDebug & 1)
+ 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 = 0;
+ 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 */
+ ObfReferenceObject(BatteryData->DeviceObject);
+ ObfDereferenceObject(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;
+ BatteryData->WaitFlag = 0;
+
+ /* 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, 0, 0, 0);
+ ExInitializeWorkItem(&BatteryData->WorkItem,
+ (PVOID)CompBattMonitorIrpCompleteWorker,
+ BatteryData);
+
+ /* Setup the IRP work entry */
+ CompBattMonitorIrpComplete(BatteryData->DeviceObject, Irp, 0);
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Fail, no memory */
+ if (CompBattDebug & 8)
+ DbgPrint("CompBatt: Couldn't allocate new battery
Irp\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ ObfDereferenceObject(BatteryData->DeviceObject);
+ }
+ }
+ else if (CompBattDebug & 8)
+ {
+ /* Fail */
+ DbgPrint("CompBattAddNewBattery: Failed to get device Object. status
= %lx\n",
+ Status);
+ }
+
+ /* Free the battery data */
+ ExFreePool(BatteryData);
+ }
+ else
+ {
+ /* Fail, no memory */
+ if (CompBattDebug & 8)
+ DbgPrint("CompBatt: Couldn't allocate new battery
node\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ /* We're done */
+ if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING AddNewBattery\n");
+ return Status;
}
NTSTATUS
@@ -60,16 +213,65 @@
CompBattRemoveBattery(IN PCUNICODE_STRING BatteryName,
IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PCOMPBATT_BATTERY_DATA BatteryData;
+ if (CompBattDebug & 1) DbgPrint("CompBatt: RemoveBattery\n");
+
+ /* Remove the entry */
+ BatteryData = RemoveBatteryFromList(BatteryName, DeviceExtension);
+ if (BatteryData)
+ {
+ /* Dereference and free it */
+ ObfDereferenceObject(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)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PWCHAR p;
+ NTSTATUS Status;
+ PWCHAR LinkList;
+ UNICODE_STRING LinkString;
+ if (CompBattDebug & 1) 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 & 8)
+ {
+ /* Fail */
+ DbgPrint("CompBatt: Couldn't get list of batteries\n");
+ }
+
+ /* Done */
+ if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteries\n");
+ return Status;
}
NTSTATUS
@@ -77,8 +279,32 @@
CompBattPnpEventHandler(IN PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification,
IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING
PnpEventHandler\n");
+ if (CompBattDebug & 2) 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 & 2)
+ 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 & 2)
+ DbgPrint("CompBatt: Received notification of battery removal\n");
+ }
+ else
+ {
+ /* Shouldn't happen */
+ if (CompBattDebug & 2) DbgPrint("CompBatt: Received unhandled PnP
event\n");
+ }
+
+ /* Done, return success */
+ if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING
PnpEventHandler\n");
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -251,7 +477,7 @@
{
/* Complete the request */
Status = Irp->IoStatus.Status;
- IofCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
/* Release the remove lock and return status */