1. Dell AWCC WMI 接口驱动程序 (alienware-wmi)¶
1.1. 简介¶
WMI 设备 WMAX 已在许多 Alienware 和 Dell 的 G 系列型号中实现。在这些型号中,已识别出两种实现。第一个由较旧的系统使用,处理 HDMI、亮度、RGB、放大器和深度睡眠控制。第二个由较新的系统使用,主要处理散热、超频和 GPIO 控制。
据推测,后者由 Alienware Command Center (AWCC) 用于管理制造商预定义的散热配置文件。alienware-wmi 驱动程序通过平台配置文件 API 公开 Thermal_Information 和 Thermal_Control 方法,以模拟 AWCC 的行为。
这个较新的接口,名为 AWCCMethodFunction,已被逆向工程,因为 Dell 没有提供任何官方文档。我们将尽最大努力描述其已发现的内部工作原理。
注意
以下方法描述可能不完整,并且某些操作在不同设备之间具有不同的实现。
1.1.1. WMI 接口描述¶
可以使用 bmfdec 实用程序从嵌入式二进制 MOF (bmof) 数据中解码 WMI 接口描述
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{A70591CE-A997-11DA-B012-B622A1EF5492}")]
class AWCCWmiMethodFunction {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(13), Implemented, read, write, Description("Return Overclocking Report.")] void Return_OverclockingReport([out] uint32 argr);
[WmiMethodId(14), Implemented, read, write, Description("Set OCUIBIOS Control.")] void Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(15), Implemented, read, write, Description("Clear OC FailSafe Flag.")] void Clear_OCFailSafeFlag([out] uint32 argr);
[WmiMethodId(19), Implemented, read, write, Description("Get Fan Sensors.")] void GetFanSensors([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(20), Implemented, read, write, Description("Thermal Information.")] void Thermal_Information([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(21), Implemented, read, write, Description("Thermal Control.")] void Thermal_Control([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(23), Implemented, read, write, Description("MemoryOCControl.")] void MemoryOCControl([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(26), Implemented, read, write, Description("System Information.")] void SystemInformation([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(28), Implemented, read, write, Description("Power Information.")] void PowerInformation([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(32), Implemented, read, write, Description("FW Update GPIO toggle.")] void FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(33), Implemented, read, write, Description("Read Total of GPIOs.")] void ReadTotalofGPIOs([out] uint32 argr);
[WmiMethodId(34), Implemented, read, write, Description("Read GPIO pin Status.")] void ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(35), Implemented, read, write, Description("Read Chassis Color.")] void ReadChassisColor([out] uint32 argr);
[WmiMethodId(36), Implemented, read, write, Description("Read Platform Properties.")] void ReadPlatformProperties([out] uint32 argr);
[WmiMethodId(37), Implemented, read, write, Description("Game Shift Status.")] void GameShiftStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(128), Implemented, read, write, Description("Caldera SW installation.")] void CalderaSWInstallation([out] uint32 argr);
[WmiMethodId(129), Implemented, read, write, Description("Caldera SW is released.")] void CalderaSWReleased([out] uint32 argr);
[WmiMethodId(130), Implemented, read, write, Description("Caldera Connection Status.")] void CalderaConnectionStatus([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(131), Implemented, read, write, Description("Surprise Unplugged Flag Status.")] void SurpriseUnpluggedFlagStatus([out] uint32 argr);
[WmiMethodId(132), Implemented, read, write, Description("Clear Surprise Unplugged Flag.")] void ClearSurpriseUnpluggedFlag([out] uint32 argr);
[WmiMethodId(133), Implemented, read, write, Description("Cancel Undock Request.")] void CancelUndockRequest([out] uint32 argr);
[WmiMethodId(135), Implemented, read, write, Description("Devices in Caldera.")] void DevicesInCaldera([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(136), Implemented, read, write, Description("Notify BIOS for SW ready to disconnect Caldera.")] void NotifyBIOSForSWReadyToDisconnectCaldera([out] uint32 argr);
[WmiMethodId(160), Implemented, read, write, Description("Tobii SW installation.")] void TobiiSWinstallation([out] uint32 argr);
[WmiMethodId(161), Implemented, read, write, Description("Tobii SW Released.")] void TobiiSWReleased([out] uint32 argr);
[WmiMethodId(162), Implemented, read, write, Description("Tobii Camera Power Reset.")] void TobiiCameraPowerReset([out] uint32 argr);
[WmiMethodId(163), Implemented, read, write, Description("Tobii Camera Power On.")] void TobiiCameraPowerOn([out] uint32 argr);
[WmiMethodId(164), Implemented, read, write, Description("Tobii Camera Power Off.")] void TobiiCameraPowerOff([out] uint32 argr);
};
其中一些方法变得非常复杂,因此我们将使用大致类似于原始 ASL 代码的伪代码来描述它们。
以下文档中未描述的方法具有未知的行为。
1.1.2. 参数结构¶
所有输入参数都具有类型 uint32,并且它们在方法之间的结构非常相似。通常,第一个字节对应于方法执行的特定操作,随后的字节对应于传递给此操作的参数。例如,如果操作的代码为 0x01 并且需要 ID 0xA0,则您将传递给方法的参数为 0xA001。
1.2. 散热方法¶
1.2.1. WMI 方法 Thermal_Information([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0x01:
argr = 1
if BYTE_0(arg2) == 0x02:
argr = SYSTEM_DESCRIPTION
if BYTE_0(arg2) == 0x03:
if BYTE_1(arg2) == 0x00:
argr = FAN_ID_0
if BYTE_1(arg2) == 0x01:
argr = FAN_ID_1
if BYTE_1(arg2) == 0x02:
argr = FAN_ID_2
if BYTE_1(arg2) == 0x03:
argr = FAN_ID_3
if BYTE_1(arg2) == 0x04:
argr = SENSOR_ID_CPU | 0x0100
if BYTE_1(arg2) == 0x05:
argr = SENSOR_ID_GPU | 0x0100
if BYTE_1(arg2) == 0x06:
argr = THERMAL_MODE_QUIET_ID
if BYTE_1(arg2) == 0x07:
argr = THERMAL_MODE_BALANCED_ID
if BYTE_1(arg2) == 0x08:
argr = THERMAL_MODE_BALANCED_PERFORMANCE_ID
if BYTE_1(arg2) == 0x09:
argr = THERMAL_MODE_PERFORMANCE_ID
if BYTE_1(arg2) == 0x0A:
argr = THERMAL_MODE_LOW_POWER_ID
if BYTE_1(arg2) == 0x0B:
argr = THERMAL_MODE_GMODE_ID
else:
argr = 0xFFFFFFFF
if BYTE_0(arg2) == 0x04:
if is_valid_sensor(BYTE_1(arg2)):
argr = SENSOR_TEMP_C
else:
argr = 0xFFFFFFFF
if BYTE_0(arg2) == 0x05:
if is_valid_fan(BYTE_1(arg2)):
argr = FAN_RPM()
if BYTE_0(arg2) == 0x06:
skip
if BYTE_0(arg2) == 0x07:
argr = 0
If BYTE_0(arg2) == 0x08:
if is_valid_fan(BYTE_1(arg2)):
argr = 0
else:
argr = 0xFFFFFFFF
if BYTE_0(arg2) == 0x09:
if is_valid_fan(BYTE_1(arg2)):
argr = FAN_UNKNOWN_STAT_0()
else:
argr = 0xFFFFFFFF
if BYTE_0(arg2) == 0x0A:
argr = THERMAL_MODE_BALANCED_ID
if BYTE_0(arg2) == 0x0B:
argr = CURRENT_THERMAL_MODE()
if BYTE_0(arg2) == 0x0C:
if is_valid_fan(BYTE_1(arg2)):
argr = FAN_UNKNOWN_STAT_1()
else:
argr = 0xFFFFFFFF
操作 0x02 返回具有以下结构的系统描述缓冲区
out[0] -> Number of fans
out[1] -> Number of sensors
out[2] -> 0x00
out[3] -> Number of thermal modes
操作 0x03 按顺序列出所有可用的风扇 ID、传感器 ID 和散热配置文件代码,但不同的型号可能具有不同数量的风扇和散热配置文件。以下是已知的范围
风扇 ID:从 2 到 4
传感器 ID:2
散热配置文件代码:从 1 到 7
总共,BYTE_1(ARG2) 的范围可能从 0x5 到 0xD,具体取决于型号。
1.2.2. WMI 方法 Thermal_Control([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0x01:
if is_valid_thermal_profile(BYTE_1(arg2)):
SET_THERMAL_PROFILE(BYTE_1(arg2))
argr = 0
if BYTE_0(arg2) == 0x02:
if is_valid_fan(BYTE_1(arg2)):
SET_FAN_SPEED_MULTIPLIER(BYTE_2(arg2))
argr = 0
else:
argr = 0xFFFFFFFF
注意
虽然您可以使用此方法手动更改风扇速度倍增器,但 Dell 的 BIOS 往往会覆盖这些更改。
以下是已知的散热配置文件代码
CUSTOM 0x00
BALANCED_USTT 0xA0
BALANCED_PERFORMANCE_USTT 0xA1
COOL_USTT 0xA2
QUIET_USTT 0xA3
PERFORMANCE_USTT 0xA4
LOW_POWER_USTT 0xA5
QUIET 0x96
BALANCED 0x97
BALANCED_PERFORMANCE 0x98
PERFORMANCE 0x99
GMODE 0xAB
通常,如果型号不支持前四个配置文件,它们将支持用户可选散热表 (USTT) 配置文件,反之亦然。
GMODE 取代了 G 系列笔记本电脑中的 PERFORMANCE。
1.2.3. WMI 方法 GameShiftStatus([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0x1:
TOGGLE_GAME_SHIFT()
argr = GET_GAME_SHIFT_STATUS()
if BYTE_0(arg2) == 0x2:
argr = GET_GAME_SHIFT_STATUS()
Game Shift Status 不会更改风扇速度配置文件,但它可能是某种 CPU/GPU 电源配置文件。尚未进行基准测试。
此方法仅存在于 Dell 的 G 系列笔记本电脑上,并且其实现暗示 GMODE 散热配置文件可用,即使 Thermal_Information 的操作 0x03 没有列出它。
Dell G 系列笔记本电脑上的 G 键也会更改 Game Shift 状态,因此两者直接相关。
1.2.4. WMI 方法 GetFanSensors([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0x1:
if is_valid_fan(BYTE_1(arg2)):
argr = 1
else:
argr = 0
if BYTE_0(arg2) == 0x2:
if is_valid_fan(BYTE_1(arg2)):
if BYTE_2(arg2) == 0:
argr == SENSOR_ID
else
argr == 0xFFFFFFFF
else:
argr = 0
1.3. 超频方法¶
警告
这些方法尚未经过测试,并且仅部分经过逆向工程。
1.3.1. WMI 方法 Return_OverclockingReport([out] uint32 argr)¶
CSMI (0xE3, 0x99)
argr = 0
CSMI 是一种未知操作。
1.3.2. WMI 方法 Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr)¶
CSMI (0xE3, 0x99)
argr = 0
CSMI 是一种未知操作。
1.3.3. WMI 方法 Clear_OCFailSafeFlag([out] uint32 argr)¶
CSMI (0xE3, 0x99)
argr = 0
CSMI 是一种未知操作。
1.3.4. WMI 方法 MemoryOCControl([in] uint32 arg2, [out] uint32 argr)¶
AWCC 支持内存超频,但此方法非常复杂,尚未被破译。
1.4. GPIO 方法¶
这些方法可能与通过 GPIO 设备进行的某种固件更新系统有关。
警告
这些方法尚未经过测试,并且仅部分经过逆向工程。
1.4.1. WMI 方法 FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0:
if BYTE_1(arg2) == 1:
SET_PIN_A_HIGH()
else:
SET_PIN_A_LOW()
if BYTE_0(arg2) == 1:
if BYTE_1(arg2) == 1:
SET_PIN_B_HIGH()
else:
SET_PIN_B_LOW()
else:
argr = 1
1.4.2. WMI 方法 ReadTotalofGPIOs([out] uint32 argr)¶
argr = 0x02
1.4.3. WMI 方法 ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr)¶
if BYTE_0(arg2) == 0:
argr = PIN_A_STATUS
if BYTE_0(arg2) == 1:
argr = PIN_B_STATUS
1.5. 其他信息方法¶
1.5.1. WMI 方法 ReadChassisColor([out] uint32 argr)¶
argr = CHASSIS_COLOR_ID
1.6. 致谢¶
感谢 AlexIII 记录和测试可用的散热配置文件代码。