Skip to content

Instantly share code, notes, and snippets.

@meeuw
Last active July 1, 2021 19:13
Show Gist options
  • Save meeuw/3d2bcf71ab8567f76db0eb25d146b605 to your computer and use it in GitHub Desktop.
Save meeuw/3d2bcf71ab8567f76db0eb25d146b605 to your computer and use it in GitHub Desktop.
<?xml version='1.0'?>
<!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd">
<signatures version='1.0'>
<opaque name='IONotificationPortRef' type64='^{IONotificationPort=}'/>
<constant name='kIOMasterPortDefault' type64='I'/>
<string_constant name='kIOFirstPublishNotification' value='IOServiceFirstPublish'/>
<string_constant name='kIOPublishNotification' value='IOServicePublish'/>
<string_constant name='kIOMatchedNotification' value='IOServiceMatched'/>
<string_constant name='kIOFirstMatchNotification' value='IOServiceFirstMatch'/>
<string_constant name='kIOTerminatedNotification' value='IOServiceTerminate'/>
<string_constant name='kIOUSBDeviceClassName' value='IOUSBDevice'/>
<function name='IOIteratorNext'>
<arg type64='I'/>
<retval type64='I'/>
</function>
<function name='IONotificationPortCreate'>
<arg type64='I'/>
<retval already_retained='true' type64='^{IONotificationPort=}'/>
</function>
<function name='IONotificationPortGetRunLoopSource'>
<arg type64='^{IONotificationPort=}'/>
<retval type64='^{__CFRunLoopSource=}'/>
</function>
<function name='IOObjectRelease'>
<arg type64='I'/>
<retval type64='i'/>
</function>
<function name='IOServiceAddMatchingNotification'>
<arg type64='^{IONotificationPort=}'/>
<arg type64='*'/>
<arg type64='^{__CFDictionary=}'/>
<arg function_pointer='true' type64='^?'>
<arg type64='^v'/>
<arg type64='I'/>
<retval type64='v'/>
</arg>
<arg type64='^v'/>
<arg type64='o^I'/>
<retval type64='i'/>
</function>
<function name='IOServiceMatching'>
<arg type64='*'/>
<retval type64='^{__CFDictionary=}'/>
</function>
</signatures>
import objc
from pathlib import Path
import CoreFoundation
import PyObjCTools.AppHelper
PyObjCTools.AppHelper.installMachInterrupt()
bridgesupport_file = Path("IOKit.bridgesupport").read_text()
objc.parseBridgeSupport(
bridgesupport_file,
globals(),
objc.pathForFramework("/System/Library/Frameworks/IOKit.framework"),
)
port = IONotificationPortCreate(kIOMasterPortDefault)
def iterate(it):
result = []
while 1:
n = IOIteratorNext(it)
if not n:
break
result.append(n)
return result
kIONotifications = (
kIOFirstPublishNotification,
kIOPublishNotification,
kIOMatchedNotification,
kIOFirstMatchNotification,
kIOTerminatedNotification,
)
@objc.callbackFor(IOServiceAddMatchingNotification)
def callback(refcon, iterator):
print(kIONotifications[refcon], iterate(iterator))
for i, v in enumerate(kIONotifications):
matching = IOServiceMatching(kIOUSBDeviceClassName)
matching["idVendor"] = 0x1050
matching["idProduct"] = 0x0407
result, it = IOServiceAddMatchingNotification(port, v, matching, callback, i, None)
print(result, it)
iterate(it)
CoreFoundation.CFRunLoopAddSource(
CoreFoundation.CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(port),
CoreFoundation.kCFRunLoopDefaultMode,
)
CoreFoundation.CFRunLoopRun()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment