【问题标题】:IOKit and getting unique ID'sIOKit 和获取唯一 ID
【发布时间】:2013-03-04 21:46:33
【问题描述】:

我正在使用:IOServiceGetMatchingServices

kr = IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceNameMatching("AppleUSBEHCI"), &io_objects);

我正在寻找如何找到有关内部 HD 的信息,因为上面会检测 USB 设备。

我似乎找不到可以告诉我这一点的清单或任何东西。

基本上我正在寻找一种从系统中获取唯一 ID 的方法。在 Windows 上,其他开发人员使用硬盘 ID。

谁能阐明这些价值观?

【问题讨论】:

  • 我认为这不是唯一识别 Mac 的好方法。 Mac 有一个序列号,应该可以通过编程方式获得(您可以在“关于此 Mac”和“系统报告”中看到它,即使更换硬盘也不会改变。还有更低的- T2 安全芯片上的唯一标识符 - 但我不知道如何获取它们。

标签: c++ macos iokit


【解决方案1】:

我相信您要做的是查看设备描述符并查看它是否具有序列号。由设备提供序列号,如果提供了序列号,则该序列号可能不是唯一的。如果设备有自定义描述符,那里也可能有用。

请参阅以下描述符: http://www.beyondlogic.org/usbnutshell/usb5.shtml

似乎有一个属性可以获取 HID 设备包装类上的序列号:

https://developer.apple.com/library/mac/#documentation/IOKit/Reference/IOHIDBase_header_reference/Reference/reference.html#//apple_ref/doc/uid/TP40012400

如果这不起作用,应该有一种方法可以直接访问 USB 设备并请求您需要的数据。

【讨论】:

  • 您能否详细说明您的答案?这些“设备描述符”在什么级别?他们是 IOKit 吗?低于那个?存储为一些二进制 blob,我们应该去某个地方吗?或者可能是我不知道的更高级别的 API? “HID”代表什么?我相信您回答中的 2-3 行介绍性内容可能会很有帮助
  • 我引用的所有内容都与 USB 协议有关,并不特定于 IOKit。检查上面的链接以获取有关描述符的更多信息。阅读此页面以了解 USB 和 HID 设备的背景:en.wikipedia.org/wiki/USB
  • 哦,谢谢。我对所有“外部的、可移动的硬盘驱动器”感兴趣,包括 USB、相机卡甚至旋转的旧 FireWire 驱动器……我是否需要为每个设备连接类型的“系列”编写特定代码以获得这样的基本诸如“序列号”之类的信息???
【解决方案2】:

在命令行中,您可以使用ioreg 工具来探索IO Kit 注册表。对于 Lion 或 Older,您还可以使用 Apple 硬件 IO 工具包中方便的 IORegistryExplorer GUI 工具。 (它在山狮上崩溃)

对于查看内部硬盘驱动器属性,这是一个很好的开始:

ioreg -irc IOAHCIBlockStorageDevice -w 0

在我的 MacBook Air 上产生的效果:

+-o IOAHCIBlockStorageDevice  <class IORegistryEntry:IOService:IOBlockStorageDevice:IOAHCIBlockStorageDevice, id 0x100000216, registered, matched, active, busy 0 (472 ms), retain 7>
  | {
  |   "IOCFPlugInTypes" = {"24514B7A-2804-11D6-8A02-003065704866"="SMARTLib.plugin"}
  |   "device-type" = "Generic"
  |   "IOStorageFeatures" = {"Unmap"=Yes}
  |   "Device Characteristics" = {"Logical Block Size"=512,"Product Name"="APPLE SSD TS256C                        ","Medium Type"="Solid State","Physical Block Size"=512,"SATA Features"=23,"Serial Number"="        X06S10H7THRZ","Product Revision Level"="CJAA0201"}
  |   "Protocol Characteristics" = {"Physical Interconnect"="SATA","Physical Interconnect Location"="Internal"}
  |   "SMART Capable" = Yes
  |   "IOMinimumSegmentAlignmentByteCount" = 4
  | }
  | 
  +-o IOBlockStorageDriver  <class IORegistryEntry:IOService:IOStorage:IOBlockStorageDriver, id 0x100000219, registered, matched, active, busy 0 (471 ms), retain 8>
    +-o APPLE SSD TS256C Media  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x10000021a, registered, matched, active, busy 0 (471 ms), retain 11>
      +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x10000021b, registered, matched, active, busy 0 (0 ms), retain 6>
      +-o IOGUIDPartitionScheme  <class IORegistryEntry:IOService:IOStorage:IOPartitionScheme:IOGUIDPartitionScheme, id 0x10000021d, !registered, !matched, active, busy 0 (3 ms), retain 8>
        +-o EFI system partition@1  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x100000263, registered, matched, active, busy 0 (0 ms), retain 9>
        | +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x100000266, registered, matched, active, busy 0 (0 ms), retain 6>
        +-o Customer@2  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x100000264, registered, matched, active, busy 0 (2 ms), retain 11>
        | +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x100000267, registered, matched, active, busy 0 (0 ms), retain 7>
        +-o Recovery HD@3  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x100000265, registered, matched, active, busy 0 (3 ms), retain 9>
          +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x100000268, registered, matched, active, busy 0 (0 ms), retain 6>

您可以通过 IOKit 用户库以编程方式获取这些属性,正如您已经为 USB 发现的那样。

在更高的层次上,一些信息也可以通过磁盘仲裁框架通过DADiskCopyDescription function 获得。通过此函数公开的设备属性似乎没有记录在 DADisk.h 头文件之外,但它们是不言自明的,例如:

extern const CFStringRef kDADiskDescriptionDeviceGUIDKey;      /* ( CFData       ) */
extern const CFStringRef kDADiskDescriptionDeviceInternalKey;  /* ( CFBoolean    ) */
extern const CFStringRef kDADiskDescriptionDeviceModelKey;     /* ( CFString     ) */
extern const CFStringRef kDADiskDescriptionDevicePathKey;      /* ( CFString     ) */
extern const CFStringRef kDADiskDescriptionDeviceProtocolKey;  /* ( CFString     ) */
extern const CFStringRef kDADiskDescriptionDeviceRevisionKey;  /* ( CFString     ) */
extern const CFStringRef kDADiskDescriptionDeviceUnitKey;      /* ( CFNumber     ) */
extern const CFStringRef kDADiskDescriptionDeviceVendorKey;    /* ( CFString     ) */

【讨论】:

  • 您能帮我了解如何从 A DSDiskRef 获取这些片段吗?我正在查看DADisk.c,它看起来像:_diskRef = DADiskCreateFromBSDName( kCFAllocatorDefault, daSession, [diskBSDName UTF8String] ); diskDesc = DADiskCopyDescription( _diskRef ); 给我一个包含很多或部分的DADiskRef。如何将DADiskRef 片段作为字符串输出?
  • DADiskCopyDescription() 返回一个常规的 CFDictionary - 这些文档是 here 但例如找到供应商,你会去NSString* vendor = (NSString*)CFDictionaryGetValue(diskDesc, kDADiskDescriptionDeviceVendorKey); - 你可以把 CFStrings 当作 NSStrings,这叫做免费桥接。如果要保留该字符串,则需要保留它。完成后不要忘记使用CFRelease(diskDesc); 释放字典。
  • 请注意,与 Objective-C 方法不同,CF 函数不会善待 NULL 对象,因此在使用之前检查 DADiskCopyDescription() 的结果是否不为 NULL。
  • 这是非常有用的建议。
  • 您的回复对我帮助很大,现在我需要做的似乎很有可能。解说清晰,简洁明了,没有绒毛。谢谢你。
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多