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

📄 smbbatt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
        status = SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
        if (!NT_SUCCESS (status)) {
            BattPrint(BAT_ERROR, ("SmbBattQueryTag: can't reset selector communications path\n"));
        }
    } else {
        //
        // Ignore the return value from ResetSelectorComm because we already
        // have an error here.
        //

        SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
    }


    SmbBattUnlockDevice (SmbBatt);
    SmbBattUnlockSelector (SmbBatt->Selector);

    BattPrint(BAT_TRACE, ("SmbBattQueryTag: EXITING\n"));
    return status;
}



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
    )
{
    PSMB_BATT           SmbBatt;
    ULONG               ResultData;
    BOOLEAN             IoCheck;
    NTSTATUS            status, st;
    PVOID               ReturnBuffer;
    ULONG               ReturnBufferLength;
    WCHAR               scratchBuffer[SMB_MAX_DATA_SIZE+1]; // +1 for UNICODE_NULL
    UNICODE_STRING      unicodeString;
    UNICODE_STRING      tmpUnicodeString;
    ANSI_STRING         ansiString;
    ULONG               oldSelectorState;
    BATTERY_REPORTING_SCALE granularity;

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


    if (BatteryTag == BATTERY_TAG_INVALID) {
        return STATUS_NO_SUCH_DEVICE;
    }

    //
    // 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, ("SmbBattQueryInformation: can't set selector communications path\n"));
    } else {

        do {
            ResultData = 0;
            ReturnBuffer = NULL;
            ReturnBufferLength = 0;
            status = STATUS_SUCCESS;


            //
            // If no device, or caller has the wrong ID give an error
            //

            if (BatteryTag != SmbBatt->Info.Tag) {
                status = STATUS_NO_SUCH_DEVICE;
                break;
            }


            //
            // Get the info requested
            //

            switch (Level) {
                case BatteryInformation:
                    ReturnBuffer = &SmbBatt->Info.Info;
                    ReturnBufferLength = sizeof (SmbBatt->Info.Info);
                    break;

                case BatteryGranularityInformation:
                    SmbBattRW(SmbBatt, BAT_FULL_CHARGE_CAPACITY, &granularity.Capacity);
                    granularity.Capacity *= SmbBatt->Info.PowerScale;
                    granularity.Granularity = SmbBatt->Info.PowerScale;
                    ReturnBuffer = &granularity;
                    ReturnBufferLength  = sizeof (granularity);
                    break;

                case BatteryTemperature:
                    SmbBattRW(SmbBatt, BAT_TEMPERATURE, &ResultData);
                    ReturnBuffer = &ResultData;
                    ReturnBufferLength = sizeof(ULONG);
                    break;

                case BatteryEstimatedTime:

                    //
                    // If an AtRate has been specified, then we will use the AtRate
                    // functions to get this information (AtRateTimeToEmpty()).
                    // Otherwise, we will return the AVERAGE_TIME_TO_EMPTY.
                    //

                    BattPrint(BAT_DATA, ("SmbBattQueryInformation: EstimatedTime: AtRate: %08x\n", AtRate));

                    if (AtRate != 0) {
                        //
                        // Currently we only support the time to empty functions.
                        //

                        ASSERT (AtRate < 0);

                        //
                        // The smart battery input value for AtRate is in 10mW increments
                        //

                        AtRate /= (LONG)SmbBatt->Info.PowerScale;
                        BattPrint(BAT_DATA, ("SmbBattQueryInformation: EstimatedTime: AtRate scaled to: %08x\n", AtRate));
                        SmbBattWW(SmbBatt, BAT_AT_RATE, AtRate);
                        SmbBattRW(SmbBatt, BAT_RATE_TIME_TO_EMPTY, &ResultData);
                        BattPrint(BAT_DATA, ("SmbBattQueryInformation: EstimatedTime: AT_RATE_TIME_TO_EMPTY: %08x\n", ResultData));

                    } else {

                        SmbBattRW(SmbBatt, BAT_AVERAGE_TIME_TO_EMPTY, &ResultData);
                        BattPrint(BAT_DATA, ("SmbBattQueryInformation: EstimatedTime: AVERAGE_TIME_TO_EMPTY: %08x\n", ResultData));
                    }

                    if (ResultData == 0xffff) {
                        ResultData = BATTERY_UNKNOWN_TIME;
                    } else {
                        ResultData *= 60;
                    }
                    BattPrint(BAT_DATA, ("SmbBattQueryInformation: (%01x) EstimatedTime: %08x seconds\n", SmbBatt->SelectorBitPosition, ResultData));

                    ReturnBuffer = &ResultData;
                    ReturnBufferLength = sizeof(ULONG);
                    break;

                case BatteryDeviceName:
                    //
                    // This has to be returned as a WCHAR string but is kept internally
                    // as a character string.  Have to convert it.
                    //

                    unicodeString.Buffer        = Buffer;
                    unicodeString.MaximumLength = BufferLength > (USHORT)-1 ? (USHORT) -1 : (USHORT)BufferLength;

                    ansiString.Length = SmbBatt->Info.DeviceNameLength;
                    ansiString.MaximumLength = sizeof(SmbBatt->Info.DeviceName);
                    ansiString.Buffer = SmbBatt->Info.DeviceName;
                    status = RtlAnsiStringToUnicodeString (&unicodeString, &ansiString, FALSE);
                    if (NT_SUCCESS(status)) {
                        ReturnBuffer       = Buffer;
                        ReturnBufferLength = unicodeString.Length;
                    }
                    break;

                case BatteryManufactureDate:
                    ReturnBuffer = &SmbBatt->Info.ManufacturerDate;
                    ReturnBufferLength = sizeof (SmbBatt->Info.ManufacturerDate);
                    break;

                case BatteryManufactureName:
                    //
                    // This has to be returned as a WCHAR string but is kept internally
                    // as a character string.  Have to convert it.
                    //

                    unicodeString.Buffer        = Buffer;
                    unicodeString.MaximumLength = BufferLength > (USHORT)-1 ? (USHORT) -1 : (USHORT)BufferLength;

                    ansiString.Length = SmbBatt->Info.ManufacturerNameLength;
                    ansiString.MaximumLength = sizeof(SmbBatt->Info.ManufacturerName);
                    ansiString.Buffer = SmbBatt->Info.ManufacturerName;
                    status = RtlAnsiStringToUnicodeString (&unicodeString, &ansiString, FALSE);
                    if (NT_SUCCESS(status)) {
                        ReturnBuffer        = Buffer;
                        ReturnBufferLength = unicodeString.Length;
                    }
                    break;
                    
                case BatteryUniqueID:
                    //
                    // The unique ID is a character string consisting of the serial
                    // number, the manufacturer name, and the device name.
                    //

                    unicodeString.Buffer        = Buffer;
                    unicodeString.MaximumLength = BufferLength > (USHORT)-1 ? (USHORT) -1 : (USHORT)BufferLength;

                    tmpUnicodeString.Buffer         = scratchBuffer;
                    tmpUnicodeString.MaximumLength  = sizeof (scratchBuffer);

                    RtlIntegerToUnicodeString(SmbBatt->Info.SerialNumber, 10, &unicodeString);

                    ansiString.Length = SmbBatt->Info.ManufacturerNameLength;
                    ansiString.MaximumLength = sizeof(SmbBatt->Info.ManufacturerName);
                    ansiString.Buffer = SmbBatt->Info.ManufacturerName;
                    status = RtlAnsiStringToUnicodeString (&tmpUnicodeString, &ansiString, FALSE);
                    if (!NT_SUCCESS(status)) break;
                    status = RtlAppendUnicodeStringToString (&unicodeString, &tmpUnicodeString);
                    if (!NT_SUCCESS(status)) break;

                    ansiString.Length = SmbBatt->Info.DeviceNameLength;
                    ansiString.MaximumLength = sizeof(SmbBatt->Info.DeviceName);
                    ansiString.Buffer = SmbBatt->Info.DeviceName;
                    status = RtlAnsiStringToUnicodeString (&tmpUnicodeString, &ansiString, FALSE);
                    if (!NT_SUCCESS(status)) break;
                    status = RtlAppendUnicodeStringToString (&unicodeString, &tmpUnicodeString);
                    if (!NT_SUCCESS(status)) break;

                    ReturnBuffer        = Buffer;
                    ReturnBufferLength = unicodeString.Length;
                    break;

                case BatterySerialNumber:
                    //
                    // This has to be returned as a WCHAR string but is kept internally
                    // as a character string.  Have to convert it.
                    //

                    unicodeString.Buffer        = Buffer;
                    unicodeString.MaximumLength = BufferLength > (USHORT)-1 ? (USHORT) -1 : (USHORT)BufferLength;

                    status = RtlIntegerToUnicodeString(SmbBatt->Info.SerialNumber, 10, &unicodeString);

                    if (NT_SUCCESS(status)) {
                        ReturnBuffer        = Buffer;
                        ReturnBufferLength = unicodeString.Length;
                    }
                    break;
                    
                default:
                    status = STATUS_INVALID_DEVICE_REQUEST;
                    break;
            }

            //
            // Re-verify static info in case there's been an IO error
            //

            //IoCheck = SmbBattVerifyStaticInfo (SmbBatt, BatteryTag);
            IoCheck = FALSE;

        } while (IoCheck);

    }


    if (NT_SUCCESS (status)) {
        //
        // Done, return buffer if needed
        //

        *ReturnedLength = ReturnBufferLength;
        
        if (ReturnBuffer != Buffer) {
            // ReturnBuffer == Buffer indicates that data is already copied.
            //
            if (BufferLength < ReturnBufferLength) {
                status = STATUS_BUFFER_TOO_SMALL;
            }

            if (NT_SUCCESS(status) && ReturnBuffer) {
                memcpy (Buffer, ReturnBuffer, ReturnBufferLength);
            }
        }

        //
        // Unlock the device and reset the selector state
        //

        st = SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
        if (!NT_SUCCESS (st)) {
            BattPrint(BAT_ERROR, ("SmbBattQueryInformation: can't reset selector communications path\n"));
            status = st;
        }
    } else {
        *ReturnedLength = 0;

        //
        // Ignore the return value from ResetSelectorComm because we already
        // have an error here.
        //

        SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
    }

    SmbBattUnlockDevice (SmbBatt);
    SmbBattUnlockSelector (SmbBatt->Selector);

    BattPrint(BAT_TRACE, ("SmbBattQueryInformation: EXITING\n"));
    return status;
}



NTSTATUS
SmbBattSetInformation (
    IN PVOID                            Context,
    IN ULONG                            BatteryTag,
    IN BATTERY_SET_INFORMATION_LEVEL    Level,
    IN PVOID Buffer                     OPTIONAL
    )
/*++

Routine Description:

    Called by the class driver to set the battery's charge/discharge state.
    The smart battery does not support the critical bias function of this
    call.

Arguments:

    Context         - Miniport context value for battery

    BatteryTag      - Tag of current battery

    Level           - Action being asked for

Return Value:

    NTSTATUS

--*/
{
    PSMB_BATT           SmbBatt;
    ULONG               newSelectorState;
    ULONG               selectorState;
    UCHAR               smbStatus;
    ULONG               tmp;

    NTSTATUS            status  = STATUS_NOT_SUPPORTED;

    PAGED_CODE();

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


    SmbBatt = (PSMB_BATT) Context;

    //
    // See if this is for our battery
    //

    if ((BatteryTag == BATTERY_TAG_INVALID) || (BatteryTag != SmbBatt->Info.Tag)) {
        return STATUS_NO_SUCH_DEVICE;
    }


    //
    // We can only do this if there is a selector in the system
    //

    if ((SmbBatt->SelectorPresent) && (SmbBatt->Selector)) {

        //
        // Get a lock on the selector
        //

        SmbBattLockSelector (SmbBatt->Selector);

        switch (Level) {

            case BatteryCharge:
                BattPrint(BAT_IRPS, ("SmbBattSetInformation: Got SetInformation for BatteryCharge\n"));

                //
                // Set the appropriate bit in the selector state charge nibble
                //

                newSelectorState = SELECTOR_SET_CHARGE_MASK;
                newSelectorState |= (SmbBatt->SelectorBitPosition << SELECTOR_SHIFT_CHARGE);

                //
                // Write the new selector state, then read it back.  The system
                // may or may not let us do this.
                //

                smbStatus = SmbBattGenericWW (
                                SmbBatt->SmbHcFdo,
                                SmbBatt->Selector->SelectorAddress,
                                SmbBatt->Selector->SelectorStateCommand,
                                newSelectorState
                            );

                if (smbStatus != SMB_STATUS_OK) {
                    BattPrint(BAT_ERROR,
                         ("SmbBattSetInformation:  couldn't write selector state - %x\n",
                         smbStatus)
                    );

                    status = STATUS_UNSUCCESSFUL;
                    break;
                }

                smbStatus = SmbBattGenericRW (
                                SmbBatt->SmbHcFdo,
                                SmbBatt->Selector->SelectorAddress,
                                SmbBatt->Selector->SelectorStateCommand,
                                &selectorState
                            );

                if ((smbStatus != SMB_STATUS_OK)) {
                    BattPrint(BAT_ERROR,
                        ("SmbBattSetInformation:  couldn't read selector state - %x\n",
                        smbStatus)
                    );

                    status = STATUS_UNSUCCESSFUL;
                    break;
                }


                //

⌨️ 快捷键说明

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