如何手动处理MacBook上所有插入的USB设备

时间:2019-01-05 00:21:48

标签: c swift macos usb

我的问题是我想手动处理插入USB设备时的处理方式。我不希望操作系统对插入的USB设备做任何事情,只能在出现以下情况时通知我它们的类型和ID。它们已插入。然后从那里,我可以选择适当的驱动程序来应用它,或者使用自定义代码手动对其进行操作。

我已经读过this关于MacOS如何处理USB的信息,它说:

  

如果您希望自己的驱动程序在其他人之上被选中,那么您要做的就是为驱动程序所用的设备添加键值对,这将使您的驱动程序获得很高的分数。通常,只需为您的供应商ID /模型输入密钥就足够了。但是,我认为您可以重写匹配方法(设备驱动程序用一组受限的C ++编写),以使您的驱动程序得分很高。

我还找到了这3个库,以获取有关USB驱动器中的事件的通知:

我只是不确定这些库是否会发生任何事情之前(自动选择并应用任何设备驱动程序)中断由操作系统处理的所有USB设备。除了要访问上述库之一中的设备及其类型之外,我什么都不想发生,但是我不确定他们是否会这样做。

除此以外,我没有太多代码:

var usb = require('usb')
usb.getDeviceList()

但是我想这将在操作系统已经选择并为其应用默认驱动程序后 解决插入的设备。我想做这样的事情:

usb.blockDefaultOSDeviceHandler()
usb.on('device:plugged_in', function(data){
  if (data.type == 'keyboard') {
    if (data.modelNumber == '123') {
      // allow
      usb.applyKeyboardDriver('abc', data.modelNumber)
      usb.on('keyboard:event', logKeyboardEvent)
    } else {
      throw new Error('Unrecognized device')
    }
  } 
})

我希望操作系统会中断所有默认行为,以便我可以自己处理插入USB设备时应执行的操作。原因是因为也许USB设备是键盘,它会自动开始输入某些键。我想知道它是键盘,需要密码和我为此预先批准的特定驱动程序。这样的东西。

在操作系统应用其默认处理规则之前,我想访问所有新插入的USB设备 。然后可以编写代码来手动处理每个插入设备的操作。

如果只有在C语言中才有可能,那么知道如何做到这一点,而不是使用node.js会更好。

1 个答案:

答案 0 :(得分:0)

答案在有关USB设备的Apple文档中。基本上,您想覆盖自定义驱动程序中的probe函数,让它返回最高分,以便覆盖所有其他驱动程序,并像平常一样实现该驱动程序。 Here是有关驱动程序选择和实例化过程的有用文档。

  

在使用设备或任何服务提供商之前,必须找到该设备的驱动程序并将其加载到内核中。 I / O套件定义了一种灵活的三相匹配过程,可将一组候选驱动程序缩小为一个或多个驱动程序。最终候选人(如果有多个候选人,则m   然后加载了符合条件的OST),并给了他们第一次管理设备或服务提供商的机会。

     

...

     

每个被视为可加载内核扩展(KEXT)的设备驱动程序,必须定义一个或多个个性,以指定其可以支持的设备类型。

     

...

     

由于一个驱动程序可以包含多个匹配的字典,每个字典为该驱动程序定义不同的个性,因此可以为不同的设备加载相同的驱动程序代码。为了竞争起见,I / O套件将每个性格视为驱动程序。如果任何一种个性都符合该家族要求的所有属性,则将加载驱动程序的代码,并有机会为该设备运行。

     

...

     

性格的一个共同属性是探究得分。探测分数是一个整数,反映了驾驶员驱动特定设备的适合程度。驱动程序可能具有其初始探测得分值,并且可以实现探测功能,使其能够基于其驱动设备的适用性来修改此默认值。与其他匹配值一样,探针得分特定于每个家庭。这是因为一旦匹配超过了课程匹配阶段,只有来自同一家庭的个性才可以竞争。有关探测得分和驱动程序在探测功能中的作用的详细信息,请参阅设备探测。

     

...

     

在引导时以及在任何时候添加或删除设备时,对于每个检测到的设备(或其他服务提供商)都会发生驱动程序匹配的过程。该过程会在/ System / Library / Extensions中动态找到最适合设备或服务的驱动程序。

     

...

     

如“驱动程序匹配”一章“体系结构概述”中所述,当总线控制器驱动程序扫描其总线并检测到连接的新设备时,将触发匹配过程。对于每个检测到的设备,控制器驱动程序都会创建一个小块。然后,I / O套件启动匹配过程,并从设备获取值以用于匹配(例如,检查PCI寄存器)。找到适合于该块的驱动程序后,将注册并加载该驱动程序。相应地,该驱动程序可以创建自己的块(可能是通过从其家族继承的行为)来进行的,从而启动匹配过程以找到合适的驱动程序。

     

...

     

匹配过程如下:

     
      
  1. 类别匹配步骤中,I / O Kit通过消除提供程序服务的错误类别的驱动程序(即nub)来缩小潜在驱动程序的范围。例如,当搜索USB驱动程序时,可以排除所有SCSI类的驱动程序对象。
  2.   
  3. 被动匹配步骤中,检查驾驶员的个性(在驾驶员的XML信息属性列表中指定),以了解提供者家庭的特定属性。例如,个性可以指定特定的供应商名称。
  4.   
  5. 主动匹配步骤中,将参照与之匹配的小节调用驾驶员的探测功能。此功能使驱动程序可以与设备通信并验证它是否可以驱动设备。驱动程序返回一个反映其驱动设备能力的探测得分。有关更多信息,请参见设备探测。在主动匹配过程中,I / O套件会加载并探测所有候选驱动程序,然后按从最高到最低探测得分的顺序对其进行排序。
  6.   
     

...

     

然后,I / O套件选择探针得分最高的其余驱动程序并启动它。如果驱动程序成功启动,它将被添加到I / O注册表中,并且所有剩余的驱动程序候选都将被丢弃。如果启动失败,则启动具有最高探针得分的驱动程序,依此类推。如果可能的候选者池中有多个驱动程序,则通用的驱动程序通常会输给更具体的驱动程序,前提是两者都声称能够驱动设备。

     

...

     

探测得分是一个有符号的32位整数,初始化为驾驶员的性格中指定的值(如果未显式初始化,则为零)。

     

...

     

如果探测成功,驱动程序将在其探测功能中返回驱动程序对象(IOService *),否则返回零。返回的对象通常是驱动程序本身,但是驱动程序可以返回另一个更适合提供者的驱动程序。探针得分是一个输入-输出参数,该探针可以根据其发现的有关设备的内容进行修改。

     

...

     

在所有驱动程序都对设备进行探测之后,将附加具有最高探测得分的设备,并调用必须由所有驱动程序实现的启动功能。启动功能将初始化设备硬件并为操作做好准备。如果驱动程序成功启动,则返回true;否则,返回true。其余的候选驱动程序实例将被丢弃,成功启动的驱动程序将继续运行。如果驱动程序无法初始化硬件,则必须使硬件保持在调用start时的状态,并返回false。然后将失败的驱动程序卸下并丢弃,并为探测得分第二高的候选驱动程序提供启动机会。

除非使用Node.js(可能)在节点中使用C / C ++扩展名,否则无法完成此操作。