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

📄 pnppower.c

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

Return Value:

    The function value is the final status of the call


--*/

{
    PIRP                    irp;
    PIO_STACK_LOCATION      irpStack;
    SMB_REGISTER_ALARM      registerAlarm;
    KEVENT                  event;
    NTSTATUS                status;

    PSMB_BATT_SUBSYSTEM     subsystemExtension  =
            (PSMB_BATT_SUBSYSTEM) Fdo->DeviceExtension;

    PAGED_CODE();

    //
    // Register for alarm notifications
    //

    registerAlarm.MinAddress        = SMB_CHARGER_ADDRESS;
    registerAlarm.MaxAddress        = SMB_BATTERY_ADDRESS;
    registerAlarm.NotifyFunction    = SmbBattAlarm;
    registerAlarm.NotifyContext     = subsystemExtension;

    KeInitializeEvent (&event, NotificationEvent, FALSE);

    irp = IoAllocateIrp (subsystemExtension->SmbHcFdo->StackSize, FALSE);

    if (!irp) {
        BattPrint(BAT_ERROR, ("SmbBattRegisterForAlarm: couldn't allocate irp\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    irpStack                    = IoGetNextIrpStackLocation(irp);
    irp->UserBuffer             = &subsystemExtension->SmbAlarmHandle;
    irpStack->MajorFunction     = IRP_MJ_INTERNAL_DEVICE_CONTROL;

    irpStack->Parameters.DeviceIoControl.IoControlCode      = SMB_REGISTER_ALARM_NOTIFY;
    irpStack->Parameters.DeviceIoControl.InputBufferLength  = sizeof(registerAlarm);
    irpStack->Parameters.DeviceIoControl.Type3InputBuffer   = &registerAlarm;
    irpStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(subsystemExtension->SmbAlarmHandle);

    IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);
    IoCallDriver (subsystemExtension->SmbHcFdo, irp);
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

    status = irp->IoStatus.Status;
    if (!NT_SUCCESS(status)) {
        BattPrint(BAT_ERROR, ("SmbBattRegisterForAlarm: couldn't register for alarms - %x\n", status));
    }

    IoFreeIrp (irp);

    return status;

}



NTSTATUS
SmbBattUnregisterForAlarm(
    IN PDEVICE_OBJECT Fdo
    )

/*++

Routine Description:

    This routine unregisters with the SmbHc for alarm notifications.  This
    is only done when smart battery subsystem FDO is stopped or unloaded.

Arguments:

    Fdo - Pointer to the Fdo for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call


--*/

{
    PIRP                    irp;
    PIO_STACK_LOCATION      irpStack;
    KEVENT                  event;
    NTSTATUS                status;

    PSMB_BATT_SUBSYSTEM     subsystemExtension  = (PSMB_BATT_SUBSYSTEM) Fdo->DeviceExtension;

    PAGED_CODE();

    //
    // DeRegister for alarm notifications
    //

    KeInitializeEvent (&event, NotificationEvent, FALSE);

    irp = IoAllocateIrp (subsystemExtension->SmbHcFdo->StackSize, FALSE);

    if (!irp) {
        BattPrint(BAT_ERROR, ("SmbBattUnregisterForAlarm: couldn't allocate irp\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    irpStack                    = IoGetNextIrpStackLocation(irp);
    irp->UserBuffer             = NULL;
    irpStack->MajorFunction     = IRP_MJ_INTERNAL_DEVICE_CONTROL;

    irpStack->Parameters.DeviceIoControl.IoControlCode      = SMB_DEREGISTER_ALARM_NOTIFY;
    irpStack->Parameters.DeviceIoControl.InputBufferLength  = sizeof(subsystemExtension->SmbAlarmHandle);
    irpStack->Parameters.DeviceIoControl.Type3InputBuffer   = &subsystemExtension->SmbAlarmHandle;
    irpStack->Parameters.DeviceIoControl.OutputBufferLength = 0;

    IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);
    IoCallDriver (subsystemExtension->SmbHcFdo, irp);
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

    status = irp->IoStatus.Status;
    if (!NT_SUCCESS(status)) {
        BattPrint(BAT_ERROR, ("SmbBattUnregisterForAlarm: couldn't unregister for alarms - %x\n", status));
    }

    IoFreeIrp (irp);

    return status;

}



NTSTATUS
SmbGetSBS (
    IN PULONG           NumberOfBatteries,
    IN PBOOLEAN         SelectorPresent,
    IN PDEVICE_OBJECT   LowerDevice
    )
/*++

Routine Description:

    This routine has the ACPI driver run the control method _SBS for the smart battery
    subsystem.  This control method returns a value that tells the driver how many
    batteries are supported and whether or not the system contains a selector.

Arguments:

    NumberOfBatteries   - pointer to return the number of batteries

    SelectorPresent     - Pointer to return whether a selector is present (TRUE)

    LowerDevice         - device object to call

Return Value:

    Status of the IOCTL to the ACPI driver.

--*/
{
    ACPI_EVAL_INPUT_BUFFER  inputBuffer;
    ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
    KEVENT                  event;
    IO_STATUS_BLOCK         ioStatusBlock;
    NTSTATUS                status;
    PACPI_METHOD_ARGUMENT   argument;
    PIRP                    irp;

    PAGED_CODE();

    BattPrint (BAT_TRACE, ("SmbGetSBS: Entering\n"));

    //
    //  Initialize the input structure
    //

    RtlZeroMemory( &inputBuffer, sizeof(ACPI_EVAL_INPUT_BUFFER) );
    inputBuffer.MethodNameAsUlong = SMBATT_SBS_METHOD;
    inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

    //
    // Set the event object to the unsignaled state.
    // It will be used to signal request completion.
    //

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    //
    // Build synchronous request with no transfer.
    //

    irp = IoBuildDeviceIoControlRequest(
       IOCTL_ACPI_ASYNC_EVAL_METHOD,
       LowerDevice,
       &inputBuffer,
       sizeof(ACPI_EVAL_INPUT_BUFFER),
       &outputBuffer,
       sizeof(ACPI_EVAL_OUTPUT_BUFFER),
       FALSE,
       &event,
       &ioStatusBlock
    );

    if (irp == NULL) {
        BattPrint (BAT_ERROR, ("SmbGetSBS: couldn't create Irp\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Pass request to port driver and wait for request to complete.
    //

    status = IoCallDriver (LowerDevice, irp);

    if (status == STATUS_PENDING) {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatusBlock.Status;
    }

    //
    // Sanity check the data
    //
    if (outputBuffer.Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
        outputBuffer.Count == 0) {

        status = STATUS_ACPI_INVALID_DATA;
    }

    *SelectorPresent = FALSE;
    *NumberOfBatteries = 0;

    if (!NT_SUCCESS(status)) {
        BattPrint (BAT_BIOS_ERROR | BAT_ERROR, ("SmbGetSBS: Irp failed - %x\n", status));
    } else {

        argument = outputBuffer.Argument;
        if (argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) {
            return STATUS_ACPI_INVALID_DATA;
        }

        switch (argument->Argument) {
            case 0:
                BattPrint(BAT_DATA, ("SmbGetSBS: Number of batteries = 1, no selector\n"));
                *NumberOfBatteries = 1;
                break;

            case 1:
            case 2:
            case 3:
            case 4:
                BattPrint(BAT_DATA, ("SmbGetSBS: Number of batteries found - %x\n", argument->Argument));
                *SelectorPresent = TRUE;
                *NumberOfBatteries = argument->Argument;
                break;

            default:
                BattPrint(BAT_ERROR, ("SmbGetSBS: Invalid number of batteries - %x\n", argument->Argument));
                return STATUS_NO_SUCH_DEVICE;
        }
    }

    return status;
}




NTSTATUS
SmbGetGLK (
    IN PBOOLEAN         GlobalLockRequired,
    IN PDEVICE_OBJECT   LowerDevice
    )
/*++

Routine Description:

    This routine has the ACPI driver run the control method _SBS for the smart battery
    subsystem.  This control method returns a value that tells the driver how many
    batteries are supported and whether or not the system contains a selector.

Arguments:

    GlobalLockRequired  - Pointer to return whether lock acquisition is needed

    LowerDevice         - device object to call

Return Value:

    Status of the IOCTL to the ACPI driver.

--*/
{
    ACPI_EVAL_INPUT_BUFFER  inputBuffer;
    ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
    KEVENT                  event;
    IO_STATUS_BLOCK         ioStatusBlock;
    NTSTATUS                status;
    PACPI_METHOD_ARGUMENT   argument;
    PIRP                    irp;

    PAGED_CODE();

    BattPrint (BAT_TRACE, ("SmbGetGLK: Entering\n"));

    //
    //  Initialize the input structure
    //

    RtlZeroMemory( &inputBuffer, sizeof(ACPI_EVAL_INPUT_BUFFER) );
    inputBuffer.MethodNameAsUlong = SMBATT_GLK_METHOD;
    inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

    //
    // Set the event object to the unsignaled state.
    // It will be used to signal request completion.
    //

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    //
    // Build synchronous request with no transfer.
    //

    irp = IoBuildDeviceIoControlRequest(
       IOCTL_ACPI_ASYNC_EVAL_METHOD,
       LowerDevice,
       &inputBuffer,
       sizeof(ACPI_EVAL_INPUT_BUFFER),
       &outputBuffer,
       sizeof(ACPI_EVAL_OUTPUT_BUFFER),
       FALSE,
       &event,
       &ioStatusBlock
    );

    if (irp == NULL) {
        BattPrint (BAT_ERROR, ("SmbGetGLK: couldn't create Irp\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Pass request to port driver and wait for request to complete.
    //

    status = IoCallDriver (LowerDevice, irp);

    if (status == STATUS_PENDING) {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatusBlock.Status;
    }

    if (!NT_SUCCESS(status)) {
        if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
            status = STATUS_SUCCESS;
            *GlobalLockRequired = FALSE;
            BattPrint (BAT_NOTE, ("SmbGetGLK: _GLK not found assuming lock is not needed.\n"));
        } else {
            BattPrint (BAT_ERROR, ("SmbGetGLK: Irp failed - %x\n", status));
        }
    } else {

        //
        // Sanity check the data
        //
        if (outputBuffer.Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
            outputBuffer.Count == 0) {

            return STATUS_ACPI_INVALID_DATA;
        }

        argument = outputBuffer.Argument;
        if (argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) {
            return STATUS_ACPI_INVALID_DATA;
        }

        if (argument->Argument == 0) {
            *GlobalLockRequired = FALSE;
        } else if (argument->Argument == 1) {
            *GlobalLockRequired = TRUE;
        } else {
            BattPrint(BAT_BIOS_ERROR, ("SmbGetGLK: Invalid value returned - %x\n", argument->Argument));
            status = STATUS_UNSUCCESSFUL;
        }
    }

    BattPrint (BAT_DATA, ("SmbGetGLK: Returning %x GLK = %d\n", status, SmbBattUseGlobalLock));
    return status;
}




NTSTATUS
SmbBattCreatePdos(
    IN PDEVICE_OBJECT SubsystemFdo
    )
/*++

Routine Description:

    This routine creates a PDO for each battery supported by the system and puts
    it into a list kept with the FDO for the smart battery subsystem.

Arguments:

    SubsystemFdo    - Fdo for the smart battery subsystem

Return Value:

    Status for creation of battery PDO.
--*/
{
    ULONG                   i;
    NTSTATUS                status;
    PSMB_BATT_PDO           batteryPdoExt;
    UNICODE_STRING          numberString;
    WCHAR                   numberBuffer[10];
    PDEVICE_OBJECT          pdo;

    PSMB_BATT_SUBSYSTEM     subsystemExt        = (PSMB_BATT_SUBSYSTEM) SubsystemFdo->DeviceExtension;
    BOOLEAN                 selectorPresent     = FALSE;

    PAGED_CODE();

    //
    // Find out if there are multiple batteries and a selector on this machine.
    //

    status = SmbGetSBS (
        &subsystemExt->NumberOfBatteries,
        &subsystemExt->SelectorPresent,
        subsystemExt->LowerDevice
    );


    if (!NT_SUCCESS(status)) {
        BattPrint(BAT_ERROR, ("SmbBattCreatePdos: error reading SBS\n"));
        return status;
    }

    status = SmbGetGLK (
        &SmbBattUseGlobalLock,
        subsystemExt->LowerDevice
    );


    if (!NT_SUCCESS(status)) {
        BattPrint(BAT_ERROR, ("SmbBattCreatePdos: error reading GLK\n"));
        //
        // If this failed, ignore the failure and continue.  This is not critical.
        //
    }

⌨️ 快捷键说明

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