From dd3eb6e798b3f7716726c6d9433e55b8ea87d308 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Fri, 19 Mar 2010 18:17:32 +0000 Subject: [PATCH] [CMBATT]: Driver Entrypoint, Create/Close handler, and Unload handler. svn path=/trunk/; revision=46275 --- reactos/drivers/bus/acpi/cmbatt/cmbatt.c | 187 +++++++++++++++++++++-- reactos/drivers/bus/acpi/cmbatt/cmbatt.h | 28 ++++ reactos/drivers/bus/acpi/cmbatt/cmbpnp.c | 6 +- reactos/drivers/bus/acpi/cmbatt/cmbwmi.c | 3 +- 4 files changed, 209 insertions(+), 15 deletions(-) diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbatt.c b/reactos/drivers/bus/acpi/cmbatt/cmbatt.c index 1957597a678..b8c59739d4e 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbatt.c +++ b/reactos/drivers/bus/acpi/cmbatt/cmbatt.c @@ -13,7 +13,12 @@ /* GLOBALS ********************************************************************/ ULONG CmBattDebug; - +PCALLBACK_OBJECT CmBattPowerCallBackObject; +PVOID CmBattPowerCallBackRegistration; +UNICODE_STRING GlobalRegistryPath; +KTIMER CmBattWakeDpcTimerObject; +KDPC CmBattWakeDpcObject; + /* FUNCTIONS ******************************************************************/ VOID @@ -32,7 +37,7 @@ CmBattWakeDpc(PKDPC Dpc, PVOID SystemArgument1, PVOID SystemArgument2) { - UNIMPLEMENTED; + } VOID @@ -45,9 +50,26 @@ CmBattNotifyHandler(PCMBATT_DEVICE_EXTENSION DeviceExtension, VOID NTAPI -CmBattUnload(PDEVICE_OBJECT DeviceObject) +CmBattUnload(IN PDRIVER_OBJECT DriverObject) { - UNIMPLEMENTED; + if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattUnload: \n"); + + /* Check if we have a registered power callback */ + if (CmBattPowerCallBackObject) + { + /* Get rid of it */ + ExUnregisterCallback(CmBattPowerCallBackRegistration); + ObfDereferenceObject(CmBattPowerCallBackObject); + } + + /* Free the registry buffer if it exists */ + if (GlobalRegistryPath.Buffer) ExFreePool(GlobalRegistryPath.Buffer); + + /* Make sure we don't still have references to the DO */ + if ((DriverObject->DeviceObject) && (CmBattDebug & CMBATT_GENERIC_WARNING)) + { + DbgPrint("Unload called before all devices removed.\n"); + } } NTSTATUS @@ -61,11 +83,65 @@ CmBattVerifyStaticInfo(ULONG StaData, NTSTATUS NTAPI -CmBattOpenClose(PDEVICE_OBJECT DeviceObject, - PIRP Irp) +CmBattOpenClose(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION IoStackLocation; + UCHAR Major; + ULONG Count; + PCMBATT_DEVICE_EXTENSION DeviceExtension; + PAGED_CODE(); + if (CmBattDebug & CMBATT_GENERIC_INFO) DPRINT("CmBattOpenClose\n"); + + /* Grab the device extension and lock it */ + DeviceExtension = DeviceObject->DeviceExtension; + ExAcquireFastMutex(&DeviceExtension->FastMutex); + + /* Check if someone is trying to open a device that doesn't exist yet */ + Count = DeviceExtension->HandleCount; + if (Count == 0xFFFFFFFF) + { + /* Fail the request */ + Status = STATUS_NO_SUCH_DEVICE; + if (CmBattDebug & CMBATT_PNP_INFO) + { + DbgPrint("CmBattOpenClose: Failed (UID = %x)(device being removed).\n", + DeviceExtension->Tag); + } + goto Complete; + } + + /* Check if this is an open or close */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + Major = IoStackLocation->MajorFunction; + if (Major == IRP_MJ_CREATE) + { + /* Increment the open count */ + DeviceExtension->HandleCount = Count + 1; + if (CmBattDebug & CMBATT_PNP_INFO) + { + DbgPrint("CmBattOpenClose: Open (DeviceNumber = %x)(count = %x).\n", + DeviceExtension->DeviceId, Count + 1); + } + } + else if (Major == IRP_MJ_CLOSE) + { + /* Decrement the open count */ + DeviceExtension->HandleCount = Count - 1; + if (CmBattDebug & CMBATT_PNP_INFO) + { + DbgPrint("CmBattOpenClose: Close (DeviceNumber = %x)(count = %x).\n", + DeviceExtension->DeviceId, Count + 1); + } + } + +Complete: + /* Release lock and complete request */ + ExReleaseFastMutex(&DeviceExtension->FastMutex); + Irp->IoStatus.Status = Status; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } NTSTATUS @@ -139,11 +215,98 @@ CmBattQueryStatus(PCMBATT_DEVICE_EXTENSION DeviceExtension, NTSTATUS NTAPI -DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PDRIVER_EXTENSION DriverExtension; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING CallbackName; + + /* Allocate registry path */ + GlobalRegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); + GlobalRegistryPath.Length = RegistryPath->Length; + GlobalRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, + GlobalRegistryPath.MaximumLength, + 'MtaB'); + if (!GlobalRegistryPath.Buffer) + { + /* Fail if we're out of memory this early */ + if (CmBattDebug & CMBATT_GENERIC_WARNING) + { + DbgPrint("CmBatt: Couldn't allocate pool for registry path."); + } + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Buffer allocated, copy the string */ + RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath); + if (CmBattDebug & CMBATT_GENERIC_INFO) + { + DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%ws\"\n", + DriverObject, + RegistryPath->Buffer); + } + + /* Setup the major dispatchers */ + DriverObject->MajorFunction[0] = CmBattOpenClose; + DriverObject->MajorFunction[2] = CmBattOpenClose; + DriverObject->MajorFunction[14] = CmBattIoctl; + DriverObject->MajorFunction[22] = CmBattPowerDispatch; + DriverObject->MajorFunction[27] = CmBattPnpDispatch; + DriverObject->MajorFunction[23] = CmBattSystemControl; + + /* And the unload routine */ + DriverObject->DriverUnload = CmBattUnload; + + /* And the add device routine */ + DriverExtension = DriverObject->DriverExtension; + DriverExtension->AddDevice = CmBattAddDevice; + + /* Create a power callback */ + RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState"); + InitializeObjectAttributes(&ObjectAttributes, + &CallbackName, + OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ExCreateCallback(&CmBattPowerCallBackObject, &ObjectAttributes, 0, TRUE); + if (!NT_SUCCESS(Status)) + { + /* No callback, fail */ + CmBattPowerCallBackObject = 0; + if (CmBattDebug & CMBATT_GENERIC_WARNING) + { + DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status); + } + } + else + { + /* Register the power callback now */ + CmBattPowerCallBackRegistration = ExRegisterCallback(CmBattPowerCallBackObject, + (PVOID)CmBattPowerCallBack, + DriverObject); + if (CmBattPowerCallBackRegistration) + { + /* Last thing: setup our DPC and timer for battery wake */ + KeInitializeDpc(&CmBattWakeDpcObject, (PVOID)CmBattWakeDpc, DriverObject); + KeInitializeTimer(&CmBattWakeDpcTimerObject); + } + else + { + ObfDereferenceObject(CmBattPowerCallBackObject); + if (CmBattDebug & CMBATT_GENERIC_WARNING) + { + DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n"); + } + } + + /* All good */ + Status = STATUS_SUCCESS; + } + + /* Return failure or success */ + return Status; } /* EOF */ diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbatt.h b/reactos/drivers/bus/acpi/cmbatt/cmbatt.h index 0443c4c86bb..f3583f8dd1b 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbatt.h +++ b/reactos/drivers/bus/acpi/cmbatt/cmbatt.h @@ -101,5 +101,33 @@ typedef struct _CMBATT_DEVICE_EXTENSION ULONG TripPointOld; ULONGLONG InterruptTime; } CMBATT_DEVICE_EXTENSION, *PCMBATT_DEVICE_EXTENSION; + +NTSTATUS +NTAPI +CmBattPowerDispatch( + PDEVICE_OBJECT DeviceObject, + PIRP Irp +); + +NTSTATUS +NTAPI +CmBattPnpDispatch( + PDEVICE_OBJECT DeviceObject, + PIRP Irp +); + +NTSTATUS +NTAPI +CmBattAddDevice( + PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT DeviceObject +); + +NTSTATUS +NTAPI +CmBattSystemControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp +); /* EOF */ diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbpnp.c b/reactos/drivers/bus/acpi/cmbatt/cmbpnp.c index fee3ec80b47..3a56dce87f0 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbpnp.c +++ b/reactos/drivers/bus/acpi/cmbatt/cmbpnp.c @@ -94,8 +94,10 @@ CmBattAddAcAdapter(PDRIVER_OBJECT DriverObject, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS NTAPI CmBattAddDevice(PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT DeviceObject) +NTSTATUS +NTAPI +CmBattAddDevice(PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT DeviceObject) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; diff --git a/reactos/drivers/bus/acpi/cmbatt/cmbwmi.c b/reactos/drivers/bus/acpi/cmbatt/cmbwmi.c index 848c920dd0b..3609e17d5ff 100644 --- a/reactos/drivers/bus/acpi/cmbatt/cmbwmi.c +++ b/reactos/drivers/bus/acpi/cmbatt/cmbwmi.c @@ -85,7 +85,8 @@ CmBattWmiRegistration(PCMBATT_DEVICE_EXTENSION DeviceExtension) NTSTATUS NTAPI -CmBattSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) +CmBattSystemControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;