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

📄 smbbatt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
            BattPrint(BAT_ERROR, ("SmbBattNewDevice: error attaching to device stack\n"));

            ExFreePool (SmbBatt);

            IoDeleteDevice (fdo);

            return(status);
        }


        //
        // Fill in privates
        //

        SmbNPBatt->Batt             = SmbBatt;
        SmbNPBatt->SmbBattFdoType   = SmbTypeBattery;
        IoInitializeRemoveLock (&SmbNPBatt->RemoveLock,
                                SMB_BATTERY_TAG,
                                REMOVE_LOCK_MAX_LOCKED_MINUTES,
                                REMOVE_LOCK_HIGH_WATER_MARK);

        ExInitializeFastMutex (&SmbNPBatt->Mutex);

        SmbBatt->NP                 = SmbNPBatt;
        SmbBatt->PDO                = PDO;
        SmbBatt->DeviceObject       = fdo;
        SmbBatt->SelectorPresent    = subsystemExt->SelectorPresent;
        SmbBatt->Selector           = subsystemExt->Selector;

        pdoExt->Fdo                 = fdo;

        //
        // Precalculate this batteries SMB_x bit position in the selector status register.
        //
        // Just move it into the lower nibble and any function that needs
        // the bit can shift it left 4 = charger, 8 = power, 12 = smb
        //

        SmbBatt->SelectorBitPosition = 1;
        if (pdoExt->BatteryNumber > 0) {
            SmbBatt->SelectorBitPosition <<= pdoExt->BatteryNumber;
        }


        //
        // Have class driver allocate a new SMB miniport device
        //

        RtlZeroMemory (&BattInit, sizeof(BattInit));
        BattInit.MajorVersion        = SMB_BATTERY_MAJOR_VERSION;
        BattInit.MinorVersion        = SMB_BATTERY_MINOR_VERSION;
        BattInit.Context             = SmbBatt;
        BattInit.QueryTag            = SmbBattQueryTag;
        BattInit.QueryInformation    = SmbBattQueryInformation;
        BattInit.SetInformation      = SmbBattSetInformation;
        BattInit.QueryStatus         = SmbBattQueryStatus;
        BattInit.SetStatusNotify     = SmbBattSetStatusNotify;
        BattInit.DisableStatusNotify = SmbBattDisableStatusNotify;

        BattInit.Pdo                 = PDO;
        BattInit.DeviceName          = NULL;

        status = BatteryClassInitializeDevice (
                    &BattInit,
                    &SmbNPBatt->Class
                 );

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

            ExFreePool (SmbBatt);

            IoDetachDevice (SmbNPBatt->LowerDevice);
            IoDeleteDevice (fdo);

            return(status);
        }
        
        //
        // Register WMI support.
        //
        status = SmbBattWmiRegistration(SmbNPBatt);

        if (!NT_SUCCESS(status)) {
            //
            // WMI support is not critical to operation.  Just log an error.
            //

            BattPrint(BAT_ERROR,
                ("SmbBattNewDevice: Could not register as a WMI provider, status = %Lx\n", status));
        }


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



    }   // else (we have a battery PDO)


    return status;
}



VOID
SmbBattUnload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Cleanup all devices and unload the driver

Arguments:

    DriverObject - Driver object for unload

Return Value:

    Status

--*/
{

    PAGED_CODE();

    BattPrint(BAT_TRACE, ("SmbBattUnload: ENTERING\n"));

    //
    // Should check here to make sure all DO's are gone.
    //

    ExFreePool (GlobalRegistryPath.Buffer);
    // This is listed as an error so I'll always see when it is unloaded...
    BattPrint(BAT_ERROR, ("SmbBattUnload: Smbbatt.sys unloaded successfully.\n"));

}



NTSTATUS
SmbBattCreate(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PSMB_NP_BATT        SmbNPBatt   = (PSMB_NP_BATT) DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION  IrpSp       = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS            status;

    PAGED_CODE();

    BattPrint(BAT_TRACE, ("SmbBattCreate: ENTERING\n"));


    status = IoAcquireRemoveLock (&SmbNPBatt->RemoveLock, IrpSp->FileObject);

    //
    // Complete the request and return status.
    //
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    BattPrint(BAT_TRACE, ("SmbBattCreate: EXITING (status = 0x%08x\n", status));
    return(status);
}



NTSTATUS
SmbBattClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PSMB_NP_BATT        SmbNPBatt   = (PSMB_NP_BATT) DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION  IrpSp       = IoGetCurrentIrpStackLocation(Irp);

    PAGED_CODE();

    BattPrint(BAT_TRACE, ("SmbBattClose: ENTERING\n"));

    IoReleaseRemoveLock (&SmbNPBatt->RemoveLock, IrpSp->FileObject);

    //
    // Complete the request and return status.
    //
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    BattPrint(BAT_TRACE, ("SmbBattClose: EXITING\n"));
    return(STATUS_SUCCESS);
}



NTSTATUS
SmbBattIoctl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    IOCTL handler.  As this is an exclusive battery device, send the
    Irp to the battery class driver to handle battery IOCTLs.

Arguments:

    DeviceObject    - Battery for request

    Irp             - IO request

Return Value:

    Status of request

--*/
{
    PSMB_NP_BATT            SmbNPBatt;
    PSMB_BATT               SmbBatt;
    ULONG                   InputLen, OutputLen;
    PVOID                   IOBuffer;
    PIO_STACK_LOCATION      IrpSp;

    BOOLEAN                 complete        = FALSE;
    NTSTATUS                status          = STATUS_NOT_SUPPORTED;

    PAGED_CODE();

    BattPrint(BAT_TRACE, ("SmbBattIoctl: ENTERING\n"));

    IrpSp       = IoGetCurrentIrpStackLocation(Irp);
    SmbNPBatt   = (PSMB_NP_BATT) DeviceObject->DeviceExtension;

    status = IoAcquireRemoveLock (&SmbNPBatt->RemoveLock, Irp);

    if (NT_SUCCESS(status)) {
        if (SmbNPBatt->SmbBattFdoType == SmbTypePdo) {
            status = STATUS_NOT_SUPPORTED;
            complete = TRUE;
        } else if (SmbNPBatt->SmbBattFdoType == SmbTypeSubsystem) {
#if DEBUG
            if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_SMBBATT_DATA) {

                //
                // Direct Access Irp
                //

                IOBuffer    = Irp->AssociatedIrp.SystemBuffer;
                InputLen    = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
                OutputLen   = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;

                status = SmbBattDirectDataAccess (
                    (PSMB_NP_BATT) DeviceObject->DeviceExtension,
                    (PSMBBATT_DATA_STRUCT) IOBuffer,
                    InputLen,
                    OutputLen
                );

                if (NT_SUCCESS(status)) {
                    Irp->IoStatus.Information = OutputLen;
                } else {
                    Irp->IoStatus.Information = 0;
                }

            } else {
#endif
                status = STATUS_NOT_SUPPORTED;
#if DEBUG
            }
#endif
        } else {
            ASSERT (SmbNPBatt->SmbBattFdoType == SmbTypeBattery);

            //
            // Check to see if this is one of the private Ioctls we handle
            //

            switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
#if DEBUG
            case IOCTL_SMBBATT_DATA:
                IOBuffer    = Irp->AssociatedIrp.SystemBuffer;
                InputLen    = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
                OutputLen   = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;

                //
                // This one is only handled by the battery subsystem
                //

                status = SmbBattDirectDataAccess (
                    (PSMB_NP_BATT) DeviceObject->DeviceExtension,
                    (PSMBBATT_DATA_STRUCT) IOBuffer,
                    InputLen,
                    OutputLen
                );

                if (NT_SUCCESS(status)) {
                    Irp->IoStatus.Information = OutputLen;
                } else {
                    Irp->IoStatus.Information = 0;
                }
                break;
#endif
            default:
                //
                // Not IOCTL for us, see if it's for the battery
                //

                SmbBatt = SmbNPBatt->Batt;
                status  = BatteryClassIoctl (SmbNPBatt->Class, Irp);

                if (status != STATUS_NOT_SUPPORTED) {
                    //
                    // The Irp was completed by the batery class.  Don't
                    // touch the Irp.  Simply release the lock and return.
                    //

                    IoReleaseRemoveLock (&SmbNPBatt->RemoveLock, Irp);
                    BattPrint(BAT_TRACE, ("SmbBattIoctl: EXITING (was battery IOCTL)\n", status));
                    return status;
                }

                break;

            }   // switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
        }

        IoReleaseRemoveLock (&SmbNPBatt->RemoveLock, Irp);
    }

    if ((status == STATUS_NOT_SUPPORTED ) && !complete) {

        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (SmbNPBatt->LowerDevice, Irp);

    } else {
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
    }
    BattPrint(BAT_TRACE, ("SmbBattIoctl: EXITING (status = 0x%08x)\n", status));
    return status;
}



NTSTATUS
SmbBattQueryTag (
    IN  PVOID Context,
    OUT PULONG BatteryTag
    )
/*++

Routine Description:

    Called by the class driver to retrieve the batteries current tag value

Arguments:

    Context         - Miniport context value for battery

    BatteryTag      - Pointer to return current tag


Return Value:

    Success if there is a battery currently installed, else no such device.

--*/
{
    //PSMB_BATT_SUBSYSTEM subsystemExt;
    NTSTATUS            status;
    PSMB_BATT           SmbBatt;
    ULONG               oldSelectorState;

    PAGED_CODE();
    BattPrint(BAT_TRACE, ("SmbBattQueryTag: ENTERING\n"));

    //
    // Get device lock and make sure the selector is set up to talk to us.
    // Since multiple people may be doing this, always lock the selector
    // first followed by the battery.
    //

    SmbBatt = (PSMB_BATT) Context;
    SmbBattLockSelector (SmbBatt->Selector);
    SmbBattLockDevice (SmbBatt);

    status = SmbBattSetSelectorComm (SmbBatt, &oldSelectorState);
    if (!NT_SUCCESS (status)) {
        BattPrint(BAT_ERROR, ("SmbBattQueryTag: can't set selector communications path\n"));
    } else {

        //
        // If the tag is not valid, check for one
        //

        if (SmbBatt->Info.Tag == BATTERY_TAG_INVALID) {
            SmbBatt->Info.Valid = 0;
        }

        //
        // Insure the static information regarding the battery up to date
        //

        SmbBattVerifyStaticInfo (SmbBatt, 0);

        //
        // If theres a battery return it's tag
        //

        if (SmbBatt->Info.Tag != BATTERY_TAG_INVALID) {
            *BatteryTag = SmbBatt->Info.Tag;
            status = STATUS_SUCCESS;
        } else {
            status = STATUS_NO_SUCH_DEVICE;
        }
    }


    //
    // Done, unlock the device and reset the selector state
    //

    if (NT_SUCCESS (status)) {

⌨️ 快捷键说明

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