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/c... ============================================================================== --- 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/c... ============================================================================== --- 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/c... ============================================================================== --- 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 */