⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbbatt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    smbbatt.c

Abstract:

    SMBus Smart Battery Subsystem Miniport Driver
    (Selector, Battery, Charger)

Author:

    Ken Reneris

Environment:

Notes:


Revision History:

    Chris Windle    1/27/98     Bug Fixes

--*/

#include "smbbattp.h"

#include <initguid.h>
#include <batclass.h>



#if DEBUG
ULONG   SMBBattDebug = BAT_WARN | BAT_ERROR | BAT_BIOS_ERROR;
#endif

// Global
BOOLEAN   SmbBattUseGlobalLock = TRUE;
UNICODE_STRING GlobalRegistryPath;

//
// Prototypes
//


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
);

NTSTATUS
SmbBattNewDevice (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PDO
);

NTSTATUS
SmbBattQueryTag (
    IN PVOID Context,
    OUT PULONG BatteryTag
);

NTSTATUS
SmbBattQueryInformation (
    IN PVOID Context,
    IN ULONG BatteryTag,
    IN BATTERY_QUERY_INFORMATION_LEVEL Level,
    IN LONG AtRate OPTIONAL,
    OUT PVOID Buffer,
    IN  ULONG BufferLength,
    OUT PULONG ReturnedLength
);

NTSTATUS
SmbBattSetStatusNotify (
    IN PVOID Context,
    IN ULONG BatteryTag,
    IN PBATTERY_NOTIFY BatteryNotify
);

NTSTATUS
SmbBattDisableStatusNotify (
    IN PVOID Context
);

NTSTATUS
SmbBattQueryStatus (
    IN PVOID Context,
    IN ULONG BatteryTag,
    OUT PBATTERY_STATUS BatteryStatus
);

NTSTATUS
SmbBattCreate(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

NTSTATUS
SmbBattClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

NTSTATUS
SmbBattIoctl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

VOID
SmbBattUnload(
    IN PDRIVER_OBJECT DriverObject
);

VOID
SmbBattProcessSelectorAlarm (
    IN PSMB_BATT_SUBSYSTEM  SubsystemExt,
    IN ULONG                OldSelectorState,
    IN ULONG                NewSelectorState
);

NTSTATUS
SmbBattGetPowerState (
    IN PSMB_BATT        SmbBatt,
    OUT PULONG          PowerState,
    OUT PLONG           Current
);

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,SmbBattNewDevice)
#pragma alloc_text(PAGE,SmbBattUnload)
#pragma alloc_text(PAGE,SmbBattCreate)
#pragma alloc_text(PAGE,SmbBattClose)
#pragma alloc_text(PAGE,SmbBattIoctl)
#pragma alloc_text(PAGE,SmbBattQueryTag)
#pragma alloc_text(PAGE,SmbBattQueryInformation)
#pragma alloc_text(PAGE,SmbBattSetInformation)
#pragma alloc_text(PAGE,SmbBattGetPowerState)
#pragma alloc_text(PAGE,SmbBattQueryStatus)
#pragma alloc_text(PAGE,SmbBattSetStatusNotify)
#pragma alloc_text(PAGE,SmbBattDisableStatusNotify)
#endif



NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine initializes the Smart Battery Driver

Arguments:

    DriverObject - Pointer to driver object created by system.

    RegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

    The function value is the final status from the initialization operation.

--*/
{
    OBJECT_ATTRIBUTES   objAttributes;

    BattPrint(BAT_TRACE, ("SmbBatt: DriverEntry\n"));

    //
    // Save the RegistryPath.
    //

    GlobalRegistryPath.MaximumLength = RegistryPath->Length +
                                          sizeof(UNICODE_NULL);
    GlobalRegistryPath.Length = RegistryPath->Length;
    GlobalRegistryPath.Buffer = ExAllocatePoolWithTag (
                                       PagedPool,
                                       GlobalRegistryPath.MaximumLength,
                                       'StaB');

    if (!GlobalRegistryPath.Buffer) {

        BattPrint ((BAT_ERROR),("SmbBatt: Couldn't allocate pool for registry path."));

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath);

    BattPrint (BAT_TRACE, ("SmbBatt DriverEntry - Obj (%08x) Path \"%ws\"\n",
                                 DriverObject, RegistryPath->Buffer));
    
    
    DriverObject->DriverUnload                          = SmbBattUnload;
    DriverObject->DriverExtension->AddDevice            = SmbBattNewDevice;

    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = SmbBattIoctl;
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = SmbBattCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = SmbBattClose;

    DriverObject->MajorFunction[IRP_MJ_PNP]             = SmbBattPnpDispatch;
    DriverObject->MajorFunction[IRP_MJ_POWER]           = SmbBattPowerDispatch;

    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]  = SmbBattSystemControl;
    return STATUS_SUCCESS;
}



NTSTATUS
SmbBattNewDevice (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PDO
    )

/*++

Routine Description:

    This creates a smb smart battery functional device objects.  The first
    object created will be the one for the "smart battery subsystem" which will
    have a PDO from ACPI.  This will receive a START Irp, then a
    QUERY_DEVICE_RELATIONS Irp.  In the QUERY it will create PDOs for the
    batteries that are supported by the system and eventually they will end
    up here for FDOs to be created and attached to them.

Arguments:

    DriverObject - Pointer to driver object created by system.

    PDO          - PDO for the new device(s)

Return Value:

    Status

--*/
{
    PDEVICE_OBJECT          fdo;
    PSMB_BATT_SUBSYSTEM     subsystemExt;
    PSMB_BATT_PDO           pdoExt;

    PSMB_NP_BATT            SmbNPBatt;
    PSMB_BATT               SmbBatt;
    BATTERY_MINIPORT_INFO   BattInit;

    NTSTATUS                status              = STATUS_UNSUCCESSFUL;
    BOOLEAN                 selectorPresent     = FALSE;

    PAGED_CODE();

    BattPrint(BAT_IRPS, ("SmbBattNewDevice: AddDevice for device %x\n", PDO));

    //
    // Check to see if we are being asked to enumerate ourself
    //

    if (PDO == NULL) {
        BattPrint(BAT_ERROR, ("SmbBattNewDevice: Being asked to enumerate\n"));
        return STATUS_NOT_IMPLEMENTED;
    }


    //
    // Check to see if the PDO is the battery subsystem PDO or a battery PDO.  This will be
    // determined by the PDO's DeviceType.
    //
    // FILE_DEVICE_ACPI     This PDO is from ACPI and belongs to battery subsystem
    // FILE_DEVICE_BATTERY  This PDO is a battery PDO
    //

    if (PDO->DeviceType == FILE_DEVICE_ACPI) {

        //
        // Create the device object
        //

        status = IoCreateDevice(
                    DriverObject,
                    sizeof (SMB_BATT_SUBSYSTEM),
                    NULL,
                    FILE_DEVICE_BATTERY,
                    FILE_DEVICE_SECURE_OPEN,
                    FALSE,
                    &fdo
                );

        if (status != STATUS_SUCCESS) {
            BattPrint(BAT_ERROR, ("SmbBattNewDevice: error creating Fdo for battery subsystem %x\n", status));
            return(status);
        }


        //
        // Initialize the Fdo
        //

        fdo->Flags |= DO_BUFFERED_IO;
        fdo->Flags |= DO_POWER_PAGABLE;

        //
        // Initialize the extension
        //

        subsystemExt = (PSMB_BATT_SUBSYSTEM)fdo->DeviceExtension;
        RtlZeroMemory (subsystemExt, sizeof (PSMB_BATT_SUBSYSTEM));

        subsystemExt->DeviceObject = fdo;
        subsystemExt->SmbBattFdoType = SmbTypeSubsystem;
        IoInitializeRemoveLock (&subsystemExt->RemoveLock,
                                SMB_BATTERY_TAG,
                                REMOVE_LOCK_MAX_LOCKED_MINUTES,
                                REMOVE_LOCK_HIGH_WATER_MARK);

        //
        // These fields are implicitly initialize by zeroing the extension
        //
        //         subsystemExt->NumberOfBatteries = 0;
        //         subsystemExt->SelectorPresent   = FALSE;
        //         subsystemExt->Selector          = NULL;
        //         subsystemExt->WorkerActive      = 0;


        KeInitializeSpinLock (&subsystemExt->AlarmListLock);
        InitializeListHead (&subsystemExt->AlarmList);
        subsystemExt->WorkerThread = IoAllocateWorkItem (fdo);


        //
        // Layer our FDO on top of the ACPI PDO.
        //

        subsystemExt->LowerDevice = IoAttachDeviceToDeviceStack (fdo,PDO);
        
        if (!subsystemExt->LowerDevice) {
            BattPrint(BAT_ERROR, ("SmbBattNewDevice: Error attaching subsystem to device stack.\n"));

            IoDeleteDevice (fdo);

            return(status);

        }


        //
        // Zero out the battery PDO list
        //  This is already zeroed by the RtlZeroMemory above.
        //
        //  RtlZeroMemory(
        //      &subsystemExt->BatteryPdoList[0],
        //      sizeof(PDEVICE_OBJECT) * MAX_SMART_BATTERIES_SUPPORTED
        //  );


        //
        // Device is ready for use
        //
        
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;


    } else {

        //
        // This is a battery PDO.  Create the FDO to layer on top of it.
        //

        pdoExt       = (PSMB_BATT_PDO) PDO->DeviceExtension;
        subsystemExt = (PSMB_BATT_SUBSYSTEM) pdoExt->SubsystemFdo->DeviceExtension;

        //
        // Allocate space for the paged portion of the device extension
        //

        SmbBatt = ExAllocatePoolWithTag (PagedPool, sizeof(SMB_BATT), SMB_BATTERY_TAG);
        if (!SmbBatt) {
            BattPrint(BAT_ERROR, ("SmbBattNewDevice: Can't allocate Smart Battery data\n"));
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory (SmbBatt, sizeof(SMB_BATT));


        //
        // Create the device object
        //

        status = IoCreateDevice(
                    DriverObject,
                    sizeof (SMB_NP_BATT),
                    NULL,
                    FILE_DEVICE_BATTERY,
                    FILE_DEVICE_SECURE_OPEN,
                    FALSE,
                    &fdo
                 );

        if (status != STATUS_SUCCESS) {
            BattPrint(BAT_ERROR, ("SmbBattNewDevice: error creating Fdo: %x\n", status));

            ExFreePool (SmbBatt);
            return(status);
        }


        //
        // Initialize the Fdo
        //

        fdo->Flags |= DO_BUFFERED_IO;
        fdo->Flags |= DO_POWER_PAGABLE;
        
        
        //
        // Layer our FDO on top of the PDO.
        //

        SmbNPBatt = (PSMB_NP_BATT) fdo->DeviceExtension;
        SmbNPBatt->LowerDevice = IoAttachDeviceToDeviceStack (fdo,PDO);

        if (!SmbNPBatt->LowerDevice) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -