我想使用内核控件将内核扩展中的消息发送到用户程序。调用EINVAL
时,我遇到ctl_enqueuedata
错误。
我已经设置了内核控件,我正在尝试使用ctl_enqueuedata
通过它发送消息。我正在设置
ep_ctl.ctl_flags = 0
在传递给ctl_register
之前,the documents建议,应该导致ctl_unit
自动设置。
引用kern_control.h
:
对于动态分配的控件ID,请勿设置CTL_FLAG_REG_ID_UNIT标志。
static struct kern_ctl_reg ep_ctl;
static kern_ctl_ref kctlref;
...
errno_t error;
bzero(&ep_ctl, sizeof(ep_ctl)); // sets ctl_unit to 0
ep_ctl.ctl_id = 0;
ep_ctl.ctl_unit = 0;
strncpy(ep_ctl.ctl_name, CONTROL_NAME, strlen(CONTROL_NAME));
ep_ctl.ctl_flags = 0x0; // not CTL_FLAG_REG_ID_UNIT so unit gets supplied. Not CTL_FLAG_PRIVILEGED either.
ep_ctl.ctl_send = EPHandleSend;
ep_ctl.ctl_getopt = EPHandleGet;
ep_ctl.ctl_setopt = EPHandleSet;
ep_ctl.ctl_connect = EPHandleConnect;
ep_ctl.ctl_disconnect = EPHandleDisconnect;
error = ctl_register(&ep_ctl, &kctlref);
printf("setupControl %d\n", error);
当我致电ctl_register
时,它会返回0
确定。
当我致电ctl_enqueuedata
时,传入我的struct kern_ctl_reg
我得到22,即EINVAL
。其中一个论点似乎是不正确的。我传递的其他参数是静态测试字符串及其数据长度和零标记。
int result = ctl_enqueuedata(kctlref, ep_ctl.ctl_unit, filename, length, 0x0);
我ep_ctl
的{{1}}的值为.ctl_unit
,0
的值为.ctl_id
。可能是传递给6
的{{1}}值无效/未初始化了吗?
ctl_unit
说ctl_unit:
对于动态分配的控件ID
,将忽略此字段
这表明它无论如何都不是必需的?
我在初始化ep_ctl时遗漏了什么吗?
答案 0 :(得分:1)
我认为你提供的错误值是ctl_enqueuedata()
的第二个参数。您必须记住ep_ctl.ctl_unit
回调中的struct sockaddr_ctl::sc_unit
而不是EPHandleConnect()
,而这应该是您应该传递到ctl_enqueuedata()
的内容。
答案 1 :(得分:0)
我建议使用OSX的内核调试工具来弄清楚这里发生了什么。这将让您浏览相关的内核代码,并告诉您拒绝输入的位置。