mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-14 04:38:20 +10:00
254 lines
10 KiB
Python
254 lines
10 KiB
Python
# Handle misc CLI menu options
|
|
# Copyright (C) 2020-2022, Dhinak G
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import NewType, Union
|
|
import subprocess
|
|
|
|
try:
|
|
import objc
|
|
except ImportError:
|
|
subprocess.run(["pip3", "install", "pyobjc"], stdout=subprocess.PIPE)
|
|
try:
|
|
import objc
|
|
except ImportError:
|
|
raise Exception("Missing PyObjc library!\nPlease run the following before starting OCLP:\npip3 install pyobjc")
|
|
|
|
from CoreFoundation import CFRelease, kCFAllocatorDefault # type: ignore # pylint: disable=no-name-in-module
|
|
from Foundation import NSBundle # type: ignore # pylint: disable=no-name-in-module
|
|
from PyObjCTools import Conversion
|
|
|
|
IOKit_bundle = NSBundle.bundleWithIdentifier_("com.apple.framework.IOKit")
|
|
|
|
# pylint: disable=invalid-name
|
|
io_name_t_ref_out = b"[128c]" # io_name_t is char[128]
|
|
const_io_name_t_ref_in = b"r*"
|
|
CFStringRef = b"^{__CFString=}"
|
|
CFDictionaryRef = b"^{__CFDictionary=}"
|
|
CFAllocatorRef = b"^{__CFAllocator=}"
|
|
# pylint: enable=invalid-name
|
|
|
|
# https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
|
|
functions = [
|
|
("IORegistryEntryCreateCFProperties", b"IIo^@" + CFAllocatorRef + b"I"),
|
|
("IOServiceMatching", CFDictionaryRef + b"r*"),
|
|
("IOServiceGetMatchingServices", b"II" + CFDictionaryRef + b"o^I"),
|
|
("IOIteratorNext", b"II"),
|
|
("IORegistryEntryGetParentEntry", b"IIr*o^I"),
|
|
("IOObjectRelease", b"II"),
|
|
("IORegistryEntryGetName", b"IIo" + io_name_t_ref_out),
|
|
("IOObjectGetClass", b"IIo" + io_name_t_ref_out),
|
|
("IOObjectCopyClass", CFStringRef + b"I"),
|
|
("IOObjectCopySuperclassForClass", CFStringRef + CFStringRef),
|
|
("IORegistryEntryGetChildIterator", b"IIr*o^I"),
|
|
("IORegistryCreateIterator", b"IIr*Io^I"),
|
|
("IORegistryEntryCreateIterator", b"IIr*Io^I"),
|
|
("IORegistryIteratorEnterEntry", b"II"),
|
|
("IORegistryIteratorExitEntry", b"II"),
|
|
("IORegistryEntryCreateCFProperty", b"@I" + CFStringRef + CFAllocatorRef + b"I"),
|
|
("IORegistryEntryGetPath", b"IIr*oI"),
|
|
("IORegistryEntryCopyPath", CFStringRef + b"Ir*"),
|
|
("IOObjectConformsTo", b"II" + const_io_name_t_ref_in),
|
|
("IORegistryEntryGetLocationInPlane", b"II" + const_io_name_t_ref_in + b"o" + io_name_t_ref_out),
|
|
("IOServiceNameMatching", CFDictionaryRef + b"r*"),
|
|
("IORegistryEntryGetRegistryEntryID", b"IIo^Q"),
|
|
("IORegistryEntryIDMatching", CFDictionaryRef + b"Q"),
|
|
("IORegistryEntryFromPath", b"II" + const_io_name_t_ref_in),
|
|
]
|
|
|
|
variables = [("kIOMasterPortDefault", b"I")]
|
|
|
|
# pylint: disable=invalid-name
|
|
pointer = type(None)
|
|
|
|
kern_return_t = NewType("kern_return_t", int)
|
|
boolean_t = int
|
|
|
|
io_object_t = NewType("io_object_t", object)
|
|
io_name_t = bytes
|
|
io_string_t = bytes
|
|
|
|
# io_registry_entry_t = NewType("io_registry_entry_t", io_object_t)
|
|
io_registry_entry_t = io_object_t
|
|
io_iterator_t = NewType("io_iterator_t", io_object_t)
|
|
|
|
CFTypeRef = Union[int, float, bytes, dict, list]
|
|
|
|
IOOptionBits = int
|
|
mach_port_t = int
|
|
CFAllocatorType = type(kCFAllocatorDefault)
|
|
|
|
NULL = 0
|
|
|
|
kIOMasterPortDefault: mach_port_t
|
|
kNilOptions: IOOptionBits = NULL
|
|
|
|
# IOKitLib.h
|
|
kIORegistryIterateRecursively = 1
|
|
kIORegistryIterateParents = 2
|
|
|
|
# pylint: enable=invalid-name
|
|
|
|
|
|
# kern_return_t IORegistryEntryCreateCFProperties(io_registry_entry_t entry, CFMutableDictionaryRef * properties, CFAllocatorRef allocator, IOOptionBits options);
|
|
def IORegistryEntryCreateCFProperties(entry: io_registry_entry_t, properties: pointer, allocator: CFAllocatorType, options: IOOptionBits) -> tuple[kern_return_t, dict]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFMutableDictionaryRef IOServiceMatching(const char * name);
|
|
def IOServiceMatching(name: bytes) -> dict: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IOServiceGetMatchingServices(mach_port_t masterPort, CFDictionaryRef matching CF_RELEASES_ARGUMENT, io_iterator_t * existing);
|
|
def IOServiceGetMatchingServices(masterPort: mach_port_t, matching: dict, existing: pointer) -> tuple[kern_return_t, io_iterator_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# io_object_t IOIteratorNext(io_iterator_t iterator);
|
|
def IOIteratorNext(iterator: io_iterator_t) -> io_object_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetParentEntry(io_registry_entry_t entry, const io_name_t plane, io_registry_entry_t * parent);
|
|
def IORegistryEntryGetParentEntry(entry: io_registry_entry_t, plane: io_name_t, parent: pointer) -> tuple[kern_return_t, io_registry_entry_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IOObjectRelease(io_object_t object);
|
|
def IOObjectRelease(object: io_object_t) -> kern_return_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetName(io_registry_entry_t entry, io_name_t name);
|
|
def IORegistryEntryGetName(entry: io_registry_entry_t, name: pointer) -> tuple[kern_return_t, bytes]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IOObjectGetClass(io_object_t object, io_name_t className);
|
|
def IOObjectGetClass(object: io_object_t, className: pointer) -> tuple[kern_return_t, bytes]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFStringRef IOObjectCopyClass(io_object_t object);
|
|
def IOObjectCopyClass(object: io_object_t) -> str: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFStringRef IOObjectCopySuperclassForClass(CFStringRef classname)
|
|
def IOObjectCopySuperclassForClass(classname: str) -> str: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetChildIterator(io_registry_entry_t entry, const io_name_t plane, io_iterator_t * iterator);
|
|
def IORegistryEntryGetChildIterator(entry: io_registry_entry_t, plane: io_name_t, iterator: pointer) -> tuple[kern_return_t, io_iterator_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryCreateIterator(mach_port_t masterPort, const io_name_t plane, IOOptionBits options, io_iterator_t * iterator)
|
|
def IORegistryCreateIterator(masterPort: mach_port_t, plane: io_name_t, options: IOOptionBits, iterator: pointer) -> tuple[kern_return_t, io_iterator_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryCreateIterator(io_registry_entry_t entry, const io_name_t plane, IOOptionBits options, io_iterator_t * iterator)
|
|
def IORegistryEntryCreateIterator(entry: io_registry_entry_t, plane: io_name_t, options: IOOptionBits, iterator: pointer) -> tuple[kern_return_t, io_iterator_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryIteratorEnterEntry(io_iterator_t iterator)
|
|
def IORegistryIteratorEnterEntry(iterator: io_iterator_t) -> kern_return_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryIteratorExitEntry(io_iterator_t iterator)
|
|
def IORegistryIteratorExitEntry(iterator: io_iterator_t) -> kern_return_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFTypeRef IORegistryEntryCreateCFProperty(io_registry_entry_t entry, CFStringRef key, CFAllocatorRef allocator, IOOptionBits options);
|
|
def IORegistryEntryCreateCFProperty(entry: io_registry_entry_t, key: str, allocator: CFAllocatorType, options: IOOptionBits) -> CFTypeRef: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetPath(io_registry_entry_t entry, const io_name_t plane, io_string_t path);
|
|
def IORegistryEntryGetPath(entry: io_registry_entry_t, plane: io_name_t, path: pointer) -> tuple[kern_return_t, io_string_t]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFStringRef IORegistryEntryCopyPath(io_registry_entry_t entry, const io_name_t plane)
|
|
def IORegistryEntryCopyPath(entry: io_registry_entry_t, plane: bytes) -> str: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# boolean_t IOObjectConformsTo(io_object_t object, const io_name_t className)
|
|
def IOObjectConformsTo(object: io_object_t, className: bytes) -> boolean_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetLocationInPlane(io_registry_entry_t entry, const io_name_t plane, io_name_t location)
|
|
def IORegistryEntryGetLocationInPlane(entry: io_registry_entry_t, plane: io_name_t, location: pointer) -> tuple[kern_return_t, bytes]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFMutableDictionaryRef IOServiceNameMatching(const char * name);
|
|
def IOServiceNameMatching(name: bytes) -> dict: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# kern_return_t IORegistryEntryGetRegistryEntryID(io_registry_entry_t entry, uint64_t * entryID)
|
|
def IORegistryEntryGetRegistryEntryID(entry: io_registry_entry_t, entryID: pointer) -> tuple[kern_return_t, int]: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# CFMutableDictionaryRef IORegistryEntryIDMatching(uint64_t entryID);
|
|
def IORegistryEntryIDMatching(entryID: int) -> dict: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
# io_registry_entry_t IORegistryEntryFromPath(mach_port_t mainPort, const io_string_t path)
|
|
def IORegistryEntryFromPath(mainPort: mach_port_t, path: io_string_t) -> io_registry_entry_t: # pylint: disable=invalid-name
|
|
raise NotImplementedError
|
|
|
|
|
|
objc.loadBundleFunctions(IOKit_bundle, globals(), functions) # type: ignore # pylint: disable=no-member
|
|
objc.loadBundleVariables(IOKit_bundle, globals(), variables) # type: ignore # pylint: disable=no-member
|
|
|
|
|
|
def ioiterator_to_list(iterator: io_iterator_t):
|
|
# items = []
|
|
item = IOIteratorNext(iterator) # noqa: F821
|
|
while item:
|
|
# items.append(next)
|
|
yield item
|
|
item = IOIteratorNext(iterator) # noqa: F821
|
|
IOObjectRelease(iterator) # noqa: F821
|
|
# return items
|
|
|
|
|
|
def corefoundation_to_native(collection):
|
|
if collection is None: # nullptr
|
|
return None
|
|
native = Conversion.pythonCollectionFromPropertyList(collection)
|
|
CFRelease(collection)
|
|
return native
|
|
|
|
|
|
def native_to_corefoundation(native):
|
|
return Conversion.propertyListFromPythonCollection(native)
|
|
|
|
|
|
def io_name_t_to_str(name):
|
|
return name.partition(b"\0")[0].decode()
|
|
|
|
|
|
def get_class_inheritance(io_object):
|
|
classes = []
|
|
cls = IOObjectCopyClass(io_object)
|
|
while cls:
|
|
# yield cls
|
|
classes.append(cls)
|
|
CFRelease(cls)
|
|
cls = IOObjectCopySuperclassForClass(cls)
|
|
return classes
|