首页
社区
课程
招聘
ACPI WMI 杂记 (对 OEM Bios导出给Windows的接口----导出OEM内部使用的WMI接口 一文补全)
发表于: 2020-8-8 16:53 6243

ACPI WMI 杂记 (对 OEM Bios导出给Windows的接口----导出OEM内部使用的WMI接口 一文补全)

2020-8-8 16:53
6243

    关于WMI ACPI,建议先通读:1.<[原创]BIOS知识点滴Follow Bini系列之---WMI ACPI>了解WMI ACPI能提供什么后,再参考MSDN 2.<Windows Instrumentation: WMI and ACPI>,另外,3.<文件系统驱动编程基础篇之4——Wmi管理规范 mof文件>也可以作为1.的补充。需要特别说明的,1.中留了demo程序,一般读者没有环境测试(也不建议用真实机器测试,万一不开机损失挺大的),这时倒可以参考我的文章<解密OEM Bios导出给Windows的接口----导出OEM内部使用的WMI接口>,从现有BIOS中提取MOF和WMI接口用于学习。

    本文应该是<解密OEM Bios导出给Windows的接口----导出OEM内部使用的WMI接口>一文的原理补充和总结,主要补充一下MOF资源文件和ACPI中各个WMI接口的关系。要厘清他们的关系,得先用<[原创]BIOS知识点滴Follow Bini系列之---WMI ACPI>文中使用的代码片:

Mof描述文件:

ASL(WMI)文件:

MOF描述文件是最终导出给用户调用的接口,WMI ACPI中的ASL code部分则是MOF所描述的Class的实现。如果读者反复阅读和对比MOF/ASL文件,会觉得他们很像动态链接库:MOF文件如同Class头文件,负责约定和导出调用接口。ASL如同DLL文件负责DLL函数的实现。至于_WDG对象,则充当了DLL的EAT(函数地址表)的中间人角色(其实还依赖于_WDG对象中嵌入式MOF文件,后面会提到),当然EAT表中可能会有若干表项组成,_WDG对象也是如此。_WDG中单个表项具有如下数据结构:

当所有表项结合在一起,形成一个巨大的Mapper[N]数组,这个数组最终构成_WDG对象。而Mof资源文件的编写者(无疑是OEM厂商了),会为_WDG对象中每个Mapper[i]制作Class。每个Class都有Mapper[i].guid对应。

WMI的调用者(想象成DLL的调用者),根据MOF资源文件(想象成Class头文件)描述的WMI接口,以ClassName的形式去调用ASL code的(想象成DLL文件)时,ACPI.sys会到ACPI命名空间中先查找_WDG对象。

找到_WDG对象后,遍历其Mapper[N]数组,并定位到Mapper[i].Flags==0的数组项,该数组项指向一块buffer,buffer中包含编译后的MOF文件,MSDN称之为嵌入式MOF资源。

ACPI.sys从嵌入式Mof资源中查找匹配的ClassName(因为上层使用Class调用WMI)。大家不妨回忆前面Mof资源描述文件中含有guid和ClassName

获得ClassName后,进一步可以获得接口名的guid,然后回到_WDG的Mapper[N]数组中,根据Mapper[i].guid查找与调用者GUID相匹配的数组项。

匹配到GUID后,ACPI.sys会取出Mapper[i].ObjectID成员,成员中包含xx值,ACPI.sys将WQ/WS和xx拼接,形成WQxx或者WSxx,然后去ACPI命名空间调用相应的WQxx或者WSxx方法。

<[原创]BIOS知识点滴Follow Bini系列之---WMI ACPI>作为一个demo程序,_WDG对象的Mapper[N]数组只有一个数组项,没有体现上述搜索过程。所以,我换一个N>1的例子,嗯,那就用从<解密OEM Bios导出给Windows的接口----导出OEM内部使用的WMI接口>提取出来的ThinkPad的_WDG对象:


这是ThinkPad T460部分_WDG对象,其中有5个数组项,最后是一个特殊数组项,暂不讨论。其他几个数组项对应的WMI接口如下:

由于ThinkPad用的是嵌入式MOF,我无法获得原始的Mof文件(如同demowmi.mof),但是运行这段vbs脚本,可以推测出mof可能的内容:


    借由Wmi Code generate生成的ACPI WMI接口测试脚本中有不少InstanceOf\instance语句:

(以下为个人理解:)前面说过Mof资源文件为_WDG对象的每个数组项编辑一个Class。套用面向对象思维,必须创建类对象(实例化Class)才能访问其成员,所以vbs脚本中

应该就是创建Mof资源文件中描述的Lenovo_PlatformSetting类对象,并命名为enumSet。

如果把enumSet理解为某个Class的对象,那么vbs脚本中的instance就是Mof资源文件中描述的Class的各个成员变量。需要注意的是:阅读vbs测试脚本时,我们发现它是以循环遍历的方式访问类对象的各个成员的,所以,我们应该认为类对象中成员变量的类型一致,因此可以构成一个数组。另外,特殊情况下,如果数组中只有一项,那么数组将简化为普通变量。为了与_WDG对象中的Mapper[N]数组区分,我们用Item数组表示Class中类型一致的成员变量。Item数组的长度(即instance的数量或者说for循环的次数)在_WDG对象的Mapper[i].instanceCount中有指定:

以ThinkPad T460P为例:

Class:Lenovo_PlatformSetting.InstanceCount=0x0A;

Class:Lenovo_SetPlarformSeting.InstanceCount=0x01;

这些都可以在_WDG对象Mapper[i].InstanceCount中找到线索:

虽然,Item数组的长度随着Mapper[i].InstanceCount的值可以固定下来,但是Item数组的数组项类型却没有指定。简单的可能是UINT类型的Item数组,复杂的可能是Buffer或者Package类型的Item(再次注意,我这里用的是Item数组)。仍以ThinkPad T460P Lenovo_PlarformSeting类为例,Lenovo_PlarformSeting类函数为Lenovo_PlarformSeting,在WMI ACPI中的实现为:Method (WQA9, 1, NotSerialized)

Method WQA9根据唯一的参数Arg0,从ACPI命名空间ITEM对象中获取数值。至于ITEM对象,它长这样


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//