我正在尝试从macOS的启动守护程序中读取当前的kPMSetClamshellSleepState
设置。我尝试了以下方法:
io_connect_t connection = IO_OBJECT_NULL;
io_service_t pmRootDomain = IOServiceGetMatchingService(kIOMainPortDefault,
IOServiceMatching("IOPMrootDomain"));
if(pmRootDomain)
{
kern_return_t res = IOServiceOpen(pmRootDomain, current_task(), 0, &connection);
if(res == KERN_SUCCESS)
{
uint64_t outputs[1] = { };
uint32_t num_outputs = 1;
res = IOConnectCallScalarMethod(connection,
kPMSetClamshellSleepState,
NULL,
0,
outputs,
&num_outputs);
if(res == KERN_SUCCESS)
{
//Done
}
//Close connection
IOServiceClose(connection);
}
IOObjectRelease(pmRootDomain);
}
但在本例中,对IOConnectCallScalarMethod
的调用返回0xE00002C2
、-536870206
或kIOReturnBadArgument
。
如何读取设置?任何建议。
1条答案
按热度按时间wgx48brx1#
I/O Kit用户客户端外部方法
对于I/O Kit用户/客户端的外部方法API以及可以传递给它的标量和结构输入或输出的组合,没有通用的语义可以推断。这个always取决于你要连接的特定
IOUserClient
子类,以及你要传递的特定方法选择器。在您的例子中,您正在处理
RootDomainUserClient
和选择器kPMSetClamshellSleepState
,其允许的参数定义如下:因此,您只能使用精确的1个标量输入来调用此选择器,而不能使用其他参数。而且,它的返回值不依赖于先前的状态。没有办法破解这个特定的界面来做你想做的事情。
翻盖状态
如果跟踪外部方法,您将发现状态存储在
IOPMRootDomain
对象的clamshellSleepDisableMask
字段中。我没有看到一个直接的用户空间访问器。它在
IOPMrootDomain::shouldSleepOnClamshellClosed()
函数中被引用,其状态反映在kAppleClamshellCausesSleepKey
/"AppleClamshellCausesSleep"
属性中。可以从用户空间使用IORegistryEntryCreateCFProperty
查询此属性。暴露属性的确切值还取决于一系列其他标志:
true
,clamshellSleepDisableMask
必须为false
clamshellSleepDisableMask
是true
之外,属性也可以是false
因此,你不能仅从这个属性100%准确地推断出
clamshellSleepDisableMask
,但也许这已经足够了。您还可以从我停止的IOPMRootDomain
源代码中找到线索,也许在另一个地方您可以推断出有关此标志状态的信息。值得注意的是,当更新上述值时,kIOPMMessageClamshellStateChange
消息显然会被传递给侦听器--也许响应这样的变化会让您找到一个可靠的解决方案。