ligius- / lenovo-backlight-control

Simple wrapper for Windows 8/10 to control the Thinkpad keyboard backlight
Apache License 2.0
40 stars 14 forks source link

For newer laptops, How to do? #9

Closed chs72 closed 2 years ago

chs72 commented 2 years ago

For newer laptops, How to do?

PS C:\Windows\system32> $assembly = [System.Reflection.Assembly]::LoadFrom("c:\Users\All Users\Lenovo\ImController\Plugins\IdeaNotebookPlugin\x64\IdeaNotebookPlugin.dll" ) PS C:\Windows\system32> $agent = $assembly.GetTypes()[0].GetMethod("GetInstance").Invoke($null,$null) PS C:\Windows\system32> PS C:\Windows\system32> PS C:\Windows\system32> PS C:\Windows\system32> Add-Type -Path "c:\Users\All Users\Lenovo\ImController\Plugins\IdeaNotebookPlugin\x64\IdeaNotebookPlugin.dll" PS C:\Windows\system32> Add-Type -Path "c:\Users\All Users\Lenovo\ImController\Plugins\IdeaNotebookPlugin\x64\Contract_Keyboard.dll" PS C:\Windows\system32> $BindingFlags = 'static','nonpublic','instance' PS C:\Windows\system32> [Lenovo.Modern.Plugins.IdeaNotebookPlugin.NativeHelper]::DoDeviceIoControl[0]

OverloadDefinitions

static bool DoDeviceIoControl[T1, T2](System.IntPtr handler, uint32 ioControlCode, [ref] T1 input, [ref] T2 output, [ref] uint32 returned) static bool DoDeviceIoControl[T1, T2](System.IntPtr handler, uint32 ioControlCode, [ref] T1 input, [ref] T2 output) static bool DoDeviceIoControl[T1](System.IntPtr handler, uint32 ioControlCode, [ref] T1 input, System.IntPtr outputBuffer, uint32 outputBufferSize, [ref] uint32 returned) static bool DoDeviceIoControl[T1](System.IntPtr handler, uint32 ioControlCode, [ref] T1 input, System.IntPtr outputBuffer, uint32 outputBufferSize) static bool DoDeviceIoControl[T2](System.IntPtr handler, uint32 ioControlCode, System.IntPtr inputBuffer, uint32 inputBufferSize, [ref] T2 output, [ref] uint32 returned) static bool DoDeviceIoControl[T2](System.IntPtr handler, uint32 ioControlCode, System.IntPtr inputBuffer, uint32 inputBufferSize, [ref] T2 output) static bool DoDeviceIoControl(System.IntPtr handler, uint32 ioControlCode, System.IntPtr inputBuffer, uint32 inputBufferSize, System.IntPtr outputBuffer, uint32 outputBufferSize, [ref] uint32 returned) static bool DoDeviceIoControl(System.IntPtr handler, uint32 ioControlCode, System.IntPtr inputBuffer, uint32 inputBufferSize, System.IntPtr outputBuffer, uint32 outputBufferSize)

ligius- commented 2 years ago

I don't remember, quite a while has passed since I reversed-engineered parts of the "LenovoVantage". There are generally two methods to control embedded processor, one of them calls the actual functions through Vantage, the other one talks directly to the chip in binary.

Example for method 1:

$agent = $assembly.GetTypes()[0].GetMethod("GetInstance").Invoke($null,$null)
$request = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.KeyboardSettingsRequest
$list = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.SettingList
$request.List = $list
$item0 = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.Setting
$item1 = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.Setting
$list.Items.Add($item0)
$list.Items.Add($item1)
$item0.key = "KeyboardBacklightLevel"
$item0.value = "OneLevel"  
$item1.key = "KeyboardBacklightStatus"
$item1.value = "Level_1"  
$agent.SetBacklightStatus($request)

Incomplete example and notes for method 2:

$native::DoDeviceIoControl([IntPtr]$ptr,[UInt32]2198872296, [ref]8, [ref]0) - lights bright and then off
$native::DoDeviceIoControl([IntPtr]$ptr,[UInt32]2198872296, [ref]8, [ref]0) - lights on (dim)

backlight: 8 off, 9 on
fnlock: 14 on, 15 off
status: 2
gettouchpad: 6
struct{5, 0 or 1} - enable/disable touchpad
ligius- commented 2 years ago

Just as an interesting note, on my newer Yoga, the keyboard backlight behaves quite strangely. It should officially have 3 levels (0,1,2) but there is also an intermediary "0.5" level. This can be even reproduced in Vantage by turning the backlight on, then off, then on again. It behaves the same if done through PowerShell. I believe this is a bug in the firmware and they did not intend it to work this way. The 0.5 setting gets reset on reboot and back to level 1. I discovered this about one year ago, wrote to Lenovo but heard nothing back from them. Was hoping there is official support for this backlight level, but I highly doubt it.