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

📄 smbmisc.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
                                IoBuffer->Command,
                                strBuffer,
                                &strLength
                            );

                            SmbBattRB (
                                SmbBatt,
                                IoBuffer->Command,
                                strBuffer2,
                                &strLength
                            );
                        } while (strcmp (strBuffer, strBuffer2));

                        RtlInitAnsiString (&ansiString, strBuffer);
                        RtlAnsiStringToUnicodeString (&unicodeString, &ansiString, FALSE);

                        ReturnBufferLength  = unicodeString.Length;


                    } else {
                        status = STATUS_INVALID_BUFFER_SIZE;
                    }
                } else {
                    // Unsupported Commands
                    status = STATUS_INVALID_PARAMETER;
                }
            }

        }

        SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
        SmbBattUnlockDevice (SmbBatt);
        SmbBattUnlockSelector (SmbBatt->Selector);
    } else if (DeviceExtension->SmbBattFdoType == SmbTypeSubsystem) {
        // This is a battery subsystem
        SubsystemExt = (PSMB_BATT_SUBSYSTEM) DeviceExtension;
        SmbBattLockSelector (SubsystemExt->Selector);

        if ((InputLen >= sizeof(SMBBATT_DATA_STRUCT)) && (OutputLen == 0)) {
            // This is a write command
            status = STATUS_NOT_IMPLEMENTED;
        } else if ((InputLen == sizeof(SMBBATT_DATA_STRUCT)) && (OutputLen > 0)){
            // This is a Read command

            switch (IoBuffer->Address) {

                case SMB_SELECTOR_ADDRESS:

                    //
                    // We have to do some translation for selector requests depending
                    // on whether the selector is stand alone or implemented in the
                    // charger.
                    //

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

                        address = SubsystemExt->Selector->SelectorAddress;
                        command = IoBuffer->Command;

                        // Map to Charger if Selector is implemented in the Charger
                        if (address == SMB_CHARGER_ADDRESS) {
                            switch (command) {
                                case SELECTOR_SELECTOR_STATE:
                                case SELECTOR_SELECTOR_PRESETS:
                                case SELECTOR_SELECTOR_INFO:
                                    command |= CHARGER_SELECTOR_COMMANDS;
                                    break;

                                default:
                                    status = STATUS_NOT_SUPPORTED;
                                    break;
                            }
                        }

                    } else {
                        status = STATUS_NO_SUCH_DEVICE;
                    }

                    break;

                case SMB_CHARGER_ADDRESS:

                    //
                    // For this one we currently only support the ChargerStatus and
                    // ChargerSpecInfo commands.
                    //
                    // Other commands are not currently supported.
                    //

                    address = IoBuffer->Address;

                    switch (IoBuffer->Command) {
                        case CHARGER_SPEC_INFO:
                        case CHARGER_STATUS:

                            command = IoBuffer->Command;
                            break;

                        default:
                            status = STATUS_NOT_SUPPORTED;
                            break;

                    }

                    break;


                default:
                    status = STATUS_NOT_SUPPORTED;
                    break;

            }   // switch (readStruct->Address)

            if (status == STATUS_SUCCESS) {
                //
                // Do the read command
                //

                smbStatus = SmbBattGenericRW (
                                SubsystemExt->SmbHcFdo,
                                address,
                                command,
                                &IoBuffer->Data.Ulong
                            );

                if (smbStatus != SMB_STATUS_OK) {
                    BattPrint (
                        BAT_ERROR,
                        ("SmbBattDirectDataAccess:  Couldn't read from - %x, status - %x\n",
                        address,
                        smbStatus)
                    );

                    status = STATUS_UNSUCCESSFUL;

                }
            }

        }

        SmbBattUnlockSelector (SubsystemExt->Selector);
    } else {
        status=STATUS_INVALID_DEVICE_REQUEST;
        BattPrint (
            BAT_ERROR,
            ("SmbBattDirectDataAccess: Invalid SmbBattFdoType")
        );
    }

    return status;
}
#endif


UCHAR
SmbBattIndex (
    IN PBATTERY_SELECTOR    Selector,
    IN ULONG                SelectorNibble,
    IN UCHAR                SimultaneousIndex
)
/*++

Routine Description:

    This routine is provided as a helper routine to determine which
    battery is selected in a given selector nibble, based on the number
    of batteries supported in the system.

Arguments:

    Selector            - Structure defining selector address and commands

    SelectorNibble      - The nibble of the SelectorState, moved to the low
                          order 4 bits, to check reverse logic on.

    SimultaneousIndex   - Which batteryindex is requested in simultaneous-
                          battery situations (0, 1, or 2)

Return Value:

    BatteryIndex =  0 - Battery A
                    1 - Battery B
                    2 - Battery C
                    3 - Battery D
                   FF - No Battery

--*/
{
    UCHAR   batteryIndex;

    PAGED_CODE();

    // Assume if SelectorInfo supports 4 batteries, use SelectorBits4 table
    if (Selector->SelectorInfo & BATTERY_D_PRESENT) {
        batteryIndex = SelectorBits4[SelectorNibble].BatteryIndex;
    } else {
        batteryIndex = SelectorBits[SelectorNibble].BatteryIndex;
    }

    // If it's valid
    if (batteryIndex != BATTERY_NONE) {

        // return index for First Battery
        if (SimultaneousIndex == 0) {
            return (batteryIndex & 3);

        // return index for Second Battery
        } else if (SimultaneousIndex == 1) {
            batteryIndex = (batteryIndex >> 2) & 3;
            if (batteryIndex != BATTERY_A) {
                return (batteryIndex);
            }

        // return index for Third Battery
        } else if (SimultaneousIndex == 2) {
            batteryIndex = (batteryIndex >> 2) & 3;
            if (batteryIndex != BATTERY_A) {
                return (batteryIndex);
            }
        }
    }

    // return no battery index
    return (BATTERY_NONE);
}



BOOLEAN
SmbBattReverseLogic (
    IN PBATTERY_SELECTOR    Selector,
    IN ULONG                SelectorNibble
)
/*++

Routine Description:

    This routine is provided as a helper routine to determine the reverse
    logic on a given selector nibble, based on the number of batteries
    supported in the system.

Arguments:

    Selector            - Structure defining selector address and commands

    SelectorNibble      - The nibble of the SelectorState, moved to the low
                          order 4 bits, to check reverse logic on.

Return Value:

    FALSE if the nibble is normal
    TRUE if the nibble is inverted

--*/
{

    PAGED_CODE();

    // Assume if SelectorInfo supports 4 batteries, use SelectorBits4 table
    if (Selector->SelectorInfo & BATTERY_D_PRESENT) {
        return (SelectorBits4[SelectorNibble].ReverseLogic);
    } else {
        return (SelectorBits[SelectorNibble].ReverseLogic);
    }
}



NTSTATUS
SmbBattAcquireGlobalLock (
    IN  PDEVICE_OBJECT LowerDeviceObject,
    OUT PACPI_MANIPULATE_GLOBAL_LOCK_BUFFER GlobalLock
)
/*++

Routine Description:

    Call ACPI driver to obtain the global lock

    Note: This routine can be called at dispatch level

Arguments:

    LowerDeviceObject - The FDO to pass the request to.

Return Value:

    Return Value from IOCTL.

--*/
{
    NTSTATUS            status;
    PIRP                irp;
    PIO_STACK_LOCATION  irpSp;
    KEVENT              event;

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

    //
    // We wish to acquire the lock
    //
    GlobalLock->Signature = ACPI_ACQUIRE_GLOBAL_LOCK_SIGNATURE;
    GlobalLock->LockObject = NULL;

    //
    // setup the irp
    //

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoAllocateIrp (LowerDeviceObject->StackSize, FALSE);
    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    irpSp = IoGetNextIrpStackLocation(irp);
    irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
    irpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK;
    irpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
    irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
    irp->AssociatedIrp.SystemBuffer = GlobalLock;
    IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);

    //
    // Send to ACPI driver
    //
    IoCallDriver (LowerDeviceObject, irp);
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
    status = irp->IoStatus.Status;
    IoFreeIrp (irp);

    if (!NT_SUCCESS(status)) {
        BattPrint(
            BAT_ERROR,
            ("SmbBattAcquireGlobalLock: Acquire Lock failed, status = %08x\n",
             status )
            );
    }

    BattPrint (BAT_TRACE, ("SmbBattAcquireGlobalLock: Returning %x\n", status));

    return status;
}



NTSTATUS
SmbBattReleaseGlobalLock (
    IN PDEVICE_OBJECT LowerDeviceObject,
    IN PACPI_MANIPULATE_GLOBAL_LOCK_BUFFER GlobalLock
)
/*++

Routine Description:

    Call ACPI driver to release the global lock

Arguments:

    LowerDeviceObject - The FDO to pass the request to.

Return Value:

    Return Value from IOCTL.

--*/
{
    NTSTATUS            status;
    PIRP                irp;
    PIO_STACK_LOCATION  irpSp;
    KEVENT              event;

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

    //
    // We wish to acquire the lock
    //
    GlobalLock->Signature = ACPI_RELEASE_GLOBAL_LOCK_SIGNATURE;

    //
    // setup the irp
    //

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoAllocateIrp (LowerDeviceObject->StackSize, FALSE);
    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    irpSp = IoGetNextIrpStackLocation(irp);
    irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
    irpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_RELEASE_GLOBAL_LOCK;
    irpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
    irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
    irp->AssociatedIrp.SystemBuffer = GlobalLock;
    IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);

    //
    // Send to ACPI driver
    //
    IoCallDriver (LowerDeviceObject, irp);
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
    status = irp->IoStatus.Status;
    IoFreeIrp (irp);

    if (!NT_SUCCESS(status)) {
        BattPrint(
            BAT_ERROR,
            ("SmbBattReleaseGlobalLock: Acquire Lock failed, status = %08x\n",
             status )
            );
    }

    BattPrint (BAT_TRACE, ("SmbBattReleaseGlobalLock: Returning %x\n", status));

    return status;
}

⌨️ 快捷键说明

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