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

📄 pnppower.c

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

    BattPrint(BAT_TRACE, ("SmbBattRemoveDevice: EXITING\n"));

    return status;
}




NTSTATUS
SmbBattQueryId(
    IN  PDEVICE_OBJECT Pdo,
    IN  PIRP           Irp
    )
/*++

Routine Description:

    This routine handles the IRP_MN_QUERY_ID for the newly created battery PDOs.

Arguments:

    Pdo         - Battery PDO

    Irp         - The query Irp

Return Value:

    NTSTATUS

--*/
{
    UNICODE_STRING          unicodeString;
    WCHAR                   unicodeBuffer[MAX_DEVICE_NAME_LENGTH];
    UNICODE_STRING          numberString;
    WCHAR                   numberBuffer[10];

    PSMB_BATT_PDO           pdoExt          = (PSMB_BATT_PDO) Pdo->DeviceExtension;
    NTSTATUS                status          = STATUS_SUCCESS;
    PWCHAR                  idString        = NULL;
    PIO_STACK_LOCATION      irpStack        = IoGetCurrentIrpStackLocation(Irp);

    PAGED_CODE();

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

    RtlZeroMemory (unicodeBuffer, MAX_DEVICE_NAME_LENGTH);
    unicodeString.MaximumLength = MAX_DEVICE_NAME_LENGTH;
    unicodeString.Length        = 0;
    unicodeString.Buffer        = unicodeBuffer;


    switch (irpStack->Parameters.QueryId.IdType) {

    case BusQueryDeviceID:

        //
        // This string has to have the form BUS\DEVICE.
        //
        // Use SMB as bus and SBS as device
        //

        RtlAppendUnicodeToString  (&unicodeString, SubSystemIdentifier);
        break;

    case BusQueryInstanceID:

        //
        // Return the string "Batteryxx" where xx is the battery number
        //

        numberString.MaximumLength = 10;
        numberString.Buffer = &numberBuffer[0];

        RtlIntegerToUnicodeString (pdoExt->BatteryNumber, 10, &numberString);
        RtlAppendUnicodeToString  (&unicodeString, BatteryInstance);
        RtlAppendUnicodeToString  (&unicodeString, &numberString.Buffer[0]);
        break;

    case BusQueryHardwareIDs:

        //
        // This is the Pnp ID for the smart battery subsystem "ACPI0002".
        // Make new hardware ID SMB\SBS, SmartBattery as a MULTIZ string
        // so we have to add a NULL string to terminate.
        //

        RtlAppendUnicodeToString  (&unicodeString, HidSmartBattery);
        unicodeString.Length += sizeof (WCHAR);
        break;

    default:

        //
        // Unknown Query Type
        //

        status = STATUS_NOT_SUPPORTED;

    }


    if (status != STATUS_NOT_SUPPORTED) {
        //
        // If we created a string, allocate a buffer for it and copy it into the buffer.
        // We need to make sure that we also copy the NULL terminator.
        //

        if (unicodeString.Length) {
            idString = ExAllocatePoolWithTag (PagedPool, unicodeString.Length + sizeof (WCHAR), 'StaB');

            if (!idString) {
                BattPrint (BAT_ERROR, ("SmbBattQueryId:  couldn't allocate id string buffer\n"));
                return STATUS_INSUFFICIENT_RESOURCES;
            }

            RtlZeroMemory (idString, unicodeString.Length + sizeof (WCHAR));
            RtlCopyMemory (idString, unicodeString.Buffer, unicodeString.Length);
        }

        Irp->IoStatus.Status = status;

        Irp->IoStatus.Information = (ULONG_PTR) idString;
    }

    BattPrint(BAT_DATA, ("SmbBattQueryId: returning ID = %x\n", idString));

    return status;
}




NTSTATUS
SmbBattQueryCapabilities(
    IN  PDEVICE_OBJECT Pdo,
    IN  PIRP           Irp
    )
/*++

Routine Description:

    This routine handles the IRP_MN_QUERY_CAPABILITIES for the newly created
    battery PDOs.

Arguments:

    Pdo         - Battery PDO

    Irp         - The query Irp

Return Value:

    NTSTATUS

--*/
{

    PDEVICE_CAPABILITIES    deviceCaps;
    PIO_STACK_LOCATION      irpStack        = IoGetCurrentIrpStackLocation(Irp);

    PAGED_CODE();

    deviceCaps = irpStack->Parameters.DeviceCapabilities.Capabilities;

    if (deviceCaps->Version != 1) {
        return STATUS_NOT_SUPPORTED;
    }


    //
    // Now set up the bits for the capabilities.
    //

    //All bits are initialized to false.  Only set bits that we support
    deviceCaps->SilentInstall   = TRUE;

    //
    // Now fill in the po manager information.
    //

    deviceCaps->SystemWake      = PowerSystemUnspecified;
    deviceCaps->DeviceWake      = PowerDeviceUnspecified;
    deviceCaps->D1Latency       = 1;
    deviceCaps->D2Latency       = 1;
    deviceCaps->D3Latency       = 1;

    return STATUS_SUCCESS;
}




SmbBattBuildSelectorStruct(
    IN PDEVICE_OBJECT SubsystemFdo
    )
/*++

Routine Description:

    This routine determines that address of the selector (whether it is a stand
    alone selector of part of the charger) and builds a selector structure with
    this information.  It also reads the initial selector information and
    caches this in the structure.  This structure will be passed out to all of
    the smart batteries in the system.

Arguments:

    SubsystemFdo    - Fdo for the smart battery subsystem

Return Value:

    NTSTATUS

--*/
{
    ULONG                   result;
    UCHAR                   smbStatus;

    PBATTERY_SELECTOR       selector     = NULL;
    PSMB_BATT_SUBSYSTEM     subsystemExt = (PSMB_BATT_SUBSYSTEM) SubsystemFdo->DeviceExtension;
    ULONG                   numberOfBatteries;

    PAGED_CODE();

    if (subsystemExt->SelectorPresent) {

        //
        // Allocate the selector structure.  This has to be from non-paged pool because
        // it will be accessed as part of the alarm processing.
        //

        selector = ExAllocatePoolWithTag (NonPagedPool, sizeof (BATTERY_SELECTOR), 'StaB');

        if (!selector) {
            BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Couldn't allocate selector structure\n"));
            
            //
            // Force Selector Not Present if allocation fails
            //

            subsystemExt->Selector = NULL;
            subsystemExt->SelectorPresent = FALSE;
            subsystemExt->NumberOfBatteries = 0;
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // See if the selector is part of the charger.  We do this by reading
        // directly from the selector first.  If this fails, then we verify
        // the charger is implementing the selector.
        //

        smbStatus = SmbBattGenericRW (
            subsystemExt->SmbHcFdo,
            SMB_SELECTOR_ADDRESS,
            SELECTOR_SELECTOR_STATE,
            &result
        );

        if (smbStatus == SMB_STATUS_OK) {

            //
            // We have a stand alone selector
            //

            selector->SelectorAddress       = SMB_SELECTOR_ADDRESS;
            selector->SelectorStateCommand  = SELECTOR_SELECTOR_STATE;
            selector->SelectorPresetsCommand= SELECTOR_SELECTOR_PRESETS;
            selector->SelectorInfoCommand   = SELECTOR_SELECTOR_INFO;

            BattPrint (BAT_NOTE, ("SmbBattBuildSelectorStruct: The selector is standalone\n"));

        } else {

            //
            // Read the Charger Spec Info to check Selector Implemented Bit
            // NOTE: We're doing this for verification and information purposes
            //

            smbStatus = SmbBattGenericRW (
                subsystemExt->SmbHcFdo,
                SMB_CHARGER_ADDRESS,
                CHARGER_SPEC_INFO,
                &result
            );

            if (smbStatus == SMB_STATUS_OK) {
                if (result & CHARGER_SELECTOR_SUPPORT_BIT) {
                    // If Selector Support Bit is present, then Selector implemented in Charger
                    BattPrint (BAT_NOTE, ("SmbBattBuildSelectorStruct: ChargerSpecInfo indicates charger implementing selector\n"));

                } else {
                    // If Charger says it doesn't implement Selector, let's double-check anyway
                    BattPrint (BAT_NOTE, ("SmbBattBuildSelectorStruct: ChargerSpecInfo indicates charger does not implement selector\n"));
                }
            } else {
                // If it returns an error, let's double-check anyway
                BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Couldn't read ChargerSpecInfo - %x\n", smbStatus));
            }

            //
            // Read SelectorState for Cache
            //

            smbStatus = SmbBattGenericRW (
                subsystemExt->SmbHcFdo,
                SMB_CHARGER_ADDRESS,
                CHARGER_SELECTOR_STATE,
                &result
            );

            if (smbStatus == SMB_STATUS_OK) {
                BattPrint (BAT_DATA, ("SmbBattBuildSelectorStruct: Selector state %x\n", result));

            } else {

                BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Couldn't read charger selector state - %x\n", smbStatus));
                goto SelectorErrorExit;
            }

            //
            // The charger is implementing the selector
            //

            selector->SelectorAddress       = SMB_CHARGER_ADDRESS;
            selector->SelectorStateCommand  = CHARGER_SELECTOR_STATE;
            selector->SelectorPresetsCommand= CHARGER_SELECTOR_PRESETS;
            selector->SelectorInfoCommand   = CHARGER_SELECTOR_INFO;

            BattPrint (BAT_NOTE, ("SmbBattBuildSelectorStruct: Charger implements the selector\n"));

        }

        //
        // Initialize the selector mutex
        //

        ExInitializeFastMutex (&selector->Mutex);

        //
        // Store SelectorState in Cache
        //

        selector->SelectorState = result;

        //
        // Read SelectorPresets for Cache
        //

        smbStatus = SmbBattGenericRW (
            subsystemExt->SmbHcFdo,
            selector->SelectorAddress,
            selector->SelectorPresetsCommand,
            &selector->SelectorPresets
        );

        if (smbStatus != SMB_STATUS_OK) {
            BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Couldn't read selector presets - %x\n", smbStatus));
            
            //
            // Should we really fail the whole thing, because of an error reading SelectorPresets?
            // Let's Emulate the Information (Ok To Use All, Use Next A if available)
            //

            selector->SelectorPresets = (selector->SelectorState & SELECTOR_PRESETS_OKTOUSE_MASK);
            if (selector->SelectorPresets & BATTERY_A_PRESENT) {
                selector->SelectorPresets |= (BATTERY_A_PRESENT << SELECTOR_SHIFT_USENEXT);
            }
            BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Emulating Selector Presets - %x\n", selector->SelectorPresets));

        } else {
            BattPrint (BAT_DATA, ("SmbBattBuildSelectorStruct: Selector presets %x\n", selector->SelectorPresets));
        }

        //
        // Read Selector Info for Cache
        //

        smbStatus = SmbBattGenericRW (
            subsystemExt->SmbHcFdo,
            selector->SelectorAddress,
            selector->SelectorInfoCommand,
            &selector->SelectorInfo
        );

        if (smbStatus != SMB_STATUS_OK) {
            BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Couldn't read selector info - %x\n", smbStatus));
            //
            // Should we really fail the whole thing, because of an error reading SelectorInfo?
            // Let's Emulate the Information (Specification 1.0, No Charge Indicator)
            //

            selector->SelectorInfo = 0x0010;
            if (subsystemExt->NumberOfBatteries > 0) {
                selector->SelectorInfo |= BATTERY_A_PRESENT;
            }
            if (subsystemExt->NumberOfBatteries > 1) {
                selector->SelectorInfo |= BATTERY_B_PRESENT;
            }
            if (subsystemExt->NumberOfBatteries > 2) {
                selector->SelectorInfo |= BATTERY_C_PRESENT;
            }
            if (subsystemExt->NumberOfBatteries > 3) {
                selector->SelectorInfo |= BATTERY_D_PRESENT;
            }
            BattPrint (BAT_ERROR, ("SmbBattBuildSelectorStruct: Emulating Selector Info - %x\n", selector->SelectorInfo));

        } else {

            BattPrint (BAT_NOTE, ("SmbBattBuildSelectorStruct: Selector info %x\n", selector->SelectorInfo));

            // Verify the Number of Batteries against the SelectorInfo
            numberOfBatteries = 0;
            result = (selector->SelectorInfo & SELECTOR_INFO_SUPPORT_MASK);
            if (result & BATTERY_A_PRESENT) numberOfBatteries++;
            if (result & BATTERY_B_PRESENT) numberOfBatteries++;
            if (result & BATTERY_C_PRESENT) numberOfBatteries++;
            if (result & BATTERY_D_PRESENT) numberOfBatteries++;

            // Should we always override ACPI??
            // Proposed Solution: if Selector supports less batteries than
            // ACPI says, then Override ACPI with selector support.  If
            // Selector supports more than ACPI says, then don't override,
            // unless ACPI was invalid and the # of batteries = 1

            if (subsystemExt->NumberOfBatteries > numberOfBatteries) {
                subsystemExt->NumberOfBatteries = numberOfBatteries;
            } else if ((subsystemExt->NumberOfBatteries == 1) && (numberOfBatteries > 1)) {
                subsystemExt->NumberOfBatteries = numberOfBatteries;
            } else if (subsystemExt->NumberOfBatteries < numberOfBatteries) {
                //subsystemExt->NumberOfBatteries = numberOfBatteries;
            }

        }

    }   // if (subsystemFdo->SelectorPresent)

    //
    // Everything was OK
    //

    subsystemExt->Selector = selector;
    return STATUS_SUCCESS;

SelectorErrorExit:

    //
    // If a failure occurs, free the selector structure and don't creat any batery devices.
    //

    ExFreePool (selector);
    subsystemExt->Selector = NULL;
    subsystemExt->SelectorPresent = FALSE;
    subsystemExt->NumberOfBatteries = 0;

    return STATUS_UNSUCCESSFUL;
}

⌨️ 快捷键说明

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