[CMBATT]: Driver Entrypoint, Create/Close handler, and Unload handler.
authorSir Richard <sir_richard@svn.reactos.org>
Fri, 19 Mar 2010 18:17:32 +0000 (18:17 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Fri, 19 Mar 2010 18:17:32 +0000 (18:17 +0000)
svn path=/trunk/; revision=46275

reactos/drivers/bus/acpi/cmbatt/cmbatt.c
reactos/drivers/bus/acpi/cmbatt/cmbatt.h
reactos/drivers/bus/acpi/cmbatt/cmbpnp.c
reactos/drivers/bus/acpi/cmbatt/cmbwmi.c

index 1957597..b8c5973 100644 (file)
 /* 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 */
index 0443c4c..f3583f8 100644 (file)
@@ -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 */
index fee3ec8..3a56dce 100644 (file)
@@ -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;
index 848c920..3609e17 100644 (file)
@@ -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;