Add AMFIPass (#1051)

This commit is contained in:
Dhinak G
2023-07-26 08:29:46 -04:00
committed by GitHub
parent aa1739c1d6
commit 43be00e9e7
17 changed files with 247 additions and 138 deletions

1
.gitignore vendored
View File

@@ -30,6 +30,7 @@ __pycache__/
/payloads/OpenCore-Legacy-Patcher /payloads/OpenCore-Legacy-Patcher
/payloads/InstallAssistant.pkg.integrityDataV1 /payloads/InstallAssistant.pkg.integrityDataV1
/payloads.dmg /payloads.dmg
/Universal-Binaries.dmg
/payloads/OpenCore-Legacy-Patcher-*.plist /payloads/OpenCore-Legacy-Patcher-*.plist
/payloads/KDK.dmg /payloads/KDK.dmg
*.log *.log

View File

@@ -20,7 +20,7 @@ class CreateBinary:
Library for creating OpenCore-Patcher application Library for creating OpenCore-Patcher application
This script's main purpose is to handle the following: This script's main purpose is to handle the following:
- Download external dependancies (ex. PatcherSupportPkg) - Download external dependencies (ex. PatcherSupportPkg)
- Convert payloads directory into DMG - Convert payloads directory into DMG
- Build Binary via Pyinstaller - Build Binary via Pyinstaller
- Patch 'LC_VERSION_MIN_MACOSX' to OS X 10.10 - Patch 'LC_VERSION_MIN_MACOSX' to OS X 10.10
@@ -275,7 +275,10 @@ class CreateBinary:
for resource in required_resources: for resource in required_resources:
if Path(f"./{resource}").exists(): if Path(f"./{resource}").exists():
if self.args.reset_binaries: if self.args.reset_binaries:
print(f"- Removing old {resource}") print(f" - Removing old {resource}")
# Just to be safe
assert resource, "Resource cannot be empty"
assert resource not in ("/", "."), "Resource cannot be root"
rm_output = subprocess.run( rm_output = subprocess.run(
["rm", "-rf", f"./{resource}"], ["rm", "-rf", f"./{resource}"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE stdout=subprocess.PIPE, stderr=subprocess.PIPE

View File

@@ -18,6 +18,7 @@ This patcher is made of multiple external applications from different people and
* [telemetrap](https://forums.macrumors.com/threads/mp3-1-others-sse-4-2-emulation-to-enable-amd-metal-driver.2206682/post-28447707) - Syncretic * [telemetrap](https://forums.macrumors.com/threads/mp3-1-others-sse-4-2-emulation-to-enable-amd-metal-driver.2206682/post-28447707) - Syncretic
* [SurPlus](https://github.com/reenigneorcim/SurPlus) - Syncretic * [SurPlus](https://github.com/reenigneorcim/SurPlus) - Syncretic
* [VMM Patch Set](https://github.com/dortania/OpenCore-Legacy-Patcher/blob/4a8f61a01da72b38a4b2250386cc4b497a31a839/payloads/Config/config.plist#L1222-L1281) - parrotgeek1 * [VMM Patch Set](https://github.com/dortania/OpenCore-Legacy-Patcher/blob/4a8f61a01da72b38a4b2250386cc4b497a31a839/payloads/Config/config.plist#L1222-L1281) - parrotgeek1
* AMFIPass - Dhinak G
* Apple Binaries - Apple Inc. * Apple Binaries - Apple Inc.
* All other patches - respective authors * All other patches - respective authors

View File

@@ -1584,6 +1584,22 @@
<dict> <dict>
<key>Arch</key> <key>Arch</key>
<string>x86_64</string> <string>x86_64</string>
<key>BundlePath</key>
<string>AMFIPass.kext</string>
<key>Comment</key>
<string>AMFIPass</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
<string>Contents/MacOS/AMFIPass</string>
<key>MaxKernel</key>
<string></string>
<key>MinKernel</key>
<string>20.0.0</string>
<key>PlistPath</key>
<string>Contents/Info.plist</string>
</dict>
<dict>
<key>Comment</key> <key>Comment</key>
<string>Aquantia Ethernet Patch</string> <string>Aquantia Ethernet Patch</string>
<key>Enabled</key> <key>Enabled</key>

Binary file not shown.

View File

@@ -82,3 +82,6 @@ class BuildSecurity:
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] = True support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] = True
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Legacy")["Enabled"] = True support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Legacy")["Enabled"] = True
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Ventura")["Enabled"] = True support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Ventura")["Enabled"] = True
logging.info("- Enabling AMFIPass")
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AMFIPass.kext", self.constants.amfipass_version, self.constants.amfipass_path)

View File

@@ -4,6 +4,7 @@
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from packaging import version
from resources import device_probe from resources import device_probe
from data import os_data from data import os_data
@@ -78,13 +79,15 @@ class Constants:
## Dortania ## Dortania
## https://github.com/dortania ## https://github.com/dortania
self.backlight_injector_version: str = "1.1.0" # BacklightInjector self.backlight_injector_version: str = "1.1.0" # BacklightInjector
self.backlight_injectorA_version: str = "1.0.0" # BacklightInjector (iMac9,1) self.backlight_injectorA_version: str = "1.0.0" # BacklightInjector (iMac9,1)
self.smcspoof_version: str = "1.0.0" # SMC-Spoof self.smcspoof_version: str = "1.0.0" # SMC-Spoof
self.mce_version: str = "1.0.0" # AppleMCEReporterDisabler self.mce_version: str = "1.0.0" # AppleMCEReporterDisabler
self.btspoof_version: str = "1.0.0" # Bluetooth-Spoof self.btspoof_version: str = "1.0.0" # Bluetooth-Spoof
self.aspp_override_version: str = "1.0.1" # ACPI_SMC_PlatformPlugin Override self.aspp_override_version: str = "1.0.1" # ACPI_SMC_PlatformPlugin Override
self.rsrhelper_version: str = "1.0.0" # RSRHelper self.rsrhelper_version: str = "1.0.0" # RSRHelper
self.amfipass_version: str = "1.3.1" # AMFIPass
self.amfipass_compatibility_version: str = "1.2.1" # Minimum AMFIPass version required
## Syncretic ## Syncretic
## https://forums.macrumors.com/members/syncretic.1173816/ ## https://forums.macrumors.com/members/syncretic.1173816/
@@ -232,6 +235,18 @@ class Constants:
os_data.os_data.ventura, os_data.os_data.ventura,
] ]
@property
def special_build(self):
"""
Special builds are used for testing. They do not get updates through the updater
"""
try:
version.parse(self.patcher_version)
return False
except version.InvalidVersion:
return True
# Payload Location # Payload Location
# Support Disk Images # Support Disk Images
@@ -489,6 +504,11 @@ class Constants:
def rsrhelper_path(self): def rsrhelper_path(self):
return self.payload_kexts_path / Path(f"Acidanthera/RSRHelper-v{self.rsrhelper_version}-{self.kext_variant}.zip") return self.payload_kexts_path / Path(f"Acidanthera/RSRHelper-v{self.rsrhelper_version}-{self.kext_variant}.zip")
@property
def amfipass_path(self):
# AMFIPass is release only
return self.payload_kexts_path / Path(f"Acidanthera/AMFIPass-v{self.amfipass_version}-RELEASE.zip")
@property @property
def innie_path(self): def innie_path(self):
return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}-{self.kext_variant}.zip") return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}-{self.kext_variant}.zip")

View File

@@ -49,7 +49,7 @@ class GenerateDefaults:
self._networking_probe() self._networking_probe()
self._misc_hardwares_probe() self._misc_hardwares_probe()
self._smbios_probe() self._smbios_probe()
self._check_amfipass_supported()
def _general_probe(self) -> None: def _general_probe(self) -> None:
""" """
@@ -309,4 +309,32 @@ class GenerateDefaults:
if is_key_enabled not in ["false", "0"]: if is_key_enabled not in ["false", "0"]:
subprocess.run(["defaults", "write", "-g", key, "-bool", "true"]) subprocess.run(["defaults", "write", "-g", key, "-bool", "true"])
subprocess.run(["defaults", "write", "-g", "Amy.MenuBar2Beta", "-bool", "false"]) subprocess.run(["defaults", "write", "-g", "Amy.MenuBar2Beta", "-bool", "false"])
def _check_amfipass_supported(self) -> None:
"""
Check if root volume supports AMFIPass
The basic requirements of this function are:
- The host is the target
- Root volume doesn't have adhoc signed binaries
If all of these conditions are met, it is safe to disable AMFI and CS_LV. Otherwise, for safety, leave it be.
"""
if not self.host_is_target:
# Unknown whether the host is using old binaries
# Rebuild it once you are on the host
return
# Check for adhoc signed binaries
if self.constants.computer.oclp_sys_signed is False:
# Root patch with new binaries, then reboot
return
# Note: simply checking the authority is not enough, as the authority can be spoofed
# (but do we really care? this is just a simple check)
# Note: the cert will change
self.constants.disable_amfi = False
self.constants.disable_cs_lv = False

View File

@@ -604,6 +604,7 @@ class Computer:
oclp_sys_version: Optional[str] = None oclp_sys_version: Optional[str] = None
oclp_sys_date: Optional[str] = None oclp_sys_date: Optional[str] = None
oclp_sys_url: Optional[str] = None oclp_sys_url: Optional[str] = None
oclp_sys_signed: Optional[bool] = False
firmware_vendor: Optional[str] = None firmware_vendor: Optional[str] = None
rosetta_active: Optional[bool] = False rosetta_active: Optional[bool] = False
@@ -927,15 +928,19 @@ class Computer:
def oclp_sys_patch_probe(self): def oclp_sys_patch_probe(self):
path = Path("/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist") path = Path("/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist")
if path.exists(): if not path.exists():
sys_plist = plistlib.load(path.open("rb")) self.oclp_sys_signed = True # No plist, so assume root is valid
if sys_plist: return
if "OpenCore Legacy Patcher" in sys_plist: sys_plist = plistlib.load(path.open("rb"))
self.oclp_sys_version = sys_plist["OpenCore Legacy Patcher"] if sys_plist:
if "Time Patched" in sys_plist: if "OpenCore Legacy Patcher" in sys_plist:
self.oclp_sys_date = sys_plist["Time Patched"] self.oclp_sys_version = sys_plist["OpenCore Legacy Patcher"]
if "Commit URL" in sys_plist: if "Time Patched" in sys_plist:
self.oclp_sys_url = sys_plist["Commit URL"] self.oclp_sys_date = sys_plist["Time Patched"]
if "Commit URL" in sys_plist:
self.oclp_sys_url = sys_plist["Commit URL"]
if "Custom Signature" in sys_plist:
self.oclp_sys_signed = sys_plist["Custom Signature"]
def check_rosetta(self): def check_rosetta(self):
result = subprocess.run("sysctl -in sysctl.proc_translated".split(), stdout=subprocess.PIPE).stdout.decode() result = subprocess.run("sysctl -in sysctl.proc_translated".split(), stdout=subprocess.PIPE).stdout.decode()

View File

@@ -20,7 +20,7 @@ from data import os_data
KDK_INSTALL_PATH: str = "/Library/Developer/KDKs" KDK_INSTALL_PATH: str = "/Library/Developer/KDKs"
KDK_INFO_PLIST: str = "KDKInfo.plist" KDK_INFO_PLIST: str = "KDKInfo.plist"
KDK_API_LINK: str = "https://raw.githubusercontent.com/dortania/KdkSupportPkg/gh-pages/manifest.json" KDK_API_LINK: str = "https://dortania.github.io/KdkSupportPkg/manifest.json"
KDK_ASSET_LIST: list = None KDK_ASSET_LIST: list = None

View File

@@ -67,7 +67,6 @@ class PatchSysVolume:
self.skip_root_kmutil_requirement = self.hardware_details["Settings: Supports Auxiliary Cache"] self.skip_root_kmutil_requirement = self.hardware_details["Settings: Supports Auxiliary Cache"]
def _init_pathing(self, custom_root_mount_path: Path = None, custom_data_mount_path: Path = None) -> None: def _init_pathing(self, custom_root_mount_path: Path = None, custom_data_mount_path: Path = None) -> None:
""" """
Initializes the pathing for root volume patching Initializes the pathing for root volume patching
@@ -493,7 +492,7 @@ class PatchSysVolume:
oclp_plist_data = plistlib.load(Path(oclp_path).open("rb")) oclp_plist_data = plistlib.load(Path(oclp_path).open("rb"))
for key in oclp_plist_data: for key in oclp_plist_data:
if isinstance(oclp_plist_data[key], (bool, int)): if isinstance(oclp_plist_data[key], (bool, int)):
continue continue
if "Install" not in oclp_plist_data[key]: if "Install" not in oclp_plist_data[key]:
continue continue
for location in oclp_plist_data[key]["Install"]: for location in oclp_plist_data[key]["Install"]:

View File

@@ -47,8 +47,7 @@ class AutomaticSysPatch:
dict = updates.CheckBinaryUpdates(self.constants).check_binary_updates() dict = updates.CheckBinaryUpdates(self.constants).check_binary_updates()
if dict: if dict:
for key in dict: version = dict["Version"]
version = dict[key]["Version"]
logging.info(f"- Found new version: {version}") logging.info(f"- Found new version: {version}")
app = wx.App() app = wx.App()
@@ -64,7 +63,7 @@ class AutomaticSysPatch:
if response == wx.ID_YES: if response == wx.ID_YES:
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP) gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP)
elif response == wx.ID_NO: elif response == wx.ID_NO:
webbrowser.open(dict[key]["Github Link"]) webbrowser.open(dict["Github Link"])
return return
if utilities.check_seal() is True: if utilities.check_seal() is True:
@@ -149,17 +148,21 @@ class AutomaticSysPatch:
logging.info("- Versions match") logging.info("- Versions match")
return True return True
if self.constants.special_build is True:
# Version doesn't match and we're on a special build
# Special builds don't have good ways to compare versions
logging.info("- Special build detected, assuming installed is older")
return False
# Check if installed version is newer than booted version # Check if installed version is newer than booted version
if updates.CheckBinaryUpdates(self.constants)._check_if_build_newer( if updates.CheckBinaryUpdates(self.constants).check_if_newer(self.constants.computer.oclp_version):
self.constants.computer.oclp_version.split("."), self.constants.patcher_version.split(".")
) is True:
logging.info("- Installed version is newer than booted version") logging.info("- Installed version is newer than booted version")
return True return True
args = [ args = [
"osascript", "osascript",
"-e", "-e",
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting an outdated OpenCore build\n- Booted: {self.constants.computer.oclp_version}\n- Installed: {self.constants.patcher_version}\n\nWould you like to update the OpenCore bootloader?" """ f"""display dialog "OpenCore Legacy Patcher has detected that you are booting {'a different' if self.constants.special_build else 'an outdated'} OpenCore build\n- Booted: {self.constants.computer.oclp_version}\n- Installed: {self.constants.patcher_version}\n\nWould you like to update the OpenCore bootloader?" """
f'with icon POSIX file "{self.constants.app_icon_path}"', f'with icon POSIX file "{self.constants.app_icon_path}"',
] ]
output = subprocess.run( output = subprocess.run(

View File

@@ -3,26 +3,16 @@
# Used when supplying data to sys_patch.py # Used when supplying data to sys_patch.py
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
import plistlib
import logging import logging
import py_sip_xnu import plistlib
from pathlib import Path from pathlib import Path
from resources import ( import packaging.version
constants, import py_sip_xnu
device_probe,
utilities, from data import cpu_data, model_array, os_data, sip_data, smbios_data
amfi_detect, from resources import (amfi_detect, constants, device_probe, kdk_handler,
network_handler, network_handler, utilities)
kdk_handler
)
from data import (
model_array,
os_data,
sip_data,
smbios_data,
cpu_data
)
class DetectRootPatch: class DetectRootPatch:
@@ -418,7 +408,7 @@ class DetectRootPatch:
bool: True if loaded, False otherwise bool: True if loaded, False otherwise
""" """
return utilities.check_kext_loaded("WhateverGreen", self.constants.detected_os) return utilities.check_kext_loaded("as.vit9696.WhateverGreen")
def _check_kdk(self): def _check_kdk(self):
@@ -521,7 +511,7 @@ class DetectRootPatch:
if self.constants.detected_os > os_data.os_data.catalina: if self.constants.detected_os > os_data.os_data.catalina:
self.brightness_legacy = True self.brightness_legacy = True
if self.model in ["iMac7,1", "iMac8,1"] or (self.model in model_array.LegacyAudio and utilities.check_kext_loaded("AppleALC", self.constants.detected_os) is False): if self.model in ["iMac7,1", "iMac8,1"] or (self.model in model_array.LegacyAudio and utilities.check_kext_loaded("as.vit9696.AppleALC") is False):
# Special hack for systems with botched GOPs # Special hack for systems with botched GOPs
# TL;DR: No Boot Screen breaks Lilu, therefore breaking audio # TL;DR: No Boot Screen breaks Lilu, therefore breaking audio
if self.constants.detected_os > os_data.os_data.catalina: if self.constants.detected_os > os_data.os_data.catalina:
@@ -610,6 +600,12 @@ class DetectRootPatch:
if self.constants.detected_os < os_data.os_data.big_sur: if self.constants.detected_os < os_data.os_data.big_sur:
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
amfipass_version = utilities.check_kext_loaded("com.dhinakg.AMFIPass")
if amfipass_version:
if packaging.version.parse(amfipass_version) >= packaging.version.parse(self.constants.amfipass_compatibility_version):
# If AMFIPass is loaded, our binaries will work
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
if self.constants.detected_os >= os_data.os_data.ventura: if self.constants.detected_os >= os_data.os_data.ventura:
if self.amfi_shim_bins is True: if self.amfi_shim_bins is True:
# Currently we require AMFI outright disabled # Currently we require AMFI outright disabled

View File

@@ -3,8 +3,11 @@
# Call check_binary_updates() to determine if any updates are available # Call check_binary_updates() to determine if any updates are available
# Returns dict with Link and Version of the latest binary update if available # Returns dict with Link and Version of the latest binary update if available
import logging import logging
from typing import Optional, Union
from resources import network_handler, constants from packaging import version
from resources import constants, network_handler
REPO_LATEST_RELEASE_URL: str = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest" REPO_LATEST_RELEASE_URL: str = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
@@ -12,48 +15,62 @@ REPO_LATEST_RELEASE_URL: str = "https://api.github.com/repos/dortania/OpenCore-L
class CheckBinaryUpdates: class CheckBinaryUpdates:
def __init__(self, global_constants: constants.Constants) -> None: def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
try:
self.binary_version = version.parse(self.constants.patcher_version)
except version.InvalidVersion:
assert self.constants.special_build is True, "Invalid version number for binary"
# Special builds will not have a proper version number
self.binary_version = version.parse("0.0.0")
self.binary_version = self.constants.patcher_version self.latest_details = None
self.binary_version_array = [int(x) for x in self.binary_version.split(".")]
def check_if_newer(self, version: Union[str, version.Version]) -> bool:
def _check_if_build_newer(self, remote_version: list = None, local_version: list = None) -> bool:
""" """
Check if the remote version is newer than the local version Check if the provided version is newer than the local version
Parameters: Parameters:
remote_version (list): Remote version to compare against version (str): Version to compare against
local_version (list): Local version to compare against
Returns: Returns:
bool: True if remote version is newer, False if not bool: True if the provided version is newer, False if not
"""
if self.constants.special_build is True:
return False
return self._check_if_build_newer(version, self.binary_version)
def _check_if_build_newer(self, first_version: Union[str, version.Version], second_version: Union[str, version.Version]) -> bool:
"""
Check if the first version is newer than the second version
Parameters:
first_version_str (str): First version to compare against (generally local)
second_version_str (str): Second version to compare against (generally remote)
Returns:
bool: True if first version is newer, False if not
""" """
if remote_version is None: if not isinstance(first_version, version.Version):
remote_version = self.remote_version_array try:
if local_version is None: first_version = version.parse(first_version)
local_version = self.binary_version_array except version.InvalidVersion:
# Special build > release build: assume special build is newer
return True
if not isinstance(second_version, version.Version):
try:
second_version = version.parse(second_version)
except version.InvalidVersion:
# Release build > special build: assume special build is newer
return False
if local_version == remote_version: if first_version == second_version:
if not self.constants.commit_info[0].startswith("refs/tags"): if not self.constants.commit_info[0].startswith("refs/tags"):
# Check for nightly builds # Check for nightly builds
return True return True
# Pad version numbers to match length (ie. 0.1.0 vs 0.1.0.1) return first_version > second_version
while len(remote_version) > len(local_version):
local_version.append(0)
while len(remote_version) < len(local_version):
remote_version.append(0)
for i in range(0, len(remote_version)):
if int(remote_version[i]) < int(local_version[i]):
break
elif int(remote_version[i]) > int(local_version[i]):
return True
return False
def _determine_local_build_type(self) -> str: def _determine_local_build_type(self) -> str:
""" """
@@ -63,11 +80,7 @@ class CheckBinaryUpdates:
str: "GUI" or "TUI" str: "GUI" or "TUI"
""" """
if self.constants.wxpython_variant is True: return "GUI" if self.constants.wxpython_variant else "TUI"
return "GUI"
else:
return "TUI"
def _determine_remote_type(self, remote_name: str) -> str: def _determine_remote_type(self, remote_name: str) -> str:
""" """
@@ -87,8 +100,7 @@ class CheckBinaryUpdates:
else: else:
return "Unknown" return "Unknown"
def check_binary_updates(self) -> Optional[dict]:
def check_binary_updates(self) -> dict:
""" """
Check if any updates are available for the OpenCore Legacy Patcher binary Check if any updates are available for the OpenCore Legacy Patcher binary
@@ -96,7 +108,13 @@ class CheckBinaryUpdates:
dict: Dictionary with Link and Version of the latest binary update if available dict: Dictionary with Link and Version of the latest binary update if available
""" """
available_binaries: list = {} if self.constants.special_build is True:
# Special builds do not get updates through the updater
return None
if self.latest_details:
# We already checked
return self.latest_details
if not network_handler.NetworkUtilities(REPO_LATEST_RELEASE_URL).verify_network_connection(): if not network_handler.NetworkUtilities(REPO_LATEST_RELEASE_URL).verify_network_connection():
return None return None
@@ -107,26 +125,26 @@ class CheckBinaryUpdates:
if "tag_name" not in data_set: if "tag_name" not in data_set:
return None return None
self.remote_version = data_set["tag_name"] # The release marked as latest will always be stable, and thus, have a proper version number
# But if not, let's not crash the program
try:
latest_remote_version = version.parse(data_set["tag_name"])
except version.InvalidVersion:
return None
self.remote_version_array = self.remote_version.split(".") if not self._check_if_build_newer(latest_remote_version, self.binary_version):
self.remote_version_array = [int(x) for x in self.remote_version_array]
if self._check_if_build_newer() is False:
return None return None
for asset in data_set["assets"]: for asset in data_set["assets"]:
logging.info(f"Found asset: {asset['name']}") logging.info(f"Found asset: {asset['name']}")
if self._determine_remote_type(asset["name"]) == self._determine_local_build_type(): if self._determine_remote_type(asset["name"]) == self._determine_local_build_type():
available_binaries.update({ self.latest_details = {
asset['name']: { "Name": asset["name"],
"Name": asset["name"], "Version": latest_remote_version,
"Version": self.remote_version, "Link": asset["browser_download_url"],
"Link": asset["browser_download_url"], "Type": self._determine_remote_type(asset["name"]),
"Type": self._determine_remote_type(asset["name"]), "Github Link": f"https://github.com/dortania/OpenCore-Legacy-Patcher/releases/{latest_remote_version}",
"Github Link": f"https://github.com/dortania/OpenCore-Legacy-Patcher/releases/{self.remote_version}" }
} return self.latest_details
})
return available_binaries
return None return None

View File

@@ -1,21 +1,20 @@
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk # Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
import argparse
import atexit
import binascii
import logging
import math import math
import os import os
import plistlib import plistlib
import re
import shutil
import subprocess import subprocess
from pathlib import Path from pathlib import Path
import os
import binascii
import argparse
import atexit
import shutil
import py_sip_xnu import py_sip_xnu
import logging from data import os_data, sip_data
from resources import constants, ioreg from resources import constants, ioreg
from data import sip_data, os_data
def hexswap(input_hex: str): def hexswap(input_hex: str):
@@ -173,15 +172,35 @@ def enable_sleep_after_running():
sleep_process = None sleep_process = None
def check_kext_loaded(kext_name, os_version): def check_kext_loaded(bundle_id: str) -> str:
if os_version > os_data.os_data.catalina: """
kext_loaded = subprocess.run(["kmutil", "showloaded", "--list-only", "--variant-suffix", "release"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) Checks if a kext is loaded
else:
kext_loaded = subprocess.run(["kextstat", "-l"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) Parameters:
if kext_name in kext_loaded.stdout.decode(): bundle_id (str): The bundle ID of the kext to check
return True
else: Returns:
return False str: The version of the kext if it is loaded, or "" if it is not loaded
"""
# Name (Version) UUID <Linked Against>
# no UUID for kextstat
pattern = re.compile(re.escape(bundle_id) + r"\s+\((?P<version>.+)\)")
args = ["kextstat", "-l", "-b", bundle_id]
if Path("/usr/bin/kmutil").exists():
args = ["kmutil", "showloaded", "--list-only", "--variant-suffix", "release", "--optional-identifier", bundle_id]
kext_loaded = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if kext_loaded.returncode != 0:
return ""
output = kext_loaded.stdout.decode()
if not output.strip():
return ""
match = pattern.search(output)
if match:
return match.group("version")
return ""
def check_oclp_boot(): def check_oclp_boot():

View File

@@ -65,7 +65,7 @@ class MainFrame(wx.Frame):
""" """
# Title label: OpenCore Legacy Patcher v{X.Y.Z} # Title label: OpenCore Legacy Patcher v{X.Y.Z}
title_label = wx.StaticText(self, label=f"OpenCore Legacy Patcher v{self.constants.patcher_version}", pos=(-1,10)) title_label = wx.StaticText(self, label=f"OpenCore Legacy Patcher {'' if self.constants.special_build else 'v'}{self.constants.patcher_version}", pos=(-1, 10))
title_label.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont")) title_label.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
title_label.Centre(wx.HORIZONTAL) title_label.Centre(wx.HORIZONTAL)
@@ -282,22 +282,21 @@ class MainFrame(wx.Frame):
if not dict: if not dict:
return return
for entry in dict: version = dict["Version"]
version = dict[entry]["Version"] logging.info(f"New version: {version}")
logging.info(f"New version: {version}") dialog = wx.MessageDialog(
dialog = wx.MessageDialog( parent=self,
parent=self, message=f"Current Version: {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}\nNew version: {version}\nWould you like to update?",
message=f"Current Version: {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}\nNew version: {version}\nWould you like to update?", caption="Update Available for OpenCore Legacy Patcher!",
caption="Update Available for OpenCore Legacy Patcher!", style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION
style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION )
) dialog.SetYesNoCancelLabels("Download and install", "Ignore", "View on Github")
dialog.SetYesNoCancelLabels("Download and install", "Ignore", "View on Github") response = dialog.ShowModal()
response = dialog.ShowModal()
if response == wx.ID_YES: if response == wx.ID_YES:
wx.CallAfter(self.on_update, dict[entry]["Link"], version) wx.CallAfter(self.on_update, dict["Link"], version)
elif response == wx.ID_CANCEL: elif response == wx.ID_CANCEL:
webbrowser.open(dict[entry]["Github Link"]) webbrowser.open(dict["Github Link"])
def on_build_and_install(self, event: wx.Event = None): def on_build_and_install(self, event: wx.Event = None):

View File

@@ -48,10 +48,8 @@ class UpdateFrame(wx.Frame):
if url == "" or version_label == "": if url == "" or version_label == "":
dict = updates.CheckBinaryUpdates(self.constants).check_binary_updates() dict = updates.CheckBinaryUpdates(self.constants).check_binary_updates()
if dict: if dict:
for key in dict: version_label = dict["Version"]
version_label = dict[key]["Version"] url = dict["Link"]
url = dict[key]["Link"]
break
else: else:
wx.MessageBox("Failed to get update info", "Critical Error") wx.MessageBox("Failed to get update info", "Critical Error")
sys.exit(1) sys.exit(1)